aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2005-02-15 07:50:23 +0000
committerJan Beulich <jbeulich@novell.com>2005-02-15 07:50:23 +0000
commit4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a (patch)
tree2a69088531ba9b490d0f2879139c059100e96879 /gas
parent0ca3e4557f03289c3b174dd841dfa73dbe51d505 (diff)
downloadgdb-4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a.zip
gdb-4b09e82862bd1cdc6a6d89f19c556bfd2307bd9a.tar.gz
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/ChangeLog6
-rw-r--r--gas/config/tc-ia64.c123
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/ia64/dv-raw-err.s42
-rw-r--r--gas/testsuite/gas/ia64/dv-waw-err.s12
-rw-r--r--gas/testsuite/gas/ia64/ia64.exp1
-rw-r--r--gas/testsuite/gas/ia64/reg-err.l14
-rw-r--r--gas/testsuite/gas/ia64/reg-err.s14
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]