This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
MIPS -gp32 patch
- To: binutils at sourceware dot cygnus dot com
- Subject: MIPS -gp32 patch
- From: Andrew Haley <aph at pasanda dot cygnus dot co dot uk>
- Date: 30 Dec 1999 18:32:57 -0000
This is to support MIPS gcc's "-mgp32" flag, which doesn't work at the
moment.
The idea of "-mgp32" is to generate 32-bit programs which run on
64-bit hardware. gcc already supports this option, but there is a
problem.
Some newer MIPS parts have a 32/64 mode bit which causes an insn trap
if a 64-bit insn is executed. However, at present gas generates a
"dadd rn, r0, rm" insn for "move rn, rm" assembly source, so we aren't
generating true 32-bit code with "-mgp32".
In order to fix this, we need to pass the "gp32" flag to gas and
prevent 64-bit forms of the move insn from being generated. I've
added an new insn flag, INSN_GP32, which is used only with -mgp32. I
have not prevented 64-bit insns from being generated if they're
explicitly required in the source as this would require tagging every
64-bit insn and seems like overkill.
The gcc changes to do this have already been approved.
OK?
Andrew.
1999-12-30 Andrew Haley <aph@cygnus.com>
* mips.h (OPCODE_IS_MEMBER): Add gp32 arg.
1999-12-30 Andrew Haley <aph@cygnus.com>
* mips-dis.c (_print_insn_mips): New arg for OPCODE_IS_MEMBER:
force gp32 to zero.
* mips-opc.c (G6): New define.
(mips_builtin_op): Add "move" definition for -gp32.
1999-12-30 Andrew Haley <aph@cygnus.com>
* config/tc-mips.c (mips_gp32): New variable.
(macro_build) Use mips_gp32.
(mips_ip): Ditto.
(md_longopts): Add "-mgp32" and "-mgp64".
(md_parse_option): Add OPTION_GP32 and OPTION_GP64.
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/config/tc-mips.c,v
retrieving revision 1.8
diff -p -2 -c -r1.8 tc-mips.c
*** tc-mips.c 1999/11/01 19:29:55 1.8
--- tc-mips.c 1999/12/30 18:29:27
*************** static int mips_eabi64 = 0;
*** 204,207 ****
--- 204,210 ----
static int mips_32bitmode = 0;
+ /* True if -mgp32 was passed. */
+ static int mips_gp32 = 0;
+
/* Some ISA's have delay slots for instructions which read or write
from a coprocessor (eg. mips1-mips3); some don't (eg mips4).
*************** macro_build (place, counter, ep, name, f
*** 2460,2464 ****
if (strcmp (fmt, insn.insn_mo->args) == 0
&& insn.insn_mo->pinfo != INSN_MACRO
! && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu)
&& (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0))
break;
--- 2463,2468 ----
if (strcmp (fmt, insn.insn_mo->args) == 0
&& insn.insn_mo->pinfo != INSN_MACRO
! && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu,
! mips_gp32)
&& (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0))
break;
*************** mips_ip (str, ip)
*** 7010,7014 ****
assert (strcmp (insn->name, str) == 0);
! if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_cpu))
ok = true;
else
--- 7014,7018 ----
assert (strcmp (insn->name, str) == 0);
! if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_cpu, mips_gp32))
ok = true;
else
*************** struct option md_longopts[] = {
*** 8817,8820 ****
--- 8821,8829 ----
#endif
+ #define OPTION_GP32 (OPTION_MD_BASE + 41)
+ #define OPTION_GP64 (OPTION_MD_BASE + 42)
+ {"mgp32", no_argument, NULL, OPTION_GP32},
+ {"mgp64", no_argument, NULL, OPTION_GP64},
+
{NULL, no_argument, NULL, 0}
};
*************** md_parse_option (c, arg)
*** 9117,9120 ****
--- 9126,9140 ----
break;
+ case OPTION_GP32:
+ mips_gp32 = 1;
+ mips_64 = 0;
+ mips_32bitmode = 1;
+ break;
+
+ case OPTION_GP64:
+ mips_gp32 = 0;
+ mips_64 = 1;
+ mips_32bitmode = 0;
+ break;
case OPTION_MABI:
Index: include/opcode/mips.h
===================================================================
RCS file: /cvs/binutils/binutils/include/opcode/mips.h,v
retrieving revision 1.3
diff -p -2 -c -r1.3 mips.h
*** mips.h 1999/11/18 19:53:48 1.3
--- mips.h 1999/12/30 18:29:29
*************** struct mips_opcode
*** 321,324 ****
--- 321,327 ----
#define INSN_3900 0x00000080
+ /* 32-bit code running on a ISA3+ CPU. */
+ #define INSN_GP32 0x00001000
+
/* Test for membership in an ISA including chip specific ISAs.
INSN is pointer to an element of the opcode table; ISA is the
*************** struct mips_opcode
*** 326,332 ****
to test, or zero if no CPU specific ISA test is desired. */
! #define OPCODE_IS_MEMBER(insn,isa,cpu) \
((((insn)->membership & INSN_ISA) != 0 \
! && ((insn)->membership & INSN_ISA) <= isa) \
|| (cpu == 4650 \
&& ((insn)->membership & INSN_4650) != 0) \
--- 329,336 ----
to test, or zero if no CPU specific ISA test is desired. */
! #define OPCODE_IS_MEMBER(insn,isa,cpu,gp32) \
((((insn)->membership & INSN_ISA) != 0 \
! && ((insn)->membership & INSN_ISA) <= isa \
! && ((insn)->membership & INSN_GP32 ? gp32 : 1)) \
|| (cpu == 4650 \
&& ((insn)->membership & INSN_4650) != 0) \
Index: opcodes/mips-dis.c
===================================================================
RCS file: /cvs/binutils/binutils/opcodes/mips-dis.c,v
retrieving revision 1.2
diff -p -2 -c -r1.2 mips-dis.c
*** mips-dis.c 1999/11/01 19:29:55 1.2
--- mips-dis.c 1999/12/30 18:29:32
*************** _print_insn_mips (memaddr, word, info)
*** 389,393 ****
register const char *d;
! if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
continue;
--- 389,393 ----
register const char *d;
! if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
continue;
Index: opcodes/mips-opc.c
===================================================================
RCS file: /cvs/binutils/binutils/opcodes/mips-opc.c,v
retrieving revision 1.4
diff -p -2 -c -r1.4 mips-opc.c
*** mips-opc.c 1999/11/18 19:53:48 1.4
--- mips-opc.c 1999/12/30 18:29:32
*************** Software Foundation, 59 Temple Place - S
*** 92,95 ****
--- 92,97 ----
)
+ #define G6 INSN_GP32
+
#define M1 0
#define M2 0
*************** const struct mips_opcode mips_builtin_op
*** 114,117 ****
--- 116,120 ----
{"li", "t,i", 0x34000000, 0xffe00000, WR_t, I1 }, /* ori */
{"li", "t,I", 0, (int) M_LI, INSN_MACRO, I1 },
+ {"move", "d,s", 0x00000025, 0xfc1f07ff, WR_d|RD_s, I1|G6 },/* or */
{"move", "d,s", 0x0000002d, 0xfc1f07ff, WR_d|RD_s, I3 },/* daddu */
{"move", "d,s", 0x00000021, 0xfc1f07ff, WR_d|RD_s, I1 },/* addu */