do_logic.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Sources of the "LOGICAL" group instructions
  3. */
  4. /* $Id$ */
  5. #include <em_abs.h>
  6. #include "logging.h"
  7. #include "global.h"
  8. #include "log.h"
  9. #include "warn.h"
  10. #include "mem.h"
  11. #include "shadow.h"
  12. #include "trap.h"
  13. #include "text.h"
  14. #include "fra.h"
  15. #ifdef LOGGING
  16. extern int must_test;
  17. #endif /* LOGGING */
  18. #ifdef LOGGING
  19. #define check_def(p,l) if (!st_sh(p) || !st_sh(p+l)) {warning(WUNLOG);}
  20. #else
  21. #define check_def(p,l)
  22. #endif /* LOGGING */
  23. DoAND(l)
  24. register size l;
  25. {
  26. /* AND w: Boolean and on two groups of w bytes */
  27. /* size of objects to be compared (in bytes) on top of stack */
  28. register ptr p;
  29. LOG(("@X6 DoAND(%ld)", l));
  30. spoilFRA();
  31. l = arg_w(l);
  32. for (p = SP; p < (SP + l); p++) {
  33. check_def(p, l);
  34. stack_loc(p + l) &= stack_loc(p);
  35. }
  36. st_dec(l);
  37. }
  38. DoIOR(l)
  39. register size l;
  40. {
  41. /* IOR w: Boolean inclusive or on two groups of w bytes */
  42. register ptr p;
  43. LOG(("@X6 DoIOR(%ld)", l));
  44. spoilFRA();
  45. l = arg_w(l);
  46. for (p = SP; p < (SP + l); p++) {
  47. check_def(p, l);
  48. stack_loc(p + l) |= stack_loc(p);
  49. }
  50. st_dec(l);
  51. }
  52. DoXOR(l)
  53. register size l;
  54. {
  55. /* XOR w: Boolean exclusive or on two groups of w bytes */
  56. register ptr p;
  57. LOG(("@X6 DoXOR(%ld)", l));
  58. spoilFRA();
  59. l = arg_w(l);
  60. for (p = SP; p < (SP + l); p++) {
  61. check_def(p, l);
  62. stack_loc(p + l) ^= stack_loc(p);
  63. }
  64. st_dec(l);
  65. }
  66. DoCOM(l)
  67. register size l;
  68. {
  69. /* COM w: Complement (one's complement of top w bytes) */
  70. register ptr p;
  71. LOG(("@X6 DoCOM(%ld)", l));
  72. spoilFRA();
  73. l = arg_w(l);
  74. for (p = SP; p < (SP + l); p++) {
  75. check_def(p, 0);
  76. stack_loc(p) = ~stack_loc(p);
  77. }
  78. }
  79. DoROL(l)
  80. register size l;
  81. {
  82. /* ROL w: Rotate left a group of w bytes */
  83. register long s, t = uwpop();
  84. register long signbit;
  85. LOG(("@X6 DoROL(%ld)", l));
  86. spoilFRA();
  87. signbit = (arg_wi(l) == 2) ? SIGNBIT2 : SIGNBIT4;
  88. s = upop(l);
  89. #ifdef LOGGING
  90. if (must_test) {
  91. /* check shift distance */
  92. if (t < 0) {
  93. warning(WSHNEG);
  94. t = 0;
  95. }
  96. if (t >= l*8) {
  97. warning(WSHLARGE);
  98. t = l*8 - 1;
  99. }
  100. }
  101. #endif /* LOGGING */
  102. /* calculate result */
  103. while (t--) {
  104. s = (s & signbit) ? ((s<<1) | BIT(0)) : (s<<1);
  105. }
  106. npush(s, l);
  107. }
  108. DoROR(l)
  109. register size l;
  110. {
  111. /* ROR w: Rotate right a group of w bytes */
  112. register long s, t = uwpop();
  113. register long signbit;
  114. LOG(("@X6 DoROR(%ld)", l));
  115. spoilFRA();
  116. signbit = (arg_wi(l) == 2) ? SIGNBIT2 : SIGNBIT4;
  117. s = upop(l);
  118. #ifdef LOGGING
  119. if (must_test) {
  120. /* check shift distance */
  121. if (t < 0) {
  122. warning(WSHNEG);
  123. t = 0;
  124. }
  125. if (t >= l*8) {
  126. warning(WSHLARGE);
  127. t = l*8 - 1;
  128. }
  129. }
  130. #endif /* LOGGING */
  131. /* calculate result */
  132. while (t--) {
  133. /* the >> in C does sign extension, the ROR does not */
  134. if (s & BIT(0))
  135. s = (s >> 1) | signbit;
  136. else s = (s >> 1) & ~signbit;
  137. }
  138. npush(s, l);
  139. }