gas/
authorJan Beulich <jbeulich@novell.com>
Tue, 15 Feb 2005 07:50:23 +0000 (07:50 +0000)
committerJan Beulich <jbeulich@novell.com>
Tue, 15 Feb 2005 07:50:23 +0000 (07:50 +0000)
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.

gas/ChangeLog
gas/config/tc-ia64.c
gas/testsuite/ChangeLog
gas/testsuite/gas/ia64/dv-raw-err.s
gas/testsuite/gas/ia64/dv-waw-err.s
gas/testsuite/gas/ia64/ia64.exp
gas/testsuite/gas/ia64/reg-err.l [new file with mode: 0644]
gas/testsuite/gas/ia64/reg-err.s [new file with mode: 0644]

index 8a43936521c4351ab4414374840a0d95089becdc..a75b7e8796ba21fedad0c2c0d1287a14e7c104ab 100644 (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>
 
        * config/tc-ia64.c (ia64_gen_real_reloc_type): Define and initialize
index 387a1b7b51ee9f48358a30b071b7c87594f08ddd..c7a6b07884627e0b5cdb2778e0849e9f9a50c71f 100644 (file)
@@ -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;
 }
 
index 18444412fafb29ce19c91ba50d38c90c1972f271..73e2c5d11e4b6d375c586e269a7fc035b4869bd7 100644 (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>
 
        * gas/ia64/reloc.[ds]: New.
index 13a1d3a42542edcb3b1ff4126f7fc327e154145b..416d042420ff05cf09f770b3eb4ebc5bbfc39843 100644 (file)
@@ -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]        
 
 // 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]
        ;;
 
 // GR%
-       ld8.c.clr       r0 = [r1]       // no DV here
+       ld8.c.clr       r1 = [r1]       // no DV here
        mov             r2 = r0         
        ;;
        mov             r3 = r4
        
 // 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     
 
 // 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               
        
 // 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)
 // 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
 
 // PSR.pp
        rsm     (1<<21)
-       mov     r0 = psr
+       mov     r1 = psr
        ;;
 
 // PSR.ri (no DV semantics)
 
 // PSR.si
        rsm     (1<<23)
-       mov     r0 = ar.itc
+       mov     r1 = ar.itc
        ;;
        ssm     (1<<23)
        mov     r1 = ar.ec      // no DV here
 
 // 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)
 
 // PSR.up
        rsm     (1<<2)
-       mov     r0 = psr.um
+       mov     r1 = psr.um
        ;;
        srlz.d
 
index acb698391a937c98776c9e9177f95bfc6d8a4971..37a8b0fde466bbccd80911398bb278e878f1ae82 100644 (file)
        ;;
 
 // CR[IRR%] (and others)
-       mov     r0 = cr.ivr
-       mov     r1 = cr.ivr
+       mov     r2 = cr.ivr
+       mov     r3 = cr.ivr
        ;;
        
 // CR[ISR]
 // 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)
 
 // 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)
index a6fe570371fbb607f5e174212511503c6382aec2..c908063b9c97ae7e875b57e9728a230d52f030fa 100644 (file)
@@ -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 (file)
index 0000000..bd4dbc4
--- /dev/null
@@ -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 (file)
index 0000000..88124d3
--- /dev/null
@@ -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]