diff options
author | Andrew Bennett <andrew.bennett@imgtec.com> | 2019-04-22 15:12:09 -0700 |
---|---|---|
committer | Faraz Shahbazker <fshahbazker@wavecomp.com> | 2019-04-26 18:28:05 -0700 |
commit | a45328b93bdd5399da8a9e56817e445cc2068edd (patch) | |
tree | d611c35292391d313d6d99f80aa1495fdbdef046 /gas/config | |
parent | 45f0ab12d463cb3999a4286e679bdef05884b3a3 (diff) | |
download | gdb-a45328b93bdd5399da8a9e56817e445cc2068edd.zip gdb-a45328b93bdd5399da8a9e56817e445cc2068edd.tar.gz gdb-a45328b93bdd5399da8a9e56817e445cc2068edd.tar.bz2 |
[MIPS] Add load-link, store-conditional paired instructions
Add several baseline MIPS32R6[1] and MIPS64R6[2] instructions
that were omitted from the initial spec. These instructions
are optional in implementations but not associated with any
ASE or pseudo-ASE. Their presence is indicated by the XNP bit
in the Config5 register.
[1] "MIPS Architecture for Programmers Volume II-A: The MIPS32
Instruction Set Manual", Imagination Technologies Ltd., Document
Number: MD00086, Revision 6.06, December 15, 2016, Section 3.2
"Alphabetical List of Instructions", pp. 228-229, pp. 354-357.
[2] "MIPS Architecture for Programmers Volume II-A: The MIPS64
Instruction Set Manual", Imagination Technologies Ltd., Document
Number: MD00087, Revision 6.06, December 15, 2016, Section 3.2
"Alphabetical List of Instructions", pp. 289-290 and pp. 458-460.
gas/
* config/tc-mips.c (macro) <M_LLWP_AB, M_LLDP_AB, M_SCWP_AB,
M_SCDP_AB>: New cases and expansions for paired instructions.
* testsuite/gas/mips/llpscp-32.s: New test source.
* testsuite/gas/mips/llpscp-64.s: Likewise.
* testsuite/gas/mips/llpscp-32.d: New test.
* testsuite/gas/mips/llpscp-64.d: Likewise.
* testsuite/gas/mips/mips.exp: Run the new tests.
* testsuite/gas/mips/r6.s: Add new instructions to test source.
* testsuite/gas/mips/r6-64.s: Likewise.
* testsuite/gas/mips/r6-64-n32.d: Check new instructions.
* testsuite/gas/mips/r6-64-n64.d: Likewise.
* testsuite/gas/mips/r6-n32.d: Likewise.
* testsuite/gas/mips/r6-n64.d: Likwwise.
* testsuite/gas/mips/r6.d: Likewise.
include/
* opcode/mips.h (M_LLWP_AB, M_LLDP_AB): New enum values.
(M_SCWP_AB, M_SCDP_AB): Likewise.
opcodes/
* mips-opc.c (mips_builtin_opcodes): Add llwp, lldp, scwp, scdp.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-mips.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index f3e3341..091ea7b 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -10279,6 +10279,7 @@ macro (struct mips_cl_insn *ip, char *str) int imm = 0; int ust = 0; int lp = 0; + int ll_sc_paired = 0; bfd_boolean large_offset; int off; int hold_mips_optimize; @@ -12014,6 +12015,13 @@ macro (struct mips_cl_insn *ip, char *str) offbits = 12; lp = 1; goto ld; + case M_LLDP_AB: + case M_LLWP_AB: + s = ip->insn_mo->name; + fmt = "t,d,s"; + ll_sc_paired = 1; + offbits = 0; + goto ld; case M_LWM_AB: gas_assert (mips_opts.micromips); s = "lwm"; @@ -12028,11 +12036,26 @@ macro (struct mips_cl_insn *ip, char *str) goto ld_st; ld: - /* We don't want to use $0 as tempreg. */ - if (op[2] == op[0] + lp || op[0] + lp == ZERO) - goto ld_st; + /* Try to use one the the load registers to compute the base address. + We don't want to use $0 as tempreg. */ + if (ll_sc_paired) + { + if ((op[0] == ZERO && op[3] == op[1]) + || (op[1] == ZERO && op[3] == op[0]) + || (op[0] == ZERO && op[1] == ZERO)) + goto ld_st; + else if (op[0] != op[3] && op[0] != ZERO) + tempreg = op[0]; + else + tempreg = op[1]; + } else - tempreg = op[0] + lp; + { + if (op[2] == op[0] + lp || op[0] + lp == ZERO) + goto ld_st; + else + tempreg = op[0] + lp; + } goto ld_noat; case M_SB_AB: @@ -12100,6 +12123,13 @@ macro (struct mips_cl_insn *ip, char *str) : ISA_IS_R6 (mips_opts.isa) ? 9 : 16); goto ld_st; + case M_SCDP_AB: + case M_SCWP_AB: + s = ip->insn_mo->name; + fmt = "t,d,s"; + ll_sc_paired = 1; + offbits = 0; + goto ld_st; case M_CACHE_AB: s = "cache"; fmt = (mips_opts.micromips ? "k,~(b)" @@ -12193,7 +12223,7 @@ macro (struct mips_cl_insn *ip, char *str) ld_st: tempreg = AT; ld_noat: - breg = op[2]; + breg = ll_sc_paired ? op[3] : op[2]; if (small_offset_p (0, align, 16)) { /* The first case exists for M_LD_AB and M_SD_AB, which are @@ -12205,7 +12235,12 @@ macro (struct mips_cl_insn *ip, char *str) else if (small_offset_p (0, align, offbits)) { if (offbits == 0) - macro_build (NULL, s, fmt, op[0], breg); + { + if (ll_sc_paired) + macro_build (NULL, s, fmt, op[0], op[1], breg); + else + macro_build (NULL, s, fmt, op[0], breg); + } else macro_build (NULL, s, fmt, op[0], (int) offset_expr.X_add_number, breg); @@ -12218,7 +12253,12 @@ macro (struct mips_cl_insn *ip, char *str) tempreg, breg, -1, offset_reloc[0], offset_reloc[1], offset_reloc[2]); if (offbits == 0) - macro_build (NULL, s, fmt, op[0], tempreg); + { + if (ll_sc_paired) + macro_build (NULL, s, fmt, op[0], op[1], tempreg); + else + macro_build (NULL, s, fmt, op[0], tempreg); + } else macro_build (NULL, s, fmt, op[0], 0, tempreg); } @@ -12261,7 +12301,10 @@ macro (struct mips_cl_insn *ip, char *str) if (offset_expr.X_add_number != 0) macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg, tempreg, BFD_RELOC_LO16); - macro_build (NULL, s, fmt, op[0], tempreg); + if (ll_sc_paired) + macro_build (NULL, s, fmt, op[0], op[1], tempreg); + else + macro_build (NULL, s, fmt, op[0], tempreg); } else if (offbits == 16) macro_build (&offset_expr, s, fmt, op[0], BFD_RELOC_LO16, tempreg); @@ -12279,7 +12322,12 @@ macro (struct mips_cl_insn *ip, char *str) macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", tempreg, tempreg, breg); if (offbits == 0) - macro_build (NULL, s, fmt, op[0], tempreg); + { + if (ll_sc_paired) + macro_build (NULL, s, fmt, op[0], op[1], tempreg); + else + macro_build (NULL, s, fmt, op[0], tempreg); + } else macro_build (NULL, s, fmt, op[0], 0, tempreg); } |