This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

[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);


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