field.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Header$ */
  6. /* BITFIELD EXPRESSION EVALUATOR */
  7. #include "lint.h"
  8. #ifndef LINT
  9. #include "nobitfield.h"
  10. #ifndef NOBITFIELD
  11. #include <em.h>
  12. #include <em_reg.h>
  13. #include "debug.h"
  14. #include "arith.h"
  15. #include "type.h"
  16. #include "idf.h"
  17. #include "label.h"
  18. #include "code.h"
  19. #include "assert.h"
  20. #include "expr.h"
  21. #include "sizes.h"
  22. #include "align.h"
  23. #include "Lpars.h"
  24. #include "field.h"
  25. arith NewLocal(); /* util.c */
  26. char *symbol2str(); /* symbol2str.c */
  27. /* Eval_field() evaluates expressions involving bit fields.
  28. The various instructions are not yet optimised in the expression
  29. tree and are therefore dealt with in this function.
  30. The actions taken at any operation are described clearly by the
  31. code for this actions.
  32. Notes
  33. [1] the bitfields are packed in target machine integers!
  34. [2] op is either an assignment operator or an increment/
  35. decrement operator
  36. [3] atype: the type in which the bitfield arithmetic is done;
  37. and in which bitfields are stored!
  38. */
  39. eval_field(expr, code)
  40. struct expr *expr;
  41. int code;
  42. {
  43. int op = expr->OP_OPER;
  44. register struct expr *leftop = expr->OP_LEFT;
  45. register struct expr *rightop = expr->OP_RIGHT;
  46. register struct field *fd = leftop->ex_type->tp_field;
  47. struct type *tp = leftop->ex_type->tp_up;
  48. arith tmpvar;
  49. struct type *atype = tp->tp_unsigned ? uword_type : word_type;
  50. arith asize = atype->tp_size;
  51. /* First some assertions to be sure that the rest is legal */
  52. ASSERT(asize == word_size); /* make sure that C_loc() is legal */
  53. ASSERT(leftop->ex_type->tp_fund == FIELD);
  54. leftop->ex_type = atype; /* this is cheating but it works... */
  55. if (op == '=') {
  56. /* F = E: f = ((E & mask)<<shift) | (~(mask<<shift) & f) */
  57. ASSERT(tp == rightop->ex_type);
  58. EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
  59. conversion(tp, atype);
  60. C_loc(fd->fd_mask);
  61. C_and(asize);
  62. if (code == TRUE)
  63. C_dup(asize);
  64. C_loc((arith)fd->fd_shift);
  65. if (atype->tp_unsigned)
  66. C_slu(asize);
  67. else
  68. C_sli(asize);
  69. C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
  70. if (leftop->ex_depth == 0) { /* simple case */
  71. load_val(leftop, RVAL);
  72. C_and(asize);
  73. C_ior(asize);
  74. store_val(&(leftop->EX_VALUE), atype);
  75. }
  76. else { /* complex case */
  77. tmpvar = NewLocal(pointer_size, pointer_align,
  78. reg_pointer, 0);
  79. EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
  80. C_dup(pointer_size);
  81. StoreLocal(tmpvar, pointer_size);
  82. C_loi(asize);
  83. C_and(asize);
  84. C_ior(asize);
  85. LoadLocal(tmpvar, pointer_size);
  86. C_sti(asize);
  87. FreeLocal(tmpvar);
  88. }
  89. }
  90. else { /* treat ++F as F += 1 and --F as F -= 1 */
  91. /* F op= e: f = (((((f>>shift)&mask) op e)&mask)<<shift)|
  92. (f&~(mask<<shift))
  93. */
  94. if (leftop->ex_depth == 0) /* simple case */
  95. load_val(leftop, RVAL);
  96. else { /* complex case */
  97. tmpvar = NewLocal(pointer_size, pointer_align,
  98. reg_pointer, 0);
  99. EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
  100. C_dup(pointer_size);
  101. StoreLocal(tmpvar, pointer_size);
  102. C_loi(asize);
  103. }
  104. if (atype->tp_unsigned) {
  105. C_loc((arith)fd->fd_shift);
  106. C_sru(asize);
  107. C_loc(fd->fd_mask);
  108. C_and(asize);
  109. }
  110. else {
  111. arith bits_in_type = asize * 8;
  112. C_loc(bits_in_type - (fd->fd_width + fd->fd_shift));
  113. C_sli(asize);
  114. C_loc(bits_in_type - fd->fd_width);
  115. C_sri(asize);
  116. }
  117. if (code == TRUE && (op == POSTINCR || op == POSTDECR))
  118. C_dup(asize);
  119. conversion(atype, rightop->ex_type);
  120. EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
  121. /* the 'op' operation: */
  122. if (op == PLUSPLUS || op == POSTINCR)
  123. assop(rightop->ex_type, PLUSAB);
  124. else
  125. if (op == MINMIN || op == POSTDECR)
  126. assop(rightop->ex_type, MINAB);
  127. else
  128. assop(rightop->ex_type, op);
  129. conversion(rightop->ex_type, atype);
  130. C_loc(fd->fd_mask);
  131. C_and(asize);
  132. if (code == TRUE && op != POSTINCR && op != POSTDECR)
  133. C_dup(asize);
  134. C_loc((arith)fd->fd_shift);
  135. if (atype->tp_unsigned)
  136. C_slu(asize);
  137. else
  138. C_sli(asize);
  139. C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
  140. if (leftop->ex_depth == 0) {
  141. load_val(leftop, RVAL);
  142. C_and(asize);
  143. C_ior(asize);
  144. store_val(&(leftop->EX_VALUE), atype);
  145. }
  146. else {
  147. LoadLocal(tmpvar, pointer_size);
  148. C_loi(asize);
  149. C_and(asize);
  150. C_ior(asize);
  151. LoadLocal(tmpvar, pointer_size);
  152. C_sti(asize);
  153. FreeLocal(tmpvar);
  154. }
  155. }
  156. if (code == TRUE) {
  157. /* Take care that the effective value stored in
  158. the bit field (i.e. the value that is got on
  159. retrieval) is on top of stack.
  160. */
  161. if (atype->tp_unsigned == 0) { /* sign extension */
  162. register arith shift = asize * 8 - fd->fd_width;
  163. C_loc(shift);
  164. C_sli(asize);
  165. C_loc(shift);
  166. C_sri(asize);
  167. }
  168. conversion(atype, expr->ex_type);
  169. }
  170. }
  171. #endif NOBITFIELD
  172. #endif LINT