diff options
author | Ian Lance Taylor <ian@airs.com> | 1992-08-19 18:27:48 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1992-08-19 18:27:48 +0000 |
commit | c50140c86b1eff40d7ca75bf18df7e5d8e36f3ea (patch) | |
tree | e3b629a55f64b3838ae201707438b62d7a2b73d8 /gas | |
parent | 1090c41efcfb57602db4549d38cc0003bcdb6d22 (diff) | |
download | gdb-c50140c86b1eff40d7ca75bf18df7e5d8e36f3ea.zip gdb-c50140c86b1eff40d7ca75bf18df7e5d8e36f3ea.tar.gz gdb-c50140c86b1eff40d7ca75bf18df7e5d8e36f3ea.tar.bz2 |
This is for PR 628.
Wed Aug 19 11:20:59 1992 Ian Lance Taylor (ian@cygnus.com)
* tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be
written with indirection on the last two operands, which can be
either data or address registers. Added a new operand type 'r'
which accepts either register type. Added '(' to notend stuff in
tc-m68kmote.c to accept (a0):(a2) in cas2 instruction.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-m68k.c | 20 | ||||
-rw-r--r-- | gas/config/tc-m68kmote.c | 39 |
3 files changed, 57 insertions, 11 deletions
diff --git a/gas/config/ChangeLog b/gas/config/ChangeLog index 712a82f..15b26a7 100644 --- a/gas/config/ChangeLog +++ b/gas/config/ChangeLog @@ -1,3 +1,11 @@ +Wed Aug 19 11:20:59 1992 Ian Lance Taylor (ian@cygnus.com) + + * tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be + written with indirection on the last two operands, which can be + either data or address registers. Added a new operand type 'r' + which accepts either register type. Added '(' to notend stuff in + tc-m68kmote.c to accept (a0):(a2) in cas2 instruction. + Tue Aug 11 12:58:14 1992 Ken Raeburn (raeburn@cygnus.com) * sparc.mt: New file. @@ -12,7 +20,6 @@ Thu Aug 6 12:08:42 1992 Steve Chamberlain (sac@thepub.cygnus.com) * config/tc-h8300.c: if a :8 is seen after an operand, fill top two bytes of any constant with 0xff: - Wed Aug 5 01:54:34 1992 John Gilmore (gnu at cygnus.com) * tc-m68k.c (try_index): Error if index scaling specified and diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 0c60c77..c3d1b19 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -117,6 +117,7 @@ static struct obstack robyn; *** MSCR otherreg --> Magic With -l option 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still + ?.? DINDR dreg@ --> (dreg) -- cas2 only examples: #foo #0x35 #12 @@ -151,6 +152,7 @@ enum operand_type { ABSL, MSCR, REGLST, + DINDR }; @@ -665,7 +667,9 @@ register struct m68k_op *opP; return OK; } - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ + /* Can't indirect off non address regs, but Dx@ is OK for cas2 */ + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL + && (str[1] != '\0' || i<DATA+0 || i>DATA+7)) { opP->error="Invalid indirect register"; return FAIL; } @@ -674,7 +678,10 @@ register struct m68k_op *opP; str++; switch(*str) { case '\0': - opP->mode=AINDR; + if (i < DATA + 0 || i > DATA + 7) + opP->mode=AINDR; + else + opP->mode=DINDR; return OK; case '-': opP->mode=ADEC; @@ -1294,6 +1301,11 @@ void m68k_ip (instring) losing++; break; + case 'r': + if (opP->mode!=AINDR && opP->mode!=DINDR) + losing++; + break; + case 's': if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC)) losing++; @@ -1809,6 +1821,9 @@ void m68k_ip (instring) break; } break; + case DINDR: + as_bad("invalid indirect register"); + break; case MSCR: default: as_bad("unknown/incorrect operand"); @@ -2090,6 +2105,7 @@ void m68k_ip (instring) break; case 'R': + case 'r': /* This depends on the fact that ADDR registers are eight more than their corresponding DATA regs, so the result will have the ADDR_REG bit set */ diff --git a/gas/config/tc-m68kmote.c b/gas/config/tc-m68kmote.c index dd18c7e..d8e93b0 100644 --- a/gas/config/tc-m68kmote.c +++ b/gas/config/tc-m68kmote.c @@ -123,6 +123,7 @@ static struct obstack robyn; *** MSCR otherreg --> Magic With -l option 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still + ?.? DINDR dreg@ --> (dreg) -- cas2 only examples: #foo #0x35 #12 @@ -157,6 +158,7 @@ enum operand_type { ABSL, MSCR, REGLST, + DINDR }; @@ -933,8 +935,10 @@ register struct m68k_op *opP; if(*str=='(') { str++; i=m68k_reg_parse(&str); - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { - /* Can't indirect off non address regs */ + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL + && (*str != ')' || str[1] != '\0' || i<DATA+0 || i>DATA+7)) { + /* Can't indirect off non address regs, + but (dx) is OK for cas2. */ opP->error="Invalid indirect register"; return FAIL; } @@ -943,8 +947,12 @@ register struct m68k_op *opP; if(*str==')') { str++; if(*str=='\0') { - /* "(An)" Address Register Indirect mode */ - opP->mode=AINDR; + /* "(An)" Address Register Indirect mode + or "(Dn)" for cas2 instruction. */ + if (i < DATA + 0 || i > DATA + 7) + opP->mode=AINDR; + else + opP->mode=DINDR; return OK; } if(*str=='+') { @@ -1209,7 +1217,9 @@ register struct m68k_op *opP; return OK; } - if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { /* Can't indirect off non address regs */ + /* Can't indirect off non address regs, but Dx@ is OK for cas2 */ + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL + && (str[1] != '\0' || i<DATA+0 || i>DATA+7)) { opP->error="Invalid indirect register"; return FAIL; } @@ -1218,7 +1228,10 @@ register struct m68k_op *opP; str++; switch(*str) { case '\0': - opP->mode=AINDR; + if (i < DATA + 0 || i > DATA + 7) + opP->mode=AINDR; + else + opP->mode=DINDR; return OK; case '-': opP->mode=ADEC; @@ -1863,6 +1876,11 @@ char *instring; losing++; break; + case 'r': + if(opP->mode!=AINDR && opP->mode!=DINDR) + losing++; + break; + case 's': if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC)) losing++; @@ -2327,6 +2345,9 @@ char *instring; break; } break; + case DINDR: + as_bad("invalid indirect register"); + break; case MSCR: default: as_bad("unknown/incorrect operand"); @@ -2608,6 +2629,7 @@ char *instring; break; case 'R': + case 'r': /* This depends on the fact that ADDR registers are eight more than their corresponding DATA regs, so the result will have the ADDR_REG bit set */ @@ -3015,7 +3037,7 @@ char *s; return 0; if(*s!=':') return 1; /* This kludge here is for the division cmd, which is a kludge */ - if(index("aAdD#",s[1])) return 0; + if(index("aAdD#(",s[1])) return 0; return 1; } #endif @@ -3296,6 +3318,7 @@ void alt_notend_table['#'] = 1; alt_notend_table['f'] = 1; alt_notend_table['F'] = 1; + alt_notend_table['('] = 1; #ifdef REGISTER_PREFIX alt_notend_table[REGISTER_PREFIX] = 1; @@ -3306,7 +3329,7 @@ void #if 0 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \ - || (*s == ':' && strchr("aAdD#", s[1]))) \ + || (*s == ':' && strchr("aAdD#(", s[1]))) \ ? 0 : 1) #endif |