This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[committed] Add MIPS16 macro operand "I"
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Sun, 14 Jul 2013 14:11:07 +0100
- Subject: [committed] Add MIPS16 macro operand "I"
The immediate operands to MIPS16 macros use specific field types like
"8" and "4". This usually reflects the operand that the final instruction
will use, but is a bit more arbitrary for things like SUBU, where the
operand is negated first. The choice of operand doesn't really matter
anyway, since the only thing that the macro code looks at is imm_expr.
It seemed clearer to use a mips-opc.c-style "I" operand instead.
The checks and error have been cut-&-pasted (ick) from the mips_ip code.
At some point we need to clean up the error capitalisation issues
and O_big stuff, but that's for another day.
Tested on various targets and applied.
Richard
include/opcode/
* mips.h: Document MIPS16 "I" opcode.
opcodes/
* mips16-opc.c (mips16_opcodes): Use "I" for immediate operands
in macros.
gas/
* config/tc-mips.c (mips16_ip): Handle "I".
Index: include/opcode/mips.h
===================================================================
--- include/opcode/mips.h 2013-07-14 10:15:36.816271679 +0100
+++ include/opcode/mips.h 2013-07-14 10:18:04.474084245 +0100
@@ -1305,6 +1305,8 @@ #define MIPS16OP_SH_IMM6 5
"l" register list for entry instruction
"L" register list for exit instruction
+ "I" an immediate value used for macros
+
The remaining codes may be extended. Except as otherwise noted,
the full extended operand is a 16 bit signed value.
"<" 3 bit unsigned shift count * 0 (MIPS16OP_*_RZ) (full 5 bit unsigned)
Index: opcodes/mips16-opc.c
===================================================================
--- opcodes/mips16-opc.c 2013-07-14 10:11:42.365962036 +0100
+++ opcodes/mips16-opc.c 2013-07-14 10:18:04.474084245 +0100
@@ -89,26 +89,26 @@ const struct mips_opcode mips16_opcodes[
{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y, 0, I1 },
{"b", "q", 0x1000, 0xf800, UBR, 0, I1 },
{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, I1 },
-{"beq", "x,U,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1 },
+{"beq", "x,I,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1 },
{"beqz", "x,p", 0x2000, 0xf800, CBR|RD_x, 0, I1 },
{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, I1 },
-{"bge", "x,8,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1 },
+{"bge", "x,I,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1 },
{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1 },
-{"bgeu", "x,8,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, I1 },
+{"bgeu", "x,I,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, I1 },
{"bgt", "x,y,p", 0, (int) M_BGT, INSN_MACRO, 0, I1 },
-{"bgt", "x,8,p", 0, (int) M_BGT_I, INSN_MACRO, 0, I1 },
+{"bgt", "x,I,p", 0, (int) M_BGT_I, INSN_MACRO, 0, I1 },
{"bgtu", "x,y,p", 0, (int) M_BGTU, INSN_MACRO, 0, I1 },
-{"bgtu", "x,8,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, I1 },
+{"bgtu", "x,I,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, I1 },
{"ble", "x,y,p", 0, (int) M_BLE, INSN_MACRO, 0, I1 },
-{"ble", "x,8,p", 0, (int) M_BLE_I, INSN_MACRO, 0, I1 },
+{"ble", "x,I,p", 0, (int) M_BLE_I, INSN_MACRO, 0, I1 },
{"bleu", "x,y,p", 0, (int) M_BLEU, INSN_MACRO, 0, I1 },
-{"bleu", "x,8,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, I1 },
+{"bleu", "x,I,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, I1 },
{"blt", "x,y,p", 0, (int) M_BLT, INSN_MACRO, 0, I1 },
-{"blt", "x,8,p", 0, (int) M_BLT_I, INSN_MACRO, 0, I1 },
+{"blt", "x,I,p", 0, (int) M_BLT_I, INSN_MACRO, 0, I1 },
{"bltu", "x,y,p", 0, (int) M_BLTU, INSN_MACRO, 0, I1 },
-{"bltu", "x,8,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1 },
+{"bltu", "x,I,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1 },
{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1 },
-{"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 },
+{"bne", "x,I,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 },
{"bnez", "x,p", 0x2800, 0xf800, CBR|RD_x, 0, I1 },
{"break", "6", 0xe805, 0xf81f, TRAP, 0, I1 },
{"bteqz", "p", 0x6000, 0xff00, CBR|RD_T, 0, I1 },
@@ -155,8 +155,8 @@ const struct mips_opcode mips16_opcodes[
{"dsrl", "y,]", 0xe808, 0xf81f, WR_y|RD_y, 0, I3 },
{"dsrl", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3 },
{"dsubu", "z,v,y", 0xe002, 0xf803, WR_z|RD_x|RD_y, 0, I3 },
-{"dsubu", "y,x,4", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1 },
-{"dsubu", "y,j", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1 },
+{"dsubu", "y,x,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1 },
+{"dsubu", "y,I", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1 },
{"exit", "L", 0xed09, 0xff1f, TRAP, 0, I1 },
{"exit", "L", 0xee09, 0xff1f, TRAP, 0, I1 },
{"exit", "", 0xef09, 0xffff, TRAP, 0, I1 },
@@ -230,8 +230,8 @@ const struct mips_opcode mips16_opcodes[
{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y, 0, I1 },
{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1 },
{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y, 0, I1 },
-{"subu", "y,x,4", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 },
-{"subu", "x,k", 0, (int) M_SUBU_I_2, INSN_MACRO,0, I1 },
+{"subu", "y,x,I", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 },
+{"subu", "x,I", 0, (int) M_SUBU_I_2, INSN_MACRO,0, I1 },
{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x, 0, I1 },
{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP, 0, I1 },
{"sw", "R,V(S)", 0x6200, 0xff00, RD_31|RD_SP, 0, I1 },
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c 2013-07-14 10:17:02.520495807 +0100
+++ gas/config/tc-mips.c 2013-07-14 10:20:31.527543003 +0100
@@ -14223,6 +14223,16 @@ mips16_ip (char *str, struct mips_cl_ins
s = expr_end;
continue;
+ case 'I':
+ my_getExpression (&imm_expr, s);
+ if (imm_expr.X_op != O_big
+ && imm_expr.X_op != O_constant)
+ insn_error = _("absolute expression required");
+ if (HAVE_32BIT_GPRS)
+ normalize_constant_expr (&imm_expr);
+ s = expr_end;
+ continue;
+
case 'a': /* 26 bit address */
case 'i':
my_getExpression (&offset_expr, s);