summaryrefslogtreecommitdiff
path: root/arch/arm64/il.cpp
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-06-04 17:01:20 -0700
committerMark Rowe <mark@vector35.com>2026-06-05 13:01:46 -0700
commit0c42e5b2491d890ae7bda0570ab57470c4a48940 (patch)
tree40134d5e81ce53d454c5b8bd07700d0d3d36360c /arch/arm64/il.cpp
parentfde1241ce928d38c2031c827ae0ddee5c6f5af0f (diff)
[aarch64] Emit abs, min, and max instructions during lifting
Diffstat (limited to 'arch/arm64/il.cpp')
-rw-r--r--arch/arm64/il.cpp29
1 files changed, 16 insertions, 13 deletions
diff --git a/arch/arm64/il.cpp b/arch/arm64/il.cpp
index 2cac5f04..c0ff2c71 100644
--- a/arch/arm64/il.cpp
+++ b/arch/arm64/il.cpp
@@ -1329,12 +1329,19 @@ bool GetLowLevelILForInstruction(
switch (instr.operation)
{
case ARM64_ABS:
- {
- ExprId src = ILREG_O(operand2);
- GenIfElse(il, il.CompareSignedLessThan(REGSZ_O(operand2), src, il.Const(REGSZ_O(operand2), 0)),
- ILSETREG_O(operand1, il.Neg(REGSZ_O(operand2), src)), ILSETREG_O(operand1, src));
+ switch (instr.encoding)
+ {
+ case ENC_ABS_32_DP_1SRC:
+ case ENC_ABS_64_DP_1SRC:
+ // FEAT_CSSC scalar absolute value on a general-purpose register
+ il.AddInstruction(ILSETREG_O(operand1, il.AbsoluteValue(REGSZ_O(operand2), ILREG_O(operand2))));
+ break;
+ default:
+ // The NEON and SVE forms are per-element absolute values, which have no native scalar
+ // representation
+ il.AddInstruction(il.Unimplemented());
+ }
break;
- }
case ARM64_ADD:
switch (instr.encoding)
{
@@ -4004,8 +4011,7 @@ bool GetLowLevelILForInstruction(
return true;
}
- GenIfElse(il, il.CompareSignedGreaterThan(REGSZ_O(operand2), op2, op3), ILSETREG_O(operand1, op2),
- ILSETREG_O(operand1, op3));
+ il.AddInstruction(ILSETREG_O(operand1, il.MaxSigned(REGSZ_O(operand2), op2, op3)));
break;
}
case ARM64_SMIN:
@@ -4028,8 +4034,7 @@ bool GetLowLevelILForInstruction(
return true;
}
- GenIfElse(il, il.CompareSignedLessThan(REGSZ_O(operand2), op2, op3), ILSETREG_O(operand1, op2),
- ILSETREG_O(operand1, op3));
+ il.AddInstruction(ILSETREG_O(operand1, il.MinSigned(REGSZ_O(operand2), op2, op3)));
break;
}
case ARM64_UDIV:
@@ -4064,8 +4069,7 @@ bool GetLowLevelILForInstruction(
return true;
}
- GenIfElse(il, il.CompareUnsignedGreaterThan(REGSZ_O(operand2), op2, op3), ILSETREG_O(operand1, op2),
- ILSETREG_O(operand1, op3));
+ il.AddInstruction(ILSETREG_O(operand1, il.MaxUnsigned(REGSZ_O(operand2), op2, op3)));
break;
}
case ARM64_UMIN:
@@ -4088,8 +4092,7 @@ bool GetLowLevelILForInstruction(
return true;
}
- GenIfElse(il, il.CompareUnsignedLessThan(REGSZ_O(operand2), op2, op3), ILSETREG_O(operand1, op2),
- ILSETREG_O(operand1, op3));
+ il.AddInstruction(ILSETREG_O(operand1, il.MinUnsigned(REGSZ_O(operand2), op2, op3)));
break;
}
case ARM64_UBFIZ: