field.c 4.2 KB

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