ARM: Implement the saturation instructions.
This commit is contained in:
parent
c96f03a250
commit
61b8e33225
2 changed files with 109 additions and 4 deletions
|
@ -67,9 +67,9 @@ class ArmStaticInst : public StaticInst
|
||||||
int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
|
int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
|
||||||
if (bits(midRes, width) != bits(midRes, width - 1)) {
|
if (bits(midRes, width) != bits(midRes, width - 1)) {
|
||||||
if (midRes > 0)
|
if (midRes > 0)
|
||||||
res = (1LL << (width - 1)) - 1;
|
res = (LL(1) << (width - 1)) - 1;
|
||||||
else
|
else
|
||||||
res = -(1LL << (width - 1));
|
res = -(LL(1) << (width - 1));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
res = midRes;
|
res = midRes;
|
||||||
|
@ -77,13 +77,29 @@ class ArmStaticInst : public StaticInst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
satInt(int32_t &res, int64_t op, int width)
|
||||||
|
{
|
||||||
|
width--;
|
||||||
|
if (op >= (LL(1) << width)) {
|
||||||
|
res = (LL(1) << width) - 1;
|
||||||
|
return true;
|
||||||
|
} else if (op < -(LL(1) << width)) {
|
||||||
|
res = -(LL(1) << width);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
res = op;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<int width>
|
template<int width>
|
||||||
static bool
|
static bool
|
||||||
uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false)
|
uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false)
|
||||||
{
|
{
|
||||||
int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
|
int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
|
||||||
if (midRes >= (1 << width)) {
|
if (midRes >= (LL(1) << width)) {
|
||||||
res = (1 << width) - 1;
|
res = (LL(1) << width) - 1;
|
||||||
return true;
|
return true;
|
||||||
} else if (midRes < 0) {
|
} else if (midRes < 0) {
|
||||||
res = 0;
|
res = 0;
|
||||||
|
@ -94,6 +110,21 @@ class ArmStaticInst : public StaticInst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
uSatInt(int32_t &res, int64_t op, int width)
|
||||||
|
{
|
||||||
|
if (op >= (LL(1) << width)) {
|
||||||
|
res = (LL(1) << width) - 1;
|
||||||
|
return true;
|
||||||
|
} else if (op < 0) {
|
||||||
|
res = 0;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
res = op;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ArmStaticInst(const char *mnem, ExtMachInst _machInst,
|
ArmStaticInst(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass)
|
OpClass __opClass)
|
||||||
|
|
|
@ -153,4 +153,78 @@ let {{
|
||||||
header_output += RevOpDeclare.subst(revshIop)
|
header_output += RevOpDeclare.subst(revshIop)
|
||||||
decoder_output += RevOpConstructor.subst(revshIop)
|
decoder_output += RevOpConstructor.subst(revshIop)
|
||||||
exec_output += PredOpExecute.subst(revshIop)
|
exec_output += PredOpExecute.subst(revshIop)
|
||||||
|
|
||||||
|
ssatCode = '''
|
||||||
|
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
||||||
|
int32_t res;
|
||||||
|
if (satInt(res, operand, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
else
|
||||||
|
CondCodes = CondCodes;
|
||||||
|
Dest = res;
|
||||||
|
'''
|
||||||
|
ssatIop = InstObjParams("ssat", "Ssat", "SatShiftOp",
|
||||||
|
{ "code": ssatCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += SatShiftOpDeclare.subst(ssatIop)
|
||||||
|
decoder_output += SatShiftOpConstructor.subst(ssatIop)
|
||||||
|
exec_output += PredOpExecute.subst(ssatIop)
|
||||||
|
|
||||||
|
usatCode = '''
|
||||||
|
int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
|
||||||
|
int32_t res;
|
||||||
|
if (uSatInt(res, operand, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
else
|
||||||
|
CondCodes = CondCodes;
|
||||||
|
Dest = res;
|
||||||
|
'''
|
||||||
|
usatIop = InstObjParams("usat", "Usat", "SatShiftOp",
|
||||||
|
{ "code": usatCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += SatShiftOpDeclare.subst(usatIop)
|
||||||
|
decoder_output += SatShiftOpConstructor.subst(usatIop)
|
||||||
|
exec_output += PredOpExecute.subst(usatIop)
|
||||||
|
|
||||||
|
ssat16Code = '''
|
||||||
|
int32_t res;
|
||||||
|
uint32_t resTemp = 0;
|
||||||
|
CondCodes = CondCodes;
|
||||||
|
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
||||||
|
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
||||||
|
if (satInt(res, argLow, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
replaceBits(resTemp, 15, 0, res);
|
||||||
|
if (satInt(res, argHigh, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
replaceBits(resTemp, 31, 16, res);
|
||||||
|
Dest = resTemp;
|
||||||
|
'''
|
||||||
|
ssat16Iop = InstObjParams("ssat16", "Ssat16", "SatOp",
|
||||||
|
{ "code": ssat16Code,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += SatOpDeclare.subst(ssat16Iop)
|
||||||
|
decoder_output += SatOpConstructor.subst(ssat16Iop)
|
||||||
|
exec_output += PredOpExecute.subst(ssat16Iop)
|
||||||
|
|
||||||
|
usat16Code = '''
|
||||||
|
int32_t res;
|
||||||
|
uint32_t resTemp = 0;
|
||||||
|
CondCodes = CondCodes;
|
||||||
|
int32_t argLow = sext<16>(bits(Op1, 15, 0));
|
||||||
|
int32_t argHigh = sext<16>(bits(Op1, 31, 16));
|
||||||
|
if (uSatInt(res, argLow, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
replaceBits(resTemp, 15, 0, res);
|
||||||
|
if (uSatInt(res, argHigh, satImm))
|
||||||
|
CondCodes = CondCodes | (1 << 27);
|
||||||
|
replaceBits(resTemp, 31, 16, res);
|
||||||
|
Dest = resTemp;
|
||||||
|
'''
|
||||||
|
usat16Iop = InstObjParams("usat16", "Usat16", "SatOp",
|
||||||
|
{ "code": usat16Code,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += SatOpDeclare.subst(usat16Iop)
|
||||||
|
decoder_output += SatOpConstructor.subst(usat16Iop)
|
||||||
|
exec_output += PredOpExecute.subst(usat16Iop)
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue