diff options
author | Jan Beulich <jbeulich@novell.com> | 2005-02-15 07:50:23 +0000 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2005-02-15 07:50:23 +0000 |
commit | 4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a (patch) | |
tree | 2a69088531ba9b490d0f2879139c059100e96879 /gas | |
parent | 0ca3e4557f03289c3b174dd841dfa73dbe51d505 (diff) | |
download | fsf-binutils-gdb-4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a.zip fsf-binutils-gdb-4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a.tar.gz fsf-binutils-gdb-4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a.tar.bz2 |
gas/
2005-02-15 Jan Beulich <jbeulich@novell.com>
* config/tc-ia64.c (parse_operands): New local variables reg1, reg2,
reg_class. Check operands and emit diagnostics for illegal use of
registers.
gas/testsuite/
2005-02-15 Jan Beulich <jbeulich@novell.com>
* gas/ia64/dv-raw-err.s: Don't use r0 or f0 as output operand.
* gas/ia64/dv-waw-err.s: Likewise.
* gas/ia64/reg-err.[ls]: New.
* gas/ia64/ia64.exp: Run new test.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-ia64.c | 123 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/dv-raw-err.s | 42 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/dv-waw-err.s | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/ia64.exp | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/reg-err.l | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/reg-err.s | 14 |
8 files changed, 192 insertions, 27 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 8a43936..a75b7e8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,11 @@ 2005-02-15 Jan Beulich <jbeulich@novell.com> + * config/tc-ia64.c (parse_operands): New local variables reg1, reg2, + reg_class. Check operands and emit diagnostics for illegal use of + registers. + +2005-02-15 Jan Beulich <jbeulich@novell.com> + * config/tc-ia64.c (ia64_gen_real_reloc_type): Define and initialize new variables type, suffix, and width. Handle BFD_RELOC_IA64_DIR(32|64)[LM]SB in FUNC_LT_FPTR_RELATIVE case. diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 387a1b7..c7a6b07 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -6012,6 +6012,8 @@ parse_operands (idesc) { int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0; int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0; + int reg1, reg2; + char reg_class; enum ia64_opnd expected_operand = IA64_OPND_NIL; enum operand_match_result result; char mnemonic[129]; @@ -6193,6 +6195,127 @@ parse_operands (idesc) as_bad ("Operand mismatch"); return 0; } + + /* Check that the instruction doesn't use + - r0, f0, or f1 as output operands + - the same predicate twice as output operands + - r0 as address of a base update load or store + - the same GR as output and address of a base update load + - two even- or two odd-numbered FRs as output operands of a floating + point parallel load. + At most two (conflicting) output (or output-like) operands can exist, + (floating point parallel loads have three outputs, but the base register, + if updated, cannot conflict with the actual outputs). */ + reg2 = reg1 = -1; + for (i = 0; i < num_operands; ++i) + { + int regno = 0; + + reg_class = 0; + switch (idesc->operands[i]) + { + case IA64_OPND_R1: + case IA64_OPND_R2: + case IA64_OPND_R3: + if (i < num_outputs) + { + if (CURR_SLOT.opnd[i].X_add_number == REG_GR) + reg_class = 'r'; + else if (reg1 < 0) + reg1 = CURR_SLOT.opnd[i].X_add_number; + else if (reg2 < 0) + reg2 = CURR_SLOT.opnd[i].X_add_number; + } + break; + case IA64_OPND_P1: + case IA64_OPND_P2: + if (i < num_outputs) + { + if (reg1 < 0) + reg1 = CURR_SLOT.opnd[i].X_add_number; + else if (reg2 < 0) + reg2 = CURR_SLOT.opnd[i].X_add_number; + } + break; + case IA64_OPND_F1: + case IA64_OPND_F2: + case IA64_OPND_F3: + case IA64_OPND_F4: + if (i < num_outputs) + { + if (CURR_SLOT.opnd[i].X_add_number >= REG_FR + && CURR_SLOT.opnd[i].X_add_number <= REG_FR + 1) + { + reg_class = 'f'; + regno = CURR_SLOT.opnd[i].X_add_number - REG_FR; + } + else if (reg1 < 0) + reg1 = CURR_SLOT.opnd[i].X_add_number; + else if (reg2 < 0) + reg2 = CURR_SLOT.opnd[i].X_add_number; + } + break; + case IA64_OPND_MR3: + if (idesc->flags & IA64_OPCODE_POSTINC) + { + if (CURR_SLOT.opnd[i].X_add_number == REG_GR) + reg_class = 'm'; + else if (reg1 < 0) + reg1 = CURR_SLOT.opnd[i].X_add_number; + else if (reg2 < 0) + reg2 = CURR_SLOT.opnd[i].X_add_number; + } + break; + default: + break; + } + switch (reg_class) + { + case 0: + break; + default: + as_warn ("Invalid use of `%c%d' as output operand", reg_class, regno); + break; + case 'm': + as_warn ("Invalid use of `r%d' as base update address operand", regno); + break; + } + } + if (reg1 == reg2) + { + if (reg1 >= REG_GR && reg1 <= REG_GR + 127) + { + reg1 -= REG_GR; + reg_class = 'r'; + } + else if (reg1 >= REG_P && reg1 <= REG_P + 63) + { + reg1 -= REG_P; + reg_class = 'p'; + } + else if (reg1 >= REG_FR && reg1 <= REG_FR + 127) + { + reg1 -= REG_FR; + reg_class = 'f'; + } + else + reg_class = 0; + if (reg_class) + as_warn ("Invalid duplicate use of `%c%d'", reg_class, reg1); + } + else if (((reg1 >= REG_FR && reg1 <= REG_FR + 31 + && reg2 >= REG_FR && reg2 <= REG_FR + 31) + || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127 + && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127)) + && ! ((reg1 ^ reg2) & 1)) + as_warn ("Invalid simultaneous use of `f%d' and `f%d'", + reg1 - REG_FR, reg2 - REG_FR); + else if ((reg1 >= REG_FR && reg1 <= REG_FR + 31 + && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127) + || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127 + && reg2 >= REG_FR && reg2 <= REG_FR + 31)) + as_warn ("Dangerous simultaneous use of `f%d' and `f%d'", + reg1 - REG_FR, reg2 - REG_FR); return idesc; } diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1844441..73e2c5d 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2005-02-15 Jan Beulich <jbeulich@novell.com> + * gas/ia64/dv-raw-err.s: Don't use r0 or f0 as output operand. + * gas/ia64/dv-waw-err.s: Likewise. + * gas/ia64/reg-err.[ls]: New. + * gas/ia64/ia64.exp: Run new test. + +2005-02-15 Jan Beulich <jbeulich@novell.com> + * gas/ia64/reloc.[ds]: New. * gas/ia64/reloc-bad.[ls]: New. * gas/ia64/ia64.exp: Run new tests. diff --git a/gas/testsuite/gas/ia64/dv-raw-err.s b/gas/testsuite/gas/ia64/dv-raw-err.s index 13a1d3a..416d042 100644 --- a/gas/testsuite/gas/ia64/dv-raw-err.s +++ b/gas/testsuite/gas/ia64/dv-raw-err.s @@ -6,8 +6,8 @@ .text .explicit // AR[BSP] - mov ar.bspstore = r1 - mov r0 = ar.bsp + mov ar.bspstore = r0 + mov r1 = ar.bsp ;; // AR[BSPSTORE] @@ -108,12 +108,12 @@ // BR% mov b0 = r0 - mov r0 = b0 + mov r2 = b0 ;; // CFM br.wtop.sptk L - fadd f0 = f1, f32 // read from rotating register region + fadd f2 = f1, f32 // read from rotating register region ;; // CR[CMCV] @@ -276,7 +276,7 @@ ;; // GR% - ld8.c.clr r0 = [r1] // no DV here + ld8.c.clr r1 = [r1] // no DV here mov r2 = r0 ;; mov r3 = r4 @@ -357,7 +357,7 @@ // PR63 br.wtop.sptk L -(p63) add r0 = r1, r2 +(p63) add r3 = r1, r2 ;; fcmp.eq p62, p63 = f2, f3 (p63) add r3 = r4, r5 @@ -368,17 +368,17 @@ // PSR.ac rum (1<<3) - ld8 r0 = [r1] + ld8 r2 = [r1] ;; // PSR.be rum (1<<1) - ld8 r0 = [r1] + ld8 r2 = [r1] ;; // PSR.bn bsw.0 - mov r0 = r15 // no DV here, since gr < 16 + mov r1 = r15 // no DV here, since gr < 16 ;; bsw.1 // GAS automatically emits a stop after bsw.n mov r1 = r16 // so this conflict is avoided @@ -439,24 +439,24 @@ // PSR.di rsm (1<<22) - mov r0 = psr + mov r1 = psr ;; // PSR.dt rsm (1<<17) - ld8 r0 = [r1] + ld8 r1 = [r1] ;; // PSR.ed (rfi is the only writer) // PSR.i ssm (1<<14) - mov r0 = psr + mov r1 = psr ;; // PSR.ia (no DV semantics) // PSR.ic ssm (1<<13) - mov r0 = psr + mov r1 = psr ;; srlz.d rsm (1<<13) @@ -479,17 +479,17 @@ // PSR.mc (rfi is the only writer) // PSR.mfh mov f32 = f33 - mov r0 = psr + mov r1 = psr ;; // PSR.mfl mov f2 = f3 - mov r0 = psr + mov r1 = psr ;; // PSR.pk rsm (1<<15) - ld8 r0 = [r1] + ld8 r1 = [r1] ;; rsm (1<<15) mov r2 = psr @@ -497,7 +497,7 @@ // PSR.pp rsm (1<<21) - mov r0 = psr + mov r1 = psr ;; // PSR.ri (no DV semantics) @@ -509,7 +509,7 @@ // PSR.si rsm (1<<23) - mov r0 = ar.itc + mov r1 = ar.itc ;; ssm (1<<23) mov r1 = ar.ec // no DV here @@ -517,13 +517,13 @@ // PSR.sp ssm (1<<20) - mov r0 = pmd[r1] + mov r1 = pmd[r1] ;; ssm (1<<20) rum 0xff ;; ssm (1<<20) - mov r0 = rr[r1] + mov r1 = rr[r1] ;; // PSR.ss (rfi is the only writer) @@ -534,7 +534,7 @@ // PSR.up rsm (1<<2) - mov r0 = psr.um + mov r1 = psr.um ;; srlz.d diff --git a/gas/testsuite/gas/ia64/dv-waw-err.s b/gas/testsuite/gas/ia64/dv-waw-err.s index acb6983..37a8b0f 100644 --- a/gas/testsuite/gas/ia64/dv-waw-err.s +++ b/gas/testsuite/gas/ia64/dv-waw-err.s @@ -186,8 +186,8 @@ ;; // CR[IRR%] (and others) - mov r0 = cr.ivr - mov r1 = cr.ivr + mov r2 = cr.ivr + mov r3 = cr.ivr ;; // CR[ISR] @@ -441,13 +441,13 @@ // PSR.mc (rfi is the only writer) // PSR.mfh mov f32 = f33 - mov r0 = psr + mov r10 = psr ;; ssm (1<<5) ssm (1<<5) ;; ssm (1<<5) - mov psr.um = r0 + mov psr.um = r10 ;; rum (1<<5) rum (1<<5) @@ -458,13 +458,13 @@ // PSR.mfl mov f2 = f3 - mov r0 = psr + mov r10 = psr ;; ssm (1<<4) ssm (1<<4) ;; ssm (1<<4) - mov psr.um = r0 + mov psr.um = r10 ;; rum (1<<4) rum (1<<4) diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp index a6fe570..c908063 100644 --- a/gas/testsuite/gas/ia64/ia64.exp +++ b/gas/testsuite/gas/ia64/ia64.exp @@ -28,6 +28,7 @@ if [istarget "ia64-*"] then { run_dump_test "nop_x" run_dump_test "mov-ar" run_list_test "operands" "" + run_list_test "reg-err" "" run_list_test "dv-raw-err" "" run_list_test "dv-waw-err" "" diff --git a/gas/testsuite/gas/ia64/reg-err.l b/gas/testsuite/gas/ia64/reg-err.l new file mode 100644 index 0000000..bd4dbc4 --- /dev/null +++ b/gas/testsuite/gas/ia64/reg-err.l @@ -0,0 +1,14 @@ +.*: Assembler messages: +.*:3: (Error|Warning): Invalid use of `r0' as output operand +.*:4: (Error|Warning): Invalid use of `r0' as base update address operand +.*:5: (Error|Warning): Invalid duplicate use of `r1' +.*:6: (Error|Warning): Invalid use of `r0' as base update address operand +.*:7: (Error|Warning): Invalid duplicate use of `p1' +.*:8: (Error|Warning): Invalid use of `f0' as output operand +.*:9: (Error|Warning): Invalid use of `f1' as output operand +.*:10: (Error|Warning): Invalid use of `f0' as output operand +.*:11: (Error|Warning): Invalid use of `f1' as output operand +.*:12: (Error|Warning): Invalid use of `f0' as output operand +.*:12: (Error|Warning): Invalid use of `f1' as output operand +.*:13: (Error|Warning): Invalid simultaneous use of `f2' and `f4' +.*:14: (Error|Warning): Dangerous simultaneous use of `f31' and `f32' diff --git a/gas/testsuite/gas/ia64/reg-err.s b/gas/testsuite/gas/ia64/reg-err.s new file mode 100644 index 0000000..88124d3 --- /dev/null +++ b/gas/testsuite/gas/ia64/reg-err.s @@ -0,0 +1,14 @@ + .text +_start: + mov r0 = r0 + ld1 r1 = [r0], 1 + ld1 r1 = [r1], 1 + st1 [r0] = r0, 1 + cmp.eq p1, p1 = 0, r0 + mov f0 = f0 + mov f1 = f1 + ldfs f0 = [r0] + ldfs f1 = [r0] + ldfps f0, f1 = [r0] + ldfps f2, f4 = [r0] + ldfps f31, f32 = [r0] |