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.
This commit is contained in:
Jan Beulich
2005-02-15 07:50:23 +00:00
parent 0ca3e4557f
commit 4b09e82862
8 changed files with 192 additions and 27 deletions

View File

@ -1,3 +1,9 @@
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> 2005-02-15 Jan Beulich <jbeulich@novell.com>
* config/tc-ia64.c (ia64_gen_real_reloc_type): Define and initialize * config/tc-ia64.c (ia64_gen_real_reloc_type): Define and initialize

View File

@ -6012,6 +6012,8 @@ parse_operands (idesc)
{ {
int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0; 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 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 ia64_opnd expected_operand = IA64_OPND_NIL;
enum operand_match_result result; enum operand_match_result result;
char mnemonic[129]; char mnemonic[129];
@ -6193,6 +6195,127 @@ parse_operands (idesc)
as_bad ("Operand mismatch"); as_bad ("Operand mismatch");
return 0; 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; return idesc;
} }

View File

@ -1,3 +1,10 @@
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> 2005-02-15 Jan Beulich <jbeulich@novell.com>
* gas/ia64/reloc.[ds]: New. * gas/ia64/reloc.[ds]: New.

View File

@ -6,8 +6,8 @@
.text .text
.explicit .explicit
// AR[BSP] // AR[BSP]
mov ar.bspstore = r1 mov ar.bspstore = r0
mov r0 = ar.bsp mov r1 = ar.bsp
;; ;;
// AR[BSPSTORE] // AR[BSPSTORE]
@ -108,12 +108,12 @@
// BR% // BR%
mov b0 = r0 mov b0 = r0
mov r0 = b0 mov r2 = b0
;; ;;
// CFM // CFM
br.wtop.sptk L br.wtop.sptk L
fadd f0 = f1, f32 // read from rotating register region fadd f2 = f1, f32 // read from rotating register region
;; ;;
// CR[CMCV] // CR[CMCV]
@ -276,7 +276,7 @@
;; ;;
// GR% // GR%
ld8.c.clr r0 = [r1] // no DV here ld8.c.clr r1 = [r1] // no DV here
mov r2 = r0 mov r2 = r0
;; ;;
mov r3 = r4 mov r3 = r4
@ -357,7 +357,7 @@
// PR63 // PR63
br.wtop.sptk L br.wtop.sptk L
(p63) add r0 = r1, r2 (p63) add r3 = r1, r2
;; ;;
fcmp.eq p62, p63 = f2, f3 fcmp.eq p62, p63 = f2, f3
(p63) add r3 = r4, r5 (p63) add r3 = r4, r5
@ -368,17 +368,17 @@
// PSR.ac // PSR.ac
rum (1<<3) rum (1<<3)
ld8 r0 = [r1] ld8 r2 = [r1]
;; ;;
// PSR.be // PSR.be
rum (1<<1) rum (1<<1)
ld8 r0 = [r1] ld8 r2 = [r1]
;; ;;
// PSR.bn // PSR.bn
bsw.0 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 bsw.1 // GAS automatically emits a stop after bsw.n
mov r1 = r16 // so this conflict is avoided mov r1 = r16 // so this conflict is avoided
@ -439,24 +439,24 @@
// PSR.di // PSR.di
rsm (1<<22) rsm (1<<22)
mov r0 = psr mov r1 = psr
;; ;;
// PSR.dt // PSR.dt
rsm (1<<17) rsm (1<<17)
ld8 r0 = [r1] ld8 r1 = [r1]
;; ;;
// PSR.ed (rfi is the only writer) // PSR.ed (rfi is the only writer)
// PSR.i // PSR.i
ssm (1<<14) ssm (1<<14)
mov r0 = psr mov r1 = psr
;; ;;
// PSR.ia (no DV semantics) // PSR.ia (no DV semantics)
// PSR.ic // PSR.ic
ssm (1<<13) ssm (1<<13)
mov r0 = psr mov r1 = psr
;; ;;
srlz.d srlz.d
rsm (1<<13) rsm (1<<13)
@ -479,17 +479,17 @@
// PSR.mc (rfi is the only writer) // PSR.mc (rfi is the only writer)
// PSR.mfh // PSR.mfh
mov f32 = f33 mov f32 = f33
mov r0 = psr mov r1 = psr
;; ;;
// PSR.mfl // PSR.mfl
mov f2 = f3 mov f2 = f3
mov r0 = psr mov r1 = psr
;; ;;
// PSR.pk // PSR.pk
rsm (1<<15) rsm (1<<15)
ld8 r0 = [r1] ld8 r1 = [r1]
;; ;;
rsm (1<<15) rsm (1<<15)
mov r2 = psr mov r2 = psr
@ -497,7 +497,7 @@
// PSR.pp // PSR.pp
rsm (1<<21) rsm (1<<21)
mov r0 = psr mov r1 = psr
;; ;;
// PSR.ri (no DV semantics) // PSR.ri (no DV semantics)
@ -509,7 +509,7 @@
// PSR.si // PSR.si
rsm (1<<23) rsm (1<<23)
mov r0 = ar.itc mov r1 = ar.itc
;; ;;
ssm (1<<23) ssm (1<<23)
mov r1 = ar.ec // no DV here mov r1 = ar.ec // no DV here
@ -517,13 +517,13 @@
// PSR.sp // PSR.sp
ssm (1<<20) ssm (1<<20)
mov r0 = pmd[r1] mov r1 = pmd[r1]
;; ;;
ssm (1<<20) ssm (1<<20)
rum 0xff rum 0xff
;; ;;
ssm (1<<20) ssm (1<<20)
mov r0 = rr[r1] mov r1 = rr[r1]
;; ;;
// PSR.ss (rfi is the only writer) // PSR.ss (rfi is the only writer)
@ -534,7 +534,7 @@
// PSR.up // PSR.up
rsm (1<<2) rsm (1<<2)
mov r0 = psr.um mov r1 = psr.um
;; ;;
srlz.d srlz.d

