This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] ARC handling of LD and ST instructions


This patch does the following things:

- Cleans up handling of the 'c' register in the ST opcode by removing
  overloading of that token during parsing.
- Adds (missing) handling of:
      ld reg, [val]
  where val is shimm, rather than limm.
  EVEN shimm values are encoded as:       ld reg, [val/2, val/2]
  ODD shimm values are encoded as a 64b:  ld reg, [limm]

Note: my version 1.1.1.1 corresponds to the binutils-010604 snapshot.

Let me know if there are any problems with this patch.

Stacey.

diff -p -r1.1.1.1 -r1.5
*** binutils/opcodes/arc-opc.c	2001/06/04 17:53:56	1.1.1.1
--- binutils/opcodes/arc-opc.c	2001/06/20 17:30:45	1.5
*************** const struct arc_operand arc_operands[] 
*** 135,142 ****
  #define REGC (REGB + 1)
    { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR,
insert_reg, extract_reg },
  
  /* fake operand used to insert shimm value into most instructions.  */
! #define SHIMMFINISH (REGC + 1)
    { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish,
0 },
  
  /* fake operand used to insert limm value into most instructions.  */
--- 135,146 ----
  #define REGC (REGB + 1)
    { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR,
insert_reg, extract_reg },
  
+ /* register C for st instructions */
+ #define REGC_ST (REGC + 1)
+   { 'C', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR,
insert_reg, extract_reg },
+ 
  /* fake operand used to insert shimm value into most instructions.  */
! #define SHIMMFINISH (REGC_ST + 1)
    { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish,
0 },
  
  /* fake operand used to insert limm value into most instructions.  */
*************** struct arc_opcode arc_opcodes[] =
*** 337,346 ****
    { "sbc%.q%.f %a,%b,%c%F%S%L",	I(-1), I(11), ARC_MACH_5, 0, 0 },
    { "sexb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(5), ARC_MACH_5, 0, 0 },
    { "sexw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(6), ARC_MACH_5, 0, 0 },
!   { "sr %c,[%Ab]%S%L", I(-1)|A(-1), I(2)|A(0x10), ARC_MACH_5, 0, 0 },
    /* "[%b]" is before "[%b,%o]" so 0 offsets don't get printed.  */
!   { "st%y%.v%.D %c,[%s]%L%S%0", I(-1)|R(-1,25,1)|R(-1,21,1),
I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
!   { "st%y%.v%.D %c,[%s,%o]%S%L%2", I(-1)|R(-1,25,1)|R(-1,21,1),
I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
    { "sub%.q%.f %a,%b,%c%F%S%L",	I(-1), I(10), ARC_MACH_5, 0, 0 },
    { "xor%.q%.f %a,%b,%c%F%S%L",	I(-1), I(15), ARC_MACH_5, 0, 0 }
  };
--- 341,351 ----
    { "sbc%.q%.f %a,%b,%c%F%S%L",	I(-1), I(11), ARC_MACH_5, 0, 0 },
    { "sexb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(5), ARC_MACH_5, 0, 0 },
    { "sexw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(6), ARC_MACH_5, 0, 0 },
!   { "sr %C,[%Ab]%S%L", I(-1)|A(-1), I(2)|A(0x10), ARC_MACH_5, 0, 0 },
! 
    /* "[%b]" is before "[%b,%o]" so 0 offsets don't get printed.  */
!   { "st%y%.v%.D %C,[%s]%L%S%0", I(-1)|R(-1,25,1)|R(-1,21,1),
I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
!   { "st%y%.v%.D %C,[%s,%o]%S%L%2", I(-1)|R(-1,25,1)|R(-1,21,1),
I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
    { "sub%.q%.f %a,%b,%c%F%S%L",	I(-1), I(10), ARC_MACH_5, 0, 0 },
    { "xor%.q%.f %a,%b,%c%F%S%L",	I(-1), I(15), ARC_MACH_5, 0, 0 }
  };
*************** insert_reg (insn, operand, mods, reg, va
*** 783,792 ****
        ls_operand[LS_BASE] = op_type;
        break;
      case 'c':
!       if ((insn & I(-1)) == I(2))
! 	ls_operand[LS_VALUE] = op_type;
!       else
! 	ls_operand[LS_OFFSET] = op_type;
        break;
      case 'o': case 'O':
        ls_operand[LS_OFFSET] = op_type;
--- 788,797 ----
        ls_operand[LS_BASE] = op_type;
        break;
      case 'c':
!       ls_operand[LS_OFFSET] = op_type;
!       break;
!     case 'C':
!       ls_operand[LS_VALUE] = op_type;
        break;
      case 'o': case 'O':
        ls_operand[LS_OFFSET] = op_type;
*************** insert_ld_syntax (insn, operand, mods, r
*** 1205,1210 ****
--- 1210,1241 ----
  	   || ls_operand[LS_OFFSET] == OP_SHIMM))
  	*errmsg = "invalid load/shimm insn";
      }
+   if (LD_SYNTAX(OP_REG,OP_SHIMM,OP_NONE) && (test == I(1)))
+     {
+       /* change an illegal instruction to a legal one */
+       if (shimm & 0x1)          /* odd shimms won't work. */
+         {
+           if (limm_p)             /* do we have a limm already? */
+             {
+               *errmsg = "impossible ld";
+             }
+           limm_p = 1;
+           limm = shimm;
+           shimm = 0;
+           shimm_p = 0;
+           insn = insn & ~(B(-1) | 511);
+           insn |= B(ARC_REG_LIMM);
+           ls_operand[LS_BASE] = OP_LIMM;
+         }
+       else
+         {
+           shimm >>= 1;
+           insn = insn & ~511;
+           insn |= shimm;
+           ls_operand[LS_OFFSET] = OP_SHIMM;
+         }
+     }
+ 
    if (!(LD_SYNTAX(OP_REG,OP_REG,OP_NONE)
  	|| LD_SYNTAX(OP_REG,OP_REG,OP_REG)
  	|| LD_SYNTAX(OP_REG,OP_REG,OP_SHIMM)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]