2012-07-27 Sean Keys <skeys@ipdatasys.com>
authorSean Keys <skeys@ipdatasys.com>
Fri, 27 Jul 2012 22:33:22 +0000 (22:33 +0000)
committerSean Keys <skeys@ipdatasys.com>
Fri, 27 Jul 2012 22:33:22 +0000 (22:33 +0000)
gas/config/
* tc-xgate.c: Consolidated inc/dec/hi/low modifieres into
one function.
(xgate_parse_operand): Added %hi and %lo handling.
gas/testsuite/gas/xgate
* xgate.exp: Added hi/lo test.
* hilo.d: New test file
* hilo.s: Net test source file.

gas/config/tc-xgate.c
gas/testsuite/gas/xgate/hilo.d [new file with mode: 0644]
gas/testsuite/gas/xgate/hilo.s [new file with mode: 0644]
gas/testsuite/gas/xgate/xgate.exp

index 7db84ea25f5123e7700e335b8b8cfce257ac284b..19983e149f97f09ba7beac9bd08be4ad34827f02 100644 (file)
@@ -122,9 +122,7 @@ xgate_get_operands (char *, s_operand []);
 static register_id
 reg_name_search (char *);
 op_modifiers
-xgate_determine_hi_low(char **);
-op_modifiers
-xgate_determine_increment(char **);
+xgate_determine_modifiers(char **);
 
 void
 xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
@@ -142,7 +140,7 @@ static unsigned int prev = 0;
 static unsigned char fixup_required = 0;
 
 /* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
-static unsigned char macroClipping = 0;        
+static unsigned char autoHiLo = 0;     
 
 static char oper_check;
 static char flag_print_insn_syntax = 0;
@@ -540,7 +538,7 @@ md_assemble (char *input_line)
       else
         {
          /* Insn is a simplified instruction - expand it out.  */
-          macroClipping = 1;
+          autoHiLo = 1;
           unsigned int i;
 
           /* skip past our ';' separator.  */
@@ -581,7 +579,7 @@ md_assemble (char *input_line)
             }
         }
     }
-  macroClipping = 0;
+  autoHiLo = 0;
   input_line = saved_input_line;
 }
 
@@ -971,8 +969,7 @@ xgate_get_operands (char *line, s_operand oprs[])
       if (*line == '#')
         line++;
 
-      oprs[num_operands].mod = xgate_determine_hi_low (&line);
-      oprs[num_operands].mod = xgate_determine_increment (&line);
+      oprs[num_operands].mod = xgate_determine_modifiers (&line);
 
       if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
         line = xgate_parse_exp (line, &oprs[num_operands].exp);
@@ -1063,8 +1060,10 @@ reg_name_search (char *name)
   return REG_NONE;
 }
 
+/* Parse operand modifiers such as inc/dec/hi/low.  */
+
 op_modifiers
-xgate_determine_hi_low(char **line)
+xgate_determine_modifiers(char **line)
 {
   char *local_line = line[0];
 
@@ -1078,21 +1077,13 @@ xgate_determine_hi_low(char **line)
       *line += 3;
       return MOD_LOAD_LOW;
     }
-  return MOD_NONE;
-}
-
-op_modifiers
-xgate_determine_increment(char **line)
-{
-  char *local_line = line[0];
-
   if (*(local_line + 2) == '+')
-      return MOD_POSTINC;
+        return MOD_POSTINC;
   if (strncasecmp (local_line, "-r", 2) == 0)
     {
       *line += 1;
       return MOD_PREDEC;
-    }
+   }
   return MOD_NONE;
 }
 
