diff options
author | Adam Nemet <anemet@caviumnetworks.com> | 2008-07-07 19:16:23 +0000 |
---|---|---|
committer | Adam Nemet <anemet@caviumnetworks.com> | 2008-07-07 19:16:23 +0000 |
commit | b19e8a9baee7c520847208842502e38e7b5116dc (patch) | |
tree | 8ec6471d9bd931ab01dd59aa8833087f71508d51 | |
parent | 79947c5421861704e56232699b629b1f13d400e3 (diff) | |
download | gdb-b19e8a9baee7c520847208842502e38e7b5116dc.zip gdb-b19e8a9baee7c520847208842502e38e7b5116dc.tar.gz gdb-b19e8a9baee7c520847208842502e38e7b5116dc.tar.bz2 |
* config/tc-mips.c (NO_ISA_COP): New macro.
(COP_INSN): New macro.
(is_opcode_valid): Use them.
(macro) <ld_st>: Use them. Don't accept coprocessor load store
insns based on the ISA if CPU is NO_ISA_COP.
<copz>: Likewise for coprocessor operations.
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-mips.c | 40 |
2 files changed, 48 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 225b521..bb82182 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2008-07-07 Adam Nemet <anemet@caviumnetworks.com> + + * config/tc-mips.c (NO_ISA_COP): New macro. + (COP_INSN): New macro. + (is_opcode_valid): Use them. + (macro) <ld_st>: Use them. Don't accept coprocessor load store + insns based on the ISA if CPU is NO_ISA_COP. + <copz>: Likewise for coprocessor operations. + 2008-07-07 Paul Brook <paul@codesourcery.com> * config/tc-arm.c (arm_fix_adjustable): Don't adjust MOVW/MOVT diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index f544e6a..d5ed84c 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -447,6 +447,11 @@ static int mips_32bitmode = 0; /* True if CPU has seq/sne and seqi/snei instructions. */ #define CPU_HAS_SEQ(CPU) ((CPU) == CPU_OCTEON) +/* True if CPU does not implement the all the coprocessor insns. For these + CPUs only those COP insns are accepted that are explicitly marked to be + available on the CPU. ISA membership for COP insns is ignored. */ +#define NO_ISA_COP(CPU) ((CPU) == CPU_OCTEON) + /* True if mflo and mfhi can be immediately followed by instructions which write to the HI and LO registers. @@ -504,7 +509,17 @@ static int mips_32bitmode = 0; /* Is this a mfhi or mflo instruction? */ #define MF_HILO_INSN(PINFO) \ - ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO)) + ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO)) + +/* Returns true for a (non floating-point) coprocessor instruction. Reading + or writing the condition code is only possible on the coprocessors and + these insns are not marked with INSN_COP. Thus for these insns use the + condition-code flags unless this is the floating-point coprocessor. */ +#define COP_INSN(PINFO) \ + (PINFO != INSN_MACRO \ + && (((PINFO) & INSN_COP) \ + || ((PINFO) & (INSN_READ_COND_CODE | INSN_WRITE_COND_CODE) \ + && ((PINFO) & (FP_S | FP_D)) == 0))) /* MIPS PIC level. */ @@ -1803,6 +1818,12 @@ is_opcode_valid (const struct mips_opcode *mo, bfd_boolean expansionp) if (expansionp ? mips_opts.mips16 : file_ase_mips16) isa |= INSN_MIPS16; + /* Don't accept instructions based on the ISA if the CPU does not implement + all the coprocessor insns. */ + if (NO_ISA_COP (mips_opts.arch) + && COP_INSN (mo->pinfo)) + isa = 0; + if (!OPCODE_IS_MEMBER (mo, isa, mips_opts.arch)) return FALSE; @@ -6312,6 +6333,15 @@ macro (struct mips_cl_insn *ip) tempreg = AT; used_at = 1; ld_st: + if (coproc + && NO_ISA_COP (mips_opts.arch) + && (ip->insn_mo->pinfo2 & (INSN2_M_FP_S | INSN2_M_FP_D)) == 0) + { + as_bad (_("opcode not supported on this processor: %s"), + mips_cpu_info_from_arch (mips_opts.arch)->name); + break; + } + /* Itbl support may require additional care here. */ if (mask == M_LWC1_AB || mask == M_SWC1_AB @@ -7180,6 +7210,14 @@ macro (struct mips_cl_insn *ip) case M_COP3: s = "c3"; copz: + if (NO_ISA_COP (mips_opts.arch) + && (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0) + { + as_bad (_("opcode not supported on this processor: %s"), + mips_cpu_info_from_arch (mips_opts.arch)->name); + break; + } + /* For now we just do C (same as Cz). The parameter will be stored in insn_opcode by mips_ip. */ macro_build (NULL, s, "C", ip->insn_opcode); |