field.c 4.6 KB

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