diff options
author | DJ Delorie <dj@redhat.com> | 2012-04-30 22:09:09 +0000 |
---|---|---|
committer | DJ Delorie <dj@redhat.com> | 2012-04-30 22:09:09 +0000 |
commit | cad335c901d6f503803e4238b251f828f369514f (patch) | |
tree | b067cb1e4d64ce631fd69d70bbdfc5a5e7d9fd56 /gas/config/rx-parse.y | |
parent | 78e98aaba5b8ece23f0cbb1a6baa0f3b1891b275 (diff) | |
download | gdb-cad335c901d6f503803e4238b251f828f369514f.zip gdb-cad335c901d6f503803e4238b251f828f369514f.tar.gz gdb-cad335c901d6f503803e4238b251f828f369514f.tar.bz2 |
* config/rx-parse.y (rx_intop): Add parameter for operation size.
Check for large positive constants really being small negative
ones.
(BRA, BSR): Update calls to rx_intop.
(immediate): Likewise.
Diffstat (limited to 'gas/config/rx-parse.y')
-rw-r--r-- | gas/config/rx-parse.y | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/gas/config/rx-parse.y b/gas/config/rx-parse.y index f223dc7..756637b 100644 --- a/gas/config/rx-parse.y +++ b/gas/config/rx-parse.y @@ -104,7 +104,7 @@ static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE }; #define id24(a,b2,b3) B3 (0xfb+a, b2, b3) -static int rx_intop (expressionS, int); +static int rx_intop (expressionS, int, int); static int rx_uintop (expressionS, int); static int rx_disp3op (expressionS); static int rx_disp5op (expressionS *, int); @@ -192,11 +192,11 @@ statement : | BRA EXPR { if (rx_disp3op ($2)) { B1 (0x08); rx_disp3 ($2, 5); } - else if (rx_intop ($2, 8)) + else if (rx_intop ($2, 8, 8)) { B1 (0x2e); PC1 ($2); } - else if (rx_intop ($2, 16)) + else if (rx_intop ($2, 16, 16)) { B1 (0x38); PC2 ($2); } - else if (rx_intop ($2, 24)) + else if (rx_intop ($2, 24, 24)) { B1 (0x04); PC3 ($2); } else { rx_relax (RX_RELAX_BRANCH, 0); @@ -213,9 +213,9 @@ statement : /* ---------------------------------------------------------------------- */ | BSR EXPR - { if (rx_intop ($2, 16)) + { if (rx_intop ($2, 16, 16)) { B1 (0x39); PC2 ($2); } - else if (rx_intop ($2, 24)) + else if (rx_intop ($2, 24, 24)) { B1 (0x05); PC3 ($2); } else { rx_relax (RX_RELAX_BRANCH, 0); @@ -1308,9 +1308,10 @@ rx_error (const char * str) } static int -rx_intop (expressionS exp, int nbits) +rx_intop (expressionS exp, int nbits, int opbits) { long v; + long mask, msb; if (exp.X_op == O_big && nbits == 32) return 1; @@ -1318,6 +1319,12 @@ rx_intop (expressionS exp, int nbits) return 0; v = exp.X_add_number; + msb = 1UL << (opbits - 1); + mask = (1UL << opbits) - 1; + + if ((v & msb) && ! (v & ~mask)) + v -= 1UL << opbits; + switch (nbits) { case 4: @@ -1461,12 +1468,12 @@ immediate (expressionS exp, int type, int pos, int bits) rx_error (_("sbb cannot use symbolic immediates")); } - if (rx_intop (exp, 8)) + if (rx_intop (exp, 8, bits)) { rx_op (exp, 1, type); return 1; } - else if (rx_intop (exp, 16)) + else if (rx_intop (exp, 16, bits)) { rx_op (exp, 2, type); return 2; @@ -1476,12 +1483,12 @@ immediate (expressionS exp, int type, int pos, int bits) rx_op (exp, 2, type); return 2; } - else if (rx_intop (exp, 24)) + else if (rx_intop (exp, 24, bits)) { rx_op (exp, 3, type); return 3; } - else if (rx_intop (exp, 32)) + else if (rx_intop (exp, 32, bits)) { rx_op (exp, 4, type); return 0; |