diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:03 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:03 -0500 |
commit | 2196f75a25e3a958c56686a5a19b21df9db0e750 (patch) | |
tree | 29c080b95f6e308f3011bcc1ad54e69ba85e7601 | |
parent | 33da368e99955230a7d83c33c49c42fb59ec5015 (diff) | |
download | gem5-2196f75a25e3a958c56686a5a19b21df9db0e750.tar.xz |
ARM: Hook the new multiply instructions into all the decoders.
-rw-r--r-- | src/arch/arm/isa/bitfields.isa | 1 | ||||
-rw-r--r-- | src/arch/arm/isa/decoder/arm.isa | 223 | ||||
-rw-r--r-- | src/arch/arm/isa/decoder/thumb.isa | 4 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/data.isa | 3 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/formats.isa | 3 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/mult.isa | 440 | ||||
-rw-r--r-- | src/arch/arm/types.hh | 1 |
7 files changed, 520 insertions, 155 deletions
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 29f3e746e..abaedd024 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -52,6 +52,7 @@ def bitfield MEDIA_OPCODE mediaOpcode; def bitfield MEDIA_OPCODE2 mediaOpcode2; def bitfield USEIMM useImm; def bitfield OPCODE_24 opcode24; +def bitfield OPCODE_24_23 opcode24_23; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; diff --git a/src/arch/arm/isa/decoder/arm.isa b/src/arch/arm/isa/decoder/arm.isa index 06f540717..d84a6a5dc 100644 --- a/src/arch/arm/isa/decoder/arm.isa +++ b/src/arch/arm/isa/decoder/arm.isa @@ -55,34 +55,7 @@ format DataOp { 0x0: decode SEVEN_AND_FOUR { 1: decode MISC_OPCODE { 0x9: decode PREPOST { - 0: decode OPCODE { - 0x0: mul({{ Rn = resTemp = Rm * Rs; }}, none); - 0x1: mla({{ Rn = resTemp = (Rm * Rs) + Rd; }}, none); - 0x2: WarnUnimpl::umall(); - 0x4: umull({{ - resTemp = ((uint64_t)Rm)*((uint64_t)Rs); - Rd = (uint32_t)(resTemp & 0xffffffff); - Rn = (uint32_t)(resTemp >> 32); - }}, llbit); - 0x5: smlal({{ - resTemp = ((int64_t)Rm) * ((int64_t)Rs); - resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); - Rd = (uint32_t)(resTemp & 0xffffffff); - Rn = (uint32_t)(resTemp >> 32); - }}, llbit); - 0x6: smull({{ - resTemp = ((int64_t)(int32_t)Rm)* - ((int64_t)(int32_t)Rs); - Rd = (int32_t)(resTemp & 0xffffffff); - Rn = (int32_t)(resTemp >> 32); - }}, llbit); - 0x7: umlal({{ - resTemp = ((uint64_t)Rm)*((uint64_t)Rs); - resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); - Rd = (uint32_t)(resTemp & 0xffffffff); - Rn = (uint32_t)(resTemp >> 32); - }}, llbit); - } + 0: ArmMultAndMultAcc::armMultAndMultAcc(); 1: decode PUBWL { 0x10: WarnUnimpl::swp(); 0x14: WarnUnimpl::swpb(); @@ -94,86 +67,61 @@ format DataOp { } 0: decode IS_MISC { 0: ArmDataProcReg::armDataProcReg(); - 1: decode MISC_OPCODE { - 0x0: decode OPCODE { - 0x8: PredOp::mrs_cpsr({{ - Rd = (Cpsr | CondCodes) & 0xF8FF03DF; - }}); - 0x9: decode USEIMM { - // The mask field is the same as the RN index. - 0: PredOp::msr_cpsr_reg({{ - uint32_t newCpsr = - cpsrWriteByInstr(Cpsr | CondCodes, - Rm, RN, false); - Cpsr = ~CondCodesMask & newCpsr; - CondCodes = CondCodesMask & newCpsr; - }}); - 1: PredImmOp::msr_cpsr_imm({{ - uint32_t newCpsr = - cpsrWriteByInstr(Cpsr | CondCodes, - rotated_imm, RN, false); - Cpsr = ~CondCodesMask & newCpsr; - CondCodes = CondCodesMask & newCpsr; + 1: decode OPCODE_7 { + 0x0: decode MISC_OPCODE { + 0x0: decode OPCODE { + 0x8: PredOp::mrs_cpsr({{ + Rd = (Cpsr | CondCodes) & 0xF8FF03DF; }}); + 0x9: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredOp::msr_cpsr_reg({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + Rm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + 1: PredImmOp::msr_cpsr_imm({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } + 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); + 0xb: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + 1: PredImmOp::msr_spsr_imm({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, + RN, false); + }}); + } } - 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); - 0xb: decode USEIMM { - // The mask field is the same as the RN index. - 0: PredOp::msr_spsr_reg({{ - Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); - }}); - 1: PredImmOp::msr_spsr_imm({{ - Spsr = spsrWriteByInstr(Spsr, rotated_imm, - RN, false); + 0x1: decode OPCODE { + 0x9: ArmBx::armBx(); + 0xb: PredOp::clz({{ + Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm))); }}); } + 0x2: decode OPCODE { + 0x9: WarnUnimpl::bxj(); + } + 0x3: decode OPCODE { + 0x9: ArmBlxReg::armBlxReg(); + } + 0x5: decode OPCODE { + 0x8: WarnUnimpl::qadd(); + 0x9: WarnUnimpl::qsub(); + 0xa: WarnUnimpl::qdadd(); + 0xb: WarnUnimpl::qdsub(); + } } - 0x1: decode OPCODE { - 0x9: ArmBx::armBx(); - 0xb: PredOp::clz({{ - Rd = ((Rm == 0) ? 32 : (31 - findMsbSet(Rm))); - }}); - } - 0x2: decode OPCODE { - 0x9: WarnUnimpl::bxj(); - } - 0x3: decode OPCODE { - 0x9: ArmBlxReg::armBlxReg(); - } - 0x5: decode OPCODE { - 0x8: WarnUnimpl::qadd(); - 0x9: WarnUnimpl::qsub(); - 0xa: WarnUnimpl::qdadd(); - 0xb: WarnUnimpl::qdsub(); - } - 0x8: decode OPCODE { - 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); - 0x9: WarnUnimpl::smlalbb(); - 0xa: WarnUnimpl::smlawb(); - 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none); - } - 0xa: decode OPCODE { - 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); - 0x9: smulwb({{ - Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); - }}, none); - 0xa: WarnUnimpl::smlaltb(); - 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none); - } - 0xc: decode OPCODE { - 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); - 0x9: WarnUnimpl::smlawt(); - 0xa: WarnUnimpl::smlalbt(); - 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none); - } - 0xe: decode OPCODE { - 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); - 0x9: smulwt({{ - Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); - }}, none); - 0xa: WarnUnimpl::smlaltt(); - 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none); - } + 0x1: ArmHalfWordMultAndMultAcc::armHalfWordMultAndMultAcc(); } } } @@ -207,58 +155,31 @@ format DataOp { 0x2: AddrMode2::addrMode2(True); 0x3: decode OPCODE_4 { 0: AddrMode2::addrMode2(False); - 1: decode MEDIA_OPCODE { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); - 0x8: decode MISC_OPCODE { - 0x1, 0x9: WarnUnimpl::pkhbt(); - 0x7: WarnUnimpl::sxtab16(); - 0xb: WarnUnimpl::sel(); - 0x5, 0xd: WarnUnimpl::pkhtb(); - 0x3: WarnUnimpl::sign_zero_extend_add(); - } - 0xa, 0xb: decode SHIFT { - 0x0, 0x2: WarnUnimpl::ssat(); - 0x1: WarnUnimpl::ssat16(); - } - 0xe, 0xf: decode SHIFT { - 0x0, 0x2: WarnUnimpl::usat(); - 0x1: WarnUnimpl::usat16(); - } - 0x10: decode RN { - 0xf: decode MISC_OPCODE { - 0x1: WarnUnimpl::smuad(); - 0x3: WarnUnimpl::smuadx(); - 0x5: WarnUnimpl::smusd(); - 0x7: WarnUnimpl::smusdx(); + 1: decode OPCODE_24_23 { + 0x0: WarnUnimpl::parallel_add_subtract_instructions(); + 0x1: decode MEDIA_OPCODE { + 0x8: decode MISC_OPCODE { + 0x1, 0x9: WarnUnimpl::pkhbt(); + 0x7: WarnUnimpl::sxtab16(); + 0xb: WarnUnimpl::sel(); + 0x5, 0xd: WarnUnimpl::pkhtb(); + 0x3: WarnUnimpl::sign_zero_extend_add(); } - default: decode MISC_OPCODE { - 0x1: WarnUnimpl::smlad(); - 0x3: WarnUnimpl::smladx(); - 0x5: WarnUnimpl::smlsd(); - 0x7: WarnUnimpl::smlsdx(); + 0xa, 0xb: decode SHIFT { + 0x0, 0x2: WarnUnimpl::ssat(); + 0x1: WarnUnimpl::ssat16(); } - } - 0x14: decode MISC_OPCODE { - 0x1: WarnUnimpl::smlald(); - 0x3: WarnUnimpl::smlaldx(); - 0x5: WarnUnimpl::smlsld(); - 0x7: WarnUnimpl::smlsldx(); - } - 0x15: decode RN { - 0xf: decode MISC_OPCODE { - 0x1: WarnUnimpl::smmul(); - 0x3: WarnUnimpl::smmulr(); - } - default: decode MISC_OPCODE { - 0x1: WarnUnimpl::smmla(); - 0x3: WarnUnimpl::smmlar(); - 0xd: WarnUnimpl::smmls(); - 0xf: WarnUnimpl::smmlsr(); + 0xe, 0xf: decode SHIFT { + 0x0, 0x2: WarnUnimpl::usat(); + 0x1: WarnUnimpl::usat16(); } } - 0x18: decode RN { - 0xf: WarnUnimpl::usada8(); - default: WarnUnimpl::usad8(); + 0x2: ArmSignedMultiplies::armSignedMultiplies(); + 0x3: decode MEDIA_OPCODE { + 0x18: decode RN { + 0xf: WarnUnimpl::usada8(); + default: WarnUnimpl::usad8(); + } } } } diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index 9a09a57d4..781e467cf 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -177,8 +177,8 @@ } } 0x1: decode HTOPCODE_8_7 { - 0x2: WarnUnimpl::Multiply_multiply_accumulate_and_absolute_difference(); - 0x3: WarnUnimpl::Long_multiply_long_multiply_accumulate_and_divide(); + 0x2: Thumb32MulMulAccAndAbsDiff::thumb32MulMulAccAndAbsDiff(); + 0x3: Thumb32LongMulMulAccAndDiv::thumb32LongMulMulAccAndDiv(); default: WarnUnimpl::Data_processing_register(); } default: decode HTOPCODE_9_8 { diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa index 6707e23c2..e866ee04b 100644 --- a/src/arch/arm/isa/formats/data.isa +++ b/src/arch/arm/isa/formats/data.isa @@ -230,8 +230,7 @@ def format Thumb16DataProcessing() {{ case 0xc: return new OrrReg(machInst, rdn, rdn, rm, 0, LSL); case 0xd: - //XXX Implement me! - return new WarnUnimplemented("mul", machInst); + return new NewMul(machInst, rdn, rm, rdn); case 0xe: return new BicReg(machInst, rdn, rdn, rm, 0, LSL); case 0xf: diff --git a/src/arch/arm/isa/formats/formats.isa b/src/arch/arm/isa/formats/formats.isa index 87383c26c..b55b82110 100644 --- a/src/arch/arm/isa/formats/formats.isa +++ b/src/arch/arm/isa/formats/formats.isa @@ -70,3 +70,6 @@ //Include the formats for data processing instructions ##include "data.isa" + +//Include the formats for multiply instructions +##include "mult.isa" diff --git a/src/arch/arm/isa/formats/mult.isa b/src/arch/arm/isa/formats/mult.isa new file mode 100644 index 000000000..a0cdfbc92 --- /dev/null +++ b/src/arch/arm/isa/formats/mult.isa @@ -0,0 +1,440 @@ +// Copyright (c) 2010 ARM Limited +// All rights reserved +// +// The license below extends only to copyright in the software and shall +// not be construed as granting a license to any other intellectual +// property including but not limited to intellectual property relating +// to a hardware implementation of the functionality of the software +// licensed hereunder. You may use the software subject to the license +// terms below provided that you ensure that this notice is replicated +// unmodified and in its entirety in all distributions of the software, +// modified or unmodified, in source code or in binary form. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +def format ArmMultAndMultAcc() {{ + decode_block = ''' + { + // The manual defines this field as 23-20, but bit 20 is usually + // ignored. + const uint32_t op = bits(machInst, 23, 21); + const bool s = bits(machInst, 20); + const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + switch (op) { + case 0x0: + if (s) { + return new NewMulCc(machInst, rd, rm, rn); + } else { + return new NewMul(machInst, rd, rm, rn); + } + case 0x1: + if (s) { + return new NewMlaCc(machInst, rd, rn, rm, ra); + } else { + return new NewMla(machInst, rd, rn, rm, ra); + } + case 0x2: + return new NewUmaal(machInst, ra, rd, rn, rm); + case 0x3: + return new NewMls(machInst, rd, rn, rm, ra); + case 0x4: + if (s) { + return new NewUmullCc(machInst, ra, rd, rn, rm); + } else { + return new NewUmull(machInst, ra, rd, rn, rm); + } + case 0x5: + if (s) { + return new NewUmlalCc(machInst, ra, rd, rn, rm); + } else { + return new NewUmlal(machInst, ra, rd, rn, rm); + } + case 0x6: + if (s) { + return new NewSmullCc(machInst, ra, rd, rn, rm); + } else { + return new NewSmull(machInst, ra, rd, rn, rm); + } + case 0x7: + if (s) { + return new NewSmlalCc(machInst, ra, rd, rn, rm); + } else { + return new NewSmlal(machInst, ra, rd, rn, rm); + } + } + } + ''' +}}; + +def format ArmHalfWordMultAndMultAcc() {{ + decode_block = ''' + { + const uint32_t op1 = bits(machInst, 22, 21); + const bool op = bits(machInst, 5); + const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + switch (op1) { + case 0x0: + switch (bits(machInst, 6, 5)) { + case 0x0: + return new NewSmlabbCc(machInst, rd, rn, rm, ra); + case 0x1: + return new NewSmlatbCc(machInst, rd, rn, rm, ra); + case 0x2: + return new NewSmlabtCc(machInst, rd, rn, rm, ra); + case 0x3: + return new NewSmlattCc(machInst, rd, rn, rm, ra); + } + case 0x1: + if (op) { + if (bits(machInst, 6)) { + return new NewSmulwt(machInst, rd, rn, rm); + } else { + return new NewSmulwb(machInst, rd, rn, rm); + } + } else { + if (bits(machInst, 6)) { + return new NewSmlawtCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmlawbCc(machInst, rd, rn, rm, ra); + } + } + case 0x2: + switch (bits(machInst, 6, 5)) { + case 0x0: + return new NewSmlalbb(machInst, ra, rd, rn, rm); + case 0x1: + return new NewSmlaltb(machInst, ra, rd, rn, rm); + case 0x2: + return new NewSmlalbt(machInst, ra, rd, rn, rm); + case 0x3: + return new NewSmlaltt(machInst, ra, rd, rn, rm); + } + case 0x3: + switch (bits(machInst, 6, 5)) { + case 0x0: + return new NewSmulbb(machInst, rd, rn, rm); + case 0x1: + return new NewSmultb(machInst, rd, rn, rm); + case 0x2: + return new NewSmulbt(machInst, rd, rn, rm); + case 0x3: + return new NewSmultt(machInst, rd, rn, rm); + } + } + } + ''' +}}; + +def format Thumb32MulMulAccAndAbsDiff() {{ + decode_block = ''' + { + const uint32_t op1 = bits(machInst, 22, 20); + const uint32_t op2 = bits(machInst, 5, 4); + const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + if (op1 != 0x1 && bits(op2, 1) != 0) { + return new Unknown(machInst); + } + switch (op1) { + case 0x0: + if (op2 == 0) { + if (ra == 0xf) { + return new NewMul(machInst, rd, rn, rm); + } else { + return new NewMla(machInst, rd, rn, rm, ra); + } + } else { + return new NewMls(machInst, rd, rn, rm, ra); + } + case 0x1: + if (ra == 0xf) { + switch (bits(machInst, 5, 4)) { + case 0x0: + return new NewSmulbb(machInst, rd, rn, rm); + case 0x1: + return new NewSmulbt(machInst, rd, rn, rm); + case 0x2: + return new NewSmultb(machInst, rd, rn, rm); + case 0x3: + return new NewSmultt(machInst, rd, rn, rm); + } + } else { + switch (bits(machInst, 5, 4)) { + case 0x0: + return new NewSmlabbCc(machInst, rd, rn, rm, ra); + case 0x1: + return new NewSmlabtCc(machInst, rd, rn, rm, ra); + case 0x2: + return new NewSmlatbCc(machInst, rd, rn, rm, ra); + case 0x3: + return new NewSmlattCc(machInst, rd, rn, rm, ra); + } + } + case 0x2: + if (ra == 0xf) { + if (bits(machInst, 4)) { + return new NewSmuadxCc(machInst, rd, rn, rm); + } else { + return new NewSmuadCc(machInst, rd, rn, rm); + } + } else { + if (bits(machInst, 4)) { + return new NewSmladxCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmladCc(machInst, rd, rn, rm, ra); + } + } + case 0x3: + if (ra == 0xf) { + if (bits(machInst, 4)) { + return new NewSmulwt(machInst, rd, rn, rm); + } else { + return new NewSmulwb(machInst, rd, rn, rm); + } + } else { + if (bits(machInst, 4)) { + return new NewSmlawtCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmlawbCc(machInst, rd, rn, rm, ra); + } + } + case 0x4: + if (ra == 0xf) { + if (bits(machInst, 4)) { + return new NewSmusdx(machInst, rd, rn, rm); + } else { + return new NewSmusd(machInst, rd, rn, rm); + } + } else { + if (bits(machInst, 4)) { + return new NewSmlsdxCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmlsdCc(machInst, rd, rn, rm, ra); + } + } + case 0x5: + if (ra == 0xf) { + if (bits(machInst, 4)) { + return new NewSmmulr(machInst, rd, rn, rm); + } else { + return new NewSmmul(machInst, rd, rn, rm); + } + } else { + if (bits(machInst, 4)) { + return new NewSmmlar(machInst, rd, rn, rm, ra); + } else { + return new NewSmmla(machInst, rd, rn, rm, ra); + } + } + case 0x6: + if (bits(machInst, 4)) { + return new NewSmmlsr(machInst, rd, rn, rm, ra); + } else { + return new NewSmmls(machInst, rd, rn, rm, ra); + } + case 0x7: + if (op2 != 0x0) { + return new Unknown(machInst); + } else if (ra == 0xf) { + return new WarnUnimplemented("usada8", machInst); + } else { + return new WarnUnimplemented("usad8", machInst); + } + } + } + ''' +}}; + +def format Thumb32LongMulMulAccAndDiv() {{ + decode_block = ''' + { + const uint32_t op1 = bits(machInst, 22, 20); + const uint32_t op2 = bits(machInst, 7, 4); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + switch (op1) { + case 0x0: + if (op2 == 0x0) { + return new NewSmull(machInst, rdlo, rdhi, rn, rm); + } + break; + case 0x1: + if (op2 == 0xf) { + return new WarnUnimplemented("sdiv", machInst); + } + break; + case 0x2: + if (op2 == 0x0) { + return new NewUmull(machInst, rdlo, rdhi, rn, rm); + } + break; + case 0x3: + if (op2 == 0xf) { + return new WarnUnimplemented("udiv", machInst); + } + break; + case 0x4: + if (op2 == 0) { + return new NewSmlal(machInst, rdlo, rdhi, rn, rm); + } else if (bits(op2, 3, 2) == 0x2) { + switch (bits(machInst, 5, 4)) { + case 0x0: + return new NewSmlalbb(machInst, rdlo, rdhi, rn, rm); + case 0x1: + return new NewSmlalbt(machInst, rdlo, rdhi, rn, rm); + case 0x2: + return new NewSmlaltb(machInst, rdlo, rdhi, rn, rm); + case 0x3: + return new NewSmlaltt(machInst, rdlo, rdhi, rn, rm); + } + } else if (bits(op2, 3, 1) == 0x6) { + if (bits(machInst, 4)) { + return new NewSmlaldx(machInst, rdlo, rdhi, rn, rm); + } else { + return new NewSmlald(machInst, rdlo, rdhi, rn, rm); + } + } + break; + case 0x5: + if (bits(op2, 3, 1) == 0x6) { + if (bits(machInst, 4)) { + return new NewSmlsldx(machInst, rdlo, rdhi, rn, rm); + } else { + return new NewSmlsld(machInst, rdlo, rdhi, rn, rm); + } + } + case 0x6: + if (op2 == 0) { + return new NewUmlal(machInst, rdlo, rdhi, rn, rm); + } else if (op2 == 0x6) { + return new NewUmaal(machInst, rdlo, rdhi, rn, rm); + } + break; + } + return new Unknown(machInst); + } + ''' +}}; + +def format ArmSignedMultiplies() {{ + decode_block = ''' + { + const uint32_t op1 = bits(machInst, 22, 20); + // This is 7-5 in the manual, but bit 5 is always ignored. + const uint32_t op2 = bits(machInst, 7, 6); + const bool aIsF = (bits(machInst, 15, 12) == 0xf); + const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); + const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); + const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); + const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); + const bool m = bits(machInst, 5); + switch (op1) { + case 0x0: + if (op2 == 0) { + if (aIsF) { + if (m) { + return new NewSmuadxCc(machInst, rd, rn, rm); + } else { + return new NewSmuadCc(machInst, rd, rn, rm); + } + } else { + if (m) { + return new NewSmladxCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmladCc(machInst, rd, rn, rm, ra); + } + } + } else if (op2 == 1) { + if (aIsF) { + if (m) { + return new NewSmusdx(machInst, rd, rn, rm); + } else { + return new NewSmusd(machInst, rd, rn, rm); + } + } else { + if (m) { + return new NewSmlsdxCc(machInst, rd, rn, rm, ra); + } else { + return new NewSmlsdCc(machInst, rd, rn, rm, ra); + } + } + } + break; + case 0x4: + if (op2 == 0) { + if (m) { + return new NewSmlaldx(machInst, ra, rd, rn, rm); + } else { + return new NewSmlald(machInst, ra, rd, rn, rm); + } + } else if (op2 == 1) { + if (m) { + return new NewSmlsldx(machInst, ra, rd, rn, rm); + } else { + return new NewSmlsld(machInst, ra, rd, rn, rm); + } + } + break; + case 0x5: + if (op2 == 0) { + if (aIsF) { + if (m) { + return new NewSmmulr(machInst, rd, rn, rm); + } else { + return new NewSmmul(machInst, rd, rn, rm); + } + } else { + if (m) { + return new NewSmmlar(machInst, rd, rn, rm, ra); + } else { + return new NewSmmla(machInst, rd, rn, rm, ra); + } + } + } else if (op2 == 0x3) { + if (m) { + return new NewSmmlsr(machInst, rd, rn, rm, ra); + } else { + return new NewSmmls(machInst, rd, rn, rm, ra); + } + } + break; + default: + break; + } + return new Unknown(machInst); + } + ''' +}}; diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 62547d53c..7c961daa4 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -67,6 +67,7 @@ namespace ArmISA Bitfield<24, 21> opcode; Bitfield<24, 20> mediaOpcode; Bitfield<24> opcode24; + Bitfield<24, 23> opcode24_23; Bitfield<23, 20> opcode23_20; Bitfield<23, 21> opcode23_21; Bitfield<20> opcode20; |