View File

@ -186,8 +186,8 @@
;; ;;
// CR[IRR%] (and others) // CR[IRR%] (and others)
mov r0 = cr.ivr mov r2 = cr.ivr
mov r1 = cr.ivr mov r3 = cr.ivr
;; ;;
// CR[ISR] // CR[ISR]
@ -441,13 +441,13 @@
// PSR.mc (rfi is the only writer) // PSR.mc (rfi is the only writer)
// PSR.mfh // PSR.mfh
mov f32 = f33 mov f32 = f33
mov r0 = psr mov r10 = psr
;; ;;
ssm (1<<5) ssm (1<<5)
ssm (1<<5) ssm (1<<5)
;; ;;
ssm (1<<5) ssm (1<<5)
mov psr.um = r0 mov psr.um = r10
;; ;;
rum (1<<5) rum (1<<5)
rum (1<<5) rum (1<<5)
@ -458,13 +458,13 @@
// PSR.mfl // PSR.mfl
mov f2 = f3 mov f2 = f3
mov r0 = psr mov r10 = psr
;; ;;
ssm (1<<4) ssm (1<<4)
ssm (1<<4) ssm (1<<4)
;; ;;
ssm (1<<4) ssm (1<<4)
mov psr.um = r0 mov psr.um = r10
;; ;;
rum (1<<4) rum (1<<4)
rum (1<<4) rum (1<<4)

View File

@ -28,6 +28,7 @@ if [istarget "ia64-*"] then {
run_dump_test "nop_x" run_dump_test "nop_x"
run_dump_test "mov-ar" run_dump_test "mov-ar"
run_list_test "operands" "" run_list_test "operands" ""
run_list_test "reg-err" ""
run_list_test "dv-raw-err" "" run_list_test "dv-raw-err" ""
run_list_test "dv-waw-err" "" run_list_test "dv-waw-err" ""

View File

@ -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'

View File

@ -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]