@@ -1197,7 +1188,7 @@ xgate_parse_operand (struct xgate_opcode *opcode,
                int *bit_width,
                int where,
                char **op_con,
-               s_operand operand_two)
+               s_operand operand)
 {
   fixS *fixp = 0;
   char *op_constraint = *op_con;
@@ -1216,24 +1207,24 @@ xgate_parse_operand (struct xgate_opcode *opcode,
       pp_fix = 0;
       *bit_width = 5;
 
-      if (operand_two.reg == REG_NONE)
+      if (operand.reg == REG_NONE)
             as_bad (_(": expected register name r0-r7 ") );
-      op_mask = operand_two.reg;
-      if(operand_two.mod == MOD_POSTINC)
+      op_mask = operand.reg;
+      if(operand.mod == MOD_POSTINC)
         pp_fix = INCREMENT;
-      if(operand_two.mod == MOD_PREDEC)
+      if(operand.mod == MOD_PREDEC)
         pp_fix = DECREMENT;
       op_mask <<= 2;
       op_mask |= pp_fix;
       break;
 
     case 'r': /* Register operand.  */
-    if (operand_two.reg == REG_NONE)
+    if (operand.reg == REG_NONE)
       as_bad (_(": expected register name r0-r7 "));
 
     *bit_width = 3;
 
-    op_mask = operand_two.reg;
+    op_mask = operand.reg;
       break;
 
     case 'i': /* Immediate value or expression expected.  */
@@ -1253,15 +1244,16 @@ xgate_parse_operand (struct xgate_opcode *opcode,
           *bit_width = 0x0F;
         }
       /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
-      if (operand_two.exp.X_op == O_constant)
+      if (operand.exp.X_op == O_constant)
         {
-          op_mask = operand_two.exp.X_add_number;
-          if ((opcode->name[strlen (opcode->name) - 1] == 'l') && macroClipping)
+          op_mask = operand.exp.X_add_number;
+          if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
+              || operand.mod == MOD_LOAD_LOW)
             {
               op_mask &= 0x00FF;
             }
-          else if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
-                   && macroClipping)
+          else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
+                   && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
             {
               op_mask >>= 8;
             }
@@ -1277,42 +1269,46 @@ xgate_parse_operand (struct xgate_opcode *opcode,
         }
       else
         {
+          /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
+             TODO fix.  */
           fixup_required = 1;
           if (*op_constraint == '8')
             {
-              if ((opcode->name[strlen (opcode->name) - 1] == 'l')
-                  && macroClipping)
+              if (((opcode->name[strlen (opcode->name) - 1] == 'l')
+                  && autoHiLo) || operand.mod == MOD_LOAD_LOW)
                 {
-                  fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE,
+                    fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
                                       BFD_RELOC_XGATE_24);
-                  /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix.  */
-                  fixp->fx_pcrel_adjust = 0;
                 }
-              if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
-                  && macroClipping)
+              else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
+                  && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
                 {
-                  fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE,
+                    fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
                                       BFD_RELOC_XGATE_IMM8_HI);
-                  fixp->fx_pcrel_adjust = 0;
                 }
-              if (!fixp)
-                as_bad (_(":unknown relocation"));
+              else
+                {
+                  as_bad (_("you must use a hi/lo directive or 16-bit macro "
+                      "to load a 16-bit value."));
+                  break;
+                }
+              fixp->fx_pcrel_adjust = 0;
             }
           else if (*op_constraint == '5')
             {
-              fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE,
+              fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
                                   BFD_RELOC_XGATE_IMM5);
               fixp->fx_pcrel_adjust = 0;
             }
           else if (*op_constraint == '4')
             {
-              fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE,
+              fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
                                   BFD_RELOC_XGATE_IMM4);
               fixp->fx_pcrel_adjust = 0;
             }
           else if (*op_constraint == '3')
             {
-            fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, FALSE,
+            fixp = fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
                 BFD_RELOC_XGATE_IMM3);
             fixp->fx_pcrel_adjust = 0;
           }
@@ -1321,17 +1317,17 @@ xgate_parse_operand (struct xgate_opcode *opcode,
             as_bad (_(":unknown relocation constraint size"));
           }
       }
-    break;
+      break;
 
     case 'c': /* CCR register expected.  */
       *bit_width = 0;
-      if (operand_two.reg != REG_CCR)
+      if (operand.reg != REG_CCR)
             as_bad (_(": expected register name ccr "));
-    break;
+      break;
 
     case 'p': /* PC register expected.  */
       *bit_width = 0;
-            if (operand_two.reg != REG_PC)
+            if (operand.reg != REG_PC)
                   as_bad (_(": expected register name pc "));
       break;
 
