ARM: Implement the VFP version of vmul.

This commit is contained in:
Gabe Black
2010-06-02 12:58:14 -05:00
parent 19e05d7e8d
commit 65f5204325
3 changed files with 56 additions and 1 deletions

View File

@@ -50,6 +50,11 @@ namespace ArmISA
class ArmStaticInst : public StaticInst
{
protected:
union IntDoubleUnion {
uint64_t bits;
double fp;
};
int32_t shift_rm_imm(uint32_t base, uint32_t shamt,
uint32_t type, uint32_t cfval) const;
int32_t shift_rm_rs(uint32_t base, uint32_t shamt,

View File

@@ -486,7 +486,25 @@ let {{
return new WarnUnimplemented("vmla, vmls", machInst);
case 0x2:
if ((opc3 & 0x1) == 0) {
return new WarnUnimplemented("vmul", machInst);
uint32_t vd;
uint32_t vm;
uint32_t vn;
if (bits(machInst, 8) == 0) {
vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1);
vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1);
vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1);
return new VmulS(machInst, (IntRegIndex)vd,
(IntRegIndex)vn, (IntRegIndex)vm);
} else {
vd = (bits(machInst, 22) << 5) |
(bits(machInst, 15, 12) << 1);
vm = (bits(machInst, 5) << 5) |
(bits(machInst, 3, 0) << 1);
vn = (bits(machInst, 7) << 5) |
(bits(machInst, 19, 16) << 1);
return new VmulD(machInst, (IntRegIndex)vd,
(IntRegIndex)vn, (IntRegIndex)vm);
}
}
case 0x1:
return new WarnUnimplemented("vnmla, vnmls, vnmul", machInst);

View File

@@ -226,4 +226,36 @@ let {{
header_output += RegRegRegOpDeclare.subst(vmov2Core2RegIop);
decoder_output += RegRegRegOpConstructor.subst(vmov2Core2RegIop);
exec_output += PredOpExecute.subst(vmov2Core2RegIop);
vmulSCode = '''
FpDest = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
FpDest = NAN;
}
'''
vmulSIop = InstObjParams("vmuls", "VmulS", "RegRegRegOp",
{ "code": vmulSCode,
"predicate_test": predicateTest }, [])
header_output += RegRegRegOpDeclare.subst(vmulSIop);
decoder_output += RegRegRegOpConstructor.subst(vmulSIop);
exec_output += PredOpExecute.subst(vmulSIop);
vmulDCode = '''
IntDoubleUnion cOp1, cOp2, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.fp = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) {
cDest.fp = NAN;
}
FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32;
'''
vmulDIop = InstObjParams("vmuld", "VmulD", "RegRegRegOp",
{ "code": vmulDCode,
"predicate_test": predicateTest }, [])
header_output += RegRegRegOpDeclare.subst(vmulDIop);
decoder_output += RegRegRegOpConstructor.subst(vmulDIop);
exec_output += PredOpExecute.subst(vmulDIop);
}};