[PATCH] ARC handling of LD and ST instructions
Stacey Sheldon
ssheldon@Catena.com
Wed Jun 20 11:02:00 GMT 2001
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)
More information about the Binutils
mailing list