@@ -1339,24 +1335,24 @@ xgate_parse_operand (struct xgate_opcode *opcode,
       (*op_con)++;
       op_constraint++;
 
-      if (operand_two.exp.X_op != O_register)
+      if (operand.exp.X_op != O_register)
         {
           if (*op_constraint == '9')
             {
-              fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, TRUE,
+              fixp = fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
                                   R_XGATE_PCREL_9);
               fixp->fx_pcrel_adjust = 1;
             }
           else if (*op_constraint == 'a')
             {
-              fixp = fix_new_exp (frag_now, where, 2, &operand_two.exp, TRUE,
+              fixp = fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
                                   R_XGATE_PCREL_10);
               fixp->fx_pcrel_adjust = 1;
             }
         }
       else
         {
-          as_fatal (_("Operand `%x' not recognized in fixup8."), operand_two.exp.X_op);
+          as_fatal (_("Operand `%x' not recognized in fixup8."), operand.exp.X_op);
         }
       break;
     case '?':
diff --git a/gas/testsuite/gas/xgate/hilo.d b/gas/testsuite/gas/xgate/hilo.d
new file mode 100644 (file)
index 0000000..32c0a68
--- /dev/null
@@ -0,0 +1,26 @@
+#objdump: -d --prefix-addresses --reloc
+#as: 
+#name: hilo
+
+# Test for correct generation of XGATE insns when using the %hi and %lo modifiers.
+
+.*: +file format elf32\-xgate
+
+Disassembly of section .text:
+0+0000 <hiTestLo> ldl R2, #0x88
+0+0002 <hiTestHi> ldh R2, #0x88 Abs\* 0x00008888 <symValue\+0x8870>
+0+0004 <loTestLo> ldl R3, #0x44
+0+0006 <loTestHi> ldh R3, #0x44 Abs\* 0x00004444 <symValue\+0x442c>
+0+0008 <hiTestLoF> ldl R2, #0xff
+0+000a <hiTestHiF> ldh R2, #0xff Abs\* 0x0000ffff <test\+0x77>
+0+000c <loTestLoF> ldl R3, #0x88
+0+000e <loTestHiF> ldh R3, #0x88 Abs\* 0x00008888 <symValue\+0x8870>
+0+0010 <hiTestLoR> ldl R2, #0x00
+                       10: R_XGATE_IMM8_HI     .text
+0+0012 <hiTestHiR> ldh R2, #0x00 Abs\* 0x00000000 <hiTestLo>
+                       12: R_XGATE_IMM8_HI     .text
+0+0014 <loTestLoR> ldl R3, #0x18
+                       14: R_XGATE_IMM8_LO     .text
+0+0016 <loTestHiR> ldh R3, #0x18 Abs\* 0x00001818 <symValue\+0x1800>
+                       16: R_XGATE_IMM8_LO     .text
+
diff --git a/gas/testsuite/gas/xgate/hilo.s b/gas/testsuite/gas/xgate/hilo.s
new file mode 100644 (file)
index 0000000..c157a6a
--- /dev/null
@@ -0,0 +1,33 @@
+# Test for correct generation of XGATE insns when using the %hi and %lo modifiers.
+       
+       .sect .text
+;Test Constants
+hiTestLo:
+       ldl R2, %hi(0x8844)
+hiTestHi:
+       ldh R2, %hi(0x8844)
+loTestLo:
+       ldl R3, %lo(0x8844)
+loTestHi:
+       ldh R3, %lo(0x8844)
+;Test Fixups
+hiTestLoF:
+       ldl R2, %hi(test)
+hiTestHiF:
+       ldh R2, %hi(test)
+loTestLoF:
+       ldl R3, %lo(test)
+loTestHiF:
+       ldh R3, %lo(test)
+;Test Relocs
+hiTestLoR:
+       ldl R2, %hi(symValue)
+hiTestHiR:
+       ldh R2, %hi(symValue)
+loTestLoR:
+       ldl R3, %lo(symValue)
+loTestHiR:
+       ldh R3, %lo(symValue)
+
+symValue:
+test = 0xff88
index 1af5e7622493aba9f00055a03025b0fba60a122c..eb5296a4c2b8cdbda3faf179551137f62946b680 100644 (file)
@@ -16,4 +16,5 @@ run_dump_test abi-xgate-32-32
 run_dump_test insns-dwarf2
 run_dump_test all_insns
 run_dump_test insns
+run_dump_test hilo