diff options
Diffstat (limited to 'src/arch/arm/isa/formats/fp.isa')
-rw-r--r-- | src/arch/arm/isa/formats/fp.isa | 167 |
1 files changed, 97 insertions, 70 deletions
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index e730833db..da439acb8 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -2034,6 +2034,7 @@ let {{ (bits(machInst, 15, 12) << 1)); } } + IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt) { if (!isInt and size == 3) { @@ -2044,31 +2045,64 @@ let {{ (bits(machInst, 3, 0) << 1)); } } - StaticInstPtr - decodeShortFpTransfer(ExtMachInst machInst) + + IntRegIndex decodeFpVn(ExtMachInst machInst, uint32_t size) { - const uint32_t l = bits(machInst, 20); - const uint32_t c = bits(machInst, 8); - const uint32_t a = bits(machInst, 23, 21); - const uint32_t q = bits(machInst, 6, 5); - const uint32_t o1 = bits(machInst, 18); - if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || - (machInst.thumb == 0 && machInst.condCode == 0xf)) { - // Determine if this is backported aarch64 FP instruction - const bool b31_b24 = bits(machInst, 31, 24) == 0xFE; - const bool b23 = bits(machInst, 23); - const bool b21_b19 = bits(machInst, 21, 19) == 0x7; - const bool b11_b9 = bits(machInst, 11, 9) == 0x5; - const uint32_t size = bits(machInst, 9, 8); - const bool op3 = bits(machInst, 6); - const bool b4 = bits(machInst, 4) == 0x0; - const uint32_t rm = bits(machInst, 17, 16); - IntRegIndex vd = decodeFpVd(machInst, size, false); - IntRegIndex vm = decodeFpVm(machInst, size, false); - IntRegIndex vdInt = decodeFpVd(machInst, size, true); - if (b31_b24 && b23 && b21_b19 && b11_b9 && op3 && b4) { + if (size == 3) { + return (IntRegIndex)((bits(machInst, 7) << 5) | + (bits(machInst, 19, 16) << 1)); + } else { + return (IntRegIndex)(bits(machInst, 7) | + (bits(machInst, 19, 16) << 1)); + } + } + + StaticInstPtr + decodeFloatingPointDataProcessing(ExtMachInst machInst) { + const uint32_t op0 = bits(machInst, 23, 20); + const uint32_t op1 = bits(machInst, 19, 16); + const uint32_t op2 = bits(machInst, 9, 8); + const uint32_t op3 = bits(machInst, 6); + const uint32_t rm = bits(machInst, 17, 16); + const uint32_t size = bits(machInst, 9, 8); + IntRegIndex vd = decodeFpVd(machInst, size, false); + IntRegIndex vm = decodeFpVm(machInst, size, false); + IntRegIndex vdInt = decodeFpVd(machInst, size, true); + IntRegIndex vn = decodeFpVn(machInst, size); + if (bits(machInst, 31, 24) == 0xFE && !bits(machInst, 4)) { + if (bits(op0, 3) == 0 && op2 != 0 && !op3){ + ConditionCode cond; + switch(bits(machInst, 21, 20)) { + case 0x0: cond = COND_EQ; break; + case 0x1: cond = COND_VS; break; + case 0x2: cond = COND_GE; break; + case 0x3: cond = COND_GT; break; + } + if (size == 3) { + return new VselD(machInst, vd, vn, vm, cond); + } else { + return new VselS(machInst, vd, vn, vm, cond); + } + } else if (bits(op0, 3) == 1 && bits(op0, 1, 0) == 0 && op2 != 0) { + const bool op = bits(machInst, 6); + if (op) { + if (size == 1) { + return new FailUnimplemented("vminnm.f16", machInst); + } + return decodeNeonSizeSingleDouble<VminnmS, VminnmD>( + size, machInst, vd, vn, vm); + } else { + if (size == 1) { + return new FailUnimplemented("vmaxnm.f16", machInst); + } + return decodeNeonSizeSingleDouble<VmaxnmS, VmaxnmD>( + size, machInst, vd, vn, vm); + } + } else if (bits(op0, 3) && bits(op0, 1, 0) == 3 && + bits(op1, 3) && op2 != 0 && op3) + { + const uint32_t o1 = bits(machInst, 18); if (o1 == 0) { - // VINT* Integer Rounding Instruction if (size == 3) { switch(rm) { case 0x0: @@ -2105,119 +2139,112 @@ let {{ } else { const bool op = bits(machInst, 7); switch(rm) { - case 0x0: + case 0x0: switch(size) { - case 0x0: + case 0x0: return new Unknown(machInst); - case 0x1: + case 0x1: return new FailUnimplemented( "vcvta.u32.f16", machInst); - case 0x2: + case 0x2: if (op) { return new VcvtaFpSIntS(machInst, vdInt, vm); } else { return new VcvtaFpUIntS(machInst, vdInt, vm); } - case 0x3: + case 0x3: if (op) { return new VcvtaFpSIntD(machInst, vdInt, vm); } else { return new VcvtaFpUIntD(machInst, vdInt, vm); } - default: return new Unknown(machInst); + default: return new Unknown(machInst); } - case 0x1: + case 0x1: switch(size) { - case 0x0: + case 0x0: return new Unknown(machInst); - case 0x1: + case 0x1: return new FailUnimplemented( "vcvtn.u32.f16", machInst); - case 0x2: + case 0x2: if (op) { return new VcvtnFpSIntS(machInst, vdInt, vm); } else { return new VcvtnFpUIntS(machInst, vdInt, vm); } - case 0x3: + case 0x3: if (op) { return new VcvtnFpSIntD(machInst, vdInt, vm); } else { return new VcvtnFpUIntD(machInst, vdInt, vm); } - default: return new Unknown(machInst); + default: return new Unknown(machInst); } - case 0x2: + case 0x2: switch(size) { - case 0x0: + case 0x0: return new Unknown(machInst); - case 0x1: + case 0x1: return new FailUnimplemented( "vcvtp.u32.f16", machInst); - case 0x2: + case 0x2: if (op) { return new VcvtpFpSIntS(machInst, vdInt, vm); } else { return new VcvtpFpUIntS(machInst, vdInt, vm); } - case 0x3: + case 0x3: if (op) { return new VcvtpFpSIntD(machInst, vdInt, vm); } else { return new VcvtpFpUIntD(machInst, vdInt, vm); } - default: return new Unknown(machInst); + default: return new Unknown(machInst); } - case 0x3: + case 0x3: switch(size) { - case 0x0: + case 0x0: return new Unknown(machInst); - case 0x1: + case 0x1: return new FailUnimplemented( "vcvtm.u32.f16", machInst); - case 0x2: + case 0x2: if (op) { return new VcvtmFpSIntS(machInst, vdInt, vm); } else { return new VcvtmFpUIntS(machInst, vdInt, vm); } - case 0x3: + case 0x3: if (op) { return new VcvtmFpSIntD(machInst, vdInt, vm); } else { return new VcvtmFpUIntD(machInst, vdInt, vm); } - default: return new Unknown(machInst); + default: return new Unknown(machInst); } - default: return new Unknown(machInst); + default: return new Unknown(machInst); } } - } else if (b31_b24 && !b23 && b11_b9 && !op3 && b4){ - // VSEL* floating point conditional select - - ConditionCode cond; - switch(bits(machInst, 21, 20)) { - case 0x0: cond = COND_EQ; break; - case 0x1: cond = COND_VS; break; - case 0x2: cond = COND_GE; break; - case 0x3: cond = COND_GT; break; - } - - if (size == 3) { - const IntRegIndex vn = - (IntRegIndex)((bits(machInst, 7) << 5) | - (bits(machInst, 19, 16) << 1)); - return new VselD(machInst, vd, vn, vm, cond); - } else { - const IntRegIndex vn = - (IntRegIndex)((bits(machInst, 19, 16) << 1) | - bits(machInst, 7)); - return new VselS(machInst, vd, vn, vm, cond); - } } else { return new Unknown(machInst); } + } else { + return new Unknown(machInst); + } + } + + StaticInstPtr + decodeShortFpTransfer(ExtMachInst machInst) + { + if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || + (machInst.thumb == 0 && machInst.condCode == 0xf)) { + return decodeFloatingPointDataProcessing(machInst); } + const uint32_t l = bits(machInst, 20); + const uint32_t c = bits(machInst, 8); + const uint32_t a = bits(machInst, 23, 21); + const uint32_t q = bits(machInst, 6, 5); if (l == 0 && c == 0) { if (a == 0) { const uint32_t vn = (bits(machInst, 19, 16) << 1) | |