Skip to content

Commit 4329840

Browse files
committed
[AArch64] Lift MTE instructions to intrinsics
1 parent 1ec0d4f commit 4329840

File tree

3 files changed

+205
-0
lines changed

3 files changed

+205
-0
lines changed

arch/arm64/arch_arm64.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,38 @@ class Arm64Architecture : public Architecture
10431043
return "__tlbi";
10441044
case ARM64_INTRIN_AT:
10451045
return "__at";
1046+
case ARM64_INTRIN_ADDG:
1047+
return "__addg";
1048+
case ARM64_INTRIN_CMPP:
1049+
return "__cmpp";
1050+
case ARM64_INTRIN_GMI:
1051+
return "__gmi";
1052+
case ARM64_INTRIN_IRG:
1053+
return "__irg";
1054+
case ARM64_INTRIN_LDG:
1055+
return "__ldg";
1056+
case ARM64_INTRIN_LDGM:
1057+
return "__ldgm";
1058+
case ARM64_INTRIN_ST2G:
1059+
return "__st2g";
1060+
case ARM64_INTRIN_STG:
1061+
return "__stg";
1062+
case ARM64_INTRIN_STGM:
1063+
return "__stgm";
1064+
case ARM64_INTRIN_STGP:
1065+
return "__stgp";
1066+
case ARM64_INTRIN_STZ2G:
1067+
return "__stz2g";
1068+
case ARM64_INTRIN_STZG:
1069+
return "__stzg";
1070+
case ARM64_INTRIN_STZGM:
1071+
return "__stzgm";
1072+
case ARM64_INTRIN_SUBG:
1073+
return "__subg";
1074+
case ARM64_INTRIN_SUBP:
1075+
return "__subp";
1076+
case ARM64_INTRIN_SUBPS:
1077+
return "__subps";
10461078
default:
10471079
break;
10481080
}

arch/arm64/il.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,10 @@ bool GetLowLevelILForInstruction(
13301330
ILSETREG_O(operand1, il.Add(REGSZ_O(operand1), ILREG_O(operand2),
13311331
ReadILOperand(il, operand3, REGSZ_O(operand1)), SETFLAGS)));
13321332
break;
1333+
case ARM64_ADDG:
1334+
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_ADDG,
1335+
{ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand3)), il.Const(1, IMM_O(operand4))}));
1336+
break;
13331337
case ARM64_ADC:
13341338
case ARM64_ADCS:
13351339
il.AddInstruction(ILSETREG_O(operand1,
@@ -1669,6 +1673,12 @@ bool GetLowLevelILForInstruction(
16691673
il.AddInstruction(il.Sub(REGSZ_O(operand1), ILREG_O(operand1),
16701674
ReadILOperand(il, operand2, REGSZ_O(operand1)), SETFLAGS));
16711675
break;
1676+
case ARM64_CMPP:
1677+
il.AddInstruction(il.Intrinsic(
1678+
{RegisterOrFlag::Flag(IL_FLAG_N), RegisterOrFlag::Flag(IL_FLAG_Z), RegisterOrFlag::Flag(IL_FLAG_C),
1679+
RegisterOrFlag::Flag(IL_FLAG_V)},
1680+
ARM64_INTRIN_CMPP, {ILREG_O(operand1), ILREG_O(operand2)}));
1681+
break;
16721682
case ARM64_CCMP:
16731683
{
16741684
LowLevelILLabel trueCode, falseCode, done;
@@ -2207,6 +2217,17 @@ bool GetLowLevelILForInstruction(
22072217
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_ERET, {}));
22082218
il.AddInstruction(il.Trap(0));
22092219
return false;
2220+
case ARM64_GMI:
2221+
il.AddInstruction(il.Intrinsic(
2222+
{RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_GMI, {ILREG_O(operand2), ILREG_O(operand3)}));
2223+
break;
2224+
case ARM64_IRG:
2225+
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_IRG,
2226+
{
2227+
ILREG_O(operand2),
2228+
operand3.operandClass == NONE ? il.Const(REGSZ_O(operand2), 0) : ILREG_O(operand3),
2229+
}));
2230+
break;
22102231
case ARM64_ISB:
22112232
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_ISB, {}));
22122233
break;
@@ -2251,6 +2272,14 @@ bool GetLowLevelILForInstruction(
22512272
if (SetPacAttr)
22522273
ApplyAttributeToLastInstruction(il, SrcInstructionUsesPointerAuth);
22532274
break;
2275+
case ARM64_LDG:
2276+
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_LDG,
2277+
{GetILOperandEffectiveAddress(il, operand2, 8, operand2.operandClass, 0)}));
2278+
break;
2279+
case ARM64_LDGM:
2280+
il.AddInstruction(
2281+
il.Intrinsic({RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_LDGM, {ILREG_O(operand2)}));
2282+
break;
22542283
case ARM64_LDRB:
22552284
case ARM64_LDURB:
22562285
LoadStoreOperandSize(il, true, false, 1, instr.operands[0], instr.operands[1]);
@@ -3406,6 +3435,120 @@ bool GetLowLevelILForInstruction(
34063435
case ARM64_STNP:
34073436
LoadStoreOperandPair(il, false, instr.operands[0], instr.operands[1], instr.operands[2]);
34083437
break;
3438+
case ARM64_ST2G:
3439+
switch (operand2.operandClass)
3440+
{
3441+
case MEM_POST_IDX:
3442+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_ST2G, {ILREG_O(operand1), ILREG_O(operand2)}));
3443+
if (IMM_O(operand2) != 0)
3444+
il.AddInstruction(ILSETREG_O(operand2,
3445+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3446+
break;
3447+
case MEM_PRE_IDX:
3448+
if (IMM_O(operand2) != 0)
3449+
il.AddInstruction(ILSETREG_O(operand2,
3450+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3451+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_ST2G, {ILREG_O(operand1), ILREG_O(operand2)}));
3452+
break;
3453+
default:
3454+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_ST2G,
3455+
{ILREG_O(operand1), GetILOperandEffectiveAddress(il, operand2, 8, operand2.operandClass, 0)}));
3456+
break;
3457+
}
3458+
break;
3459+
case ARM64_STG:
3460+
switch (operand2.operandClass)
3461+
{
3462+
case MEM_POST_IDX:
3463+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STG, {ILREG_O(operand1), ILREG_O(operand2)}));
3464+
if (IMM_O(operand2) != 0)
3465+
il.AddInstruction(ILSETREG_O(operand2,
3466+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3467+
break;
3468+
case MEM_PRE_IDX:
3469+
if (IMM_O(operand2) != 0)
3470+
il.AddInstruction(ILSETREG_O(operand2,
3471+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3472+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STG, {ILREG_O(operand1), ILREG_O(operand2)}));
3473+
break;
3474+
default:
3475+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STG,
3476+
{ILREG_O(operand1), GetILOperandEffectiveAddress(il, operand2, 8, operand2.operandClass, 0)}));
3477+
break;
3478+
}
3479+
break;
3480+
case ARM64_STGM:
3481+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STGM, {ILREG_O(operand1), ILREG_O(operand2)}));
3482+
break;
3483+
case ARM64_STGP:
3484+
switch (operand3.operandClass)
3485+
{
3486+
case MEM_POST_IDX:
3487+
il.AddInstruction(
3488+
il.Intrinsic({}, ARM64_INTRIN_STGP, {ILREG_O(operand1), ILREG_O(operand2), ILREG_O(operand3)}));
3489+
if (IMM_O(operand3) != 0)
3490+
il.AddInstruction(ILSETREG_O(operand3,
3491+
il.Add(REGSZ_O(operand3), ILREG_O(operand3), il.Const(REGSZ_O(operand3), IMM_O(operand3)))));
3492+
break;
3493+
case MEM_PRE_IDX:
3494+
if (IMM_O(operand3) != 0)
3495+
il.AddInstruction(ILSETREG_O(operand3,
3496+
il.Add(REGSZ_O(operand3), ILREG_O(operand3), il.Const(REGSZ_O(operand3), IMM_O(operand3)))));
3497+
il.AddInstruction(
3498+
il.Intrinsic({}, ARM64_INTRIN_STGP, {ILREG_O(operand1), ILREG_O(operand2), ILREG_O(operand3)}));
3499+
break;
3500+
default:
3501+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STGP,
3502+
{ILREG_O(operand1), ILREG_O(operand2),
3503+
GetILOperandEffectiveAddress(il, operand3, 8, operand3.operandClass, 0)}));
3504+
break;
3505+
}
3506+
break;
3507+
case ARM64_STZ2G:
3508+
switch (operand2.operandClass)
3509+
{
3510+
case MEM_POST_IDX:
3511+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZ2G, {ILREG_O(operand1), ILREG_O(operand2)}));
3512+
if (IMM_O(operand2) != 0)
3513+
il.AddInstruction(ILSETREG_O(operand2,
3514+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3515+
break;
3516+
case MEM_PRE_IDX:
3517+
if (IMM_O(operand2) != 0)
3518+
il.AddInstruction(ILSETREG_O(operand2,
3519+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3520+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZ2G, {ILREG_O(operand1), ILREG_O(operand2)}));
3521+
break;
3522+
default:
3523+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZ2G,
3524+
{ILREG_O(operand1), GetILOperandEffectiveAddress(il, operand2, 8, operand2.operandClass, 0)}));
3525+
break;
3526+
}
3527+
break;
3528+
case ARM64_STZG:
3529+
switch (operand2.operandClass)
3530+
{
3531+
case MEM_POST_IDX:
3532+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZG, {ILREG_O(operand1), ILREG_O(operand2)}));
3533+
if (IMM_O(operand2) != 0)
3534+
il.AddInstruction(ILSETREG_O(operand2,
3535+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3536+
break;
3537+
case MEM_PRE_IDX:
3538+
if (IMM_O(operand2) != 0)
3539+
il.AddInstruction(ILSETREG_O(operand2,
3540+
il.Add(REGSZ_O(operand2), ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand2)))));
3541+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZG, {ILREG_O(operand1), ILREG_O(operand2)}));
3542+
break;
3543+
default:
3544+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZG,
3545+
{ILREG_O(operand1), GetILOperandEffectiveAddress(il, operand2, 8, operand2.operandClass, 0)}));
3546+
break;
3547+
}
3548+
break;
3549+
case ARM64_STZGM:
3550+
il.AddInstruction(il.Intrinsic({}, ARM64_INTRIN_STZGM, {ILREG_O(operand1), ILREG_O(operand2)}));
3551+
break;
34093552
case ARM64_STR:
34103553
switch (instr.encoding)
34113554
{
@@ -3450,6 +3593,20 @@ bool GetLowLevelILForInstruction(
34503593
operand1, il.Sub(REGSZ_O(operand1), ILREG_O(operand2),
34513594
ReadILOperand(il, instr.operands[2], REGSZ_O(operand1)), SETFLAGS)));
34523595
break;
3596+
case ARM64_SUBG:
3597+
il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_SUBG,
3598+
{ILREG_O(operand2), il.Const(REGSZ_O(operand2), IMM_O(operand3)), il.Const(1, IMM_O(operand4))}));
3599+
break;
3600+
case ARM64_SUBP:
3601+
il.AddInstruction(il.Intrinsic(
3602+
{RegisterOrFlag::Register(REG_O(operand1))}, ARM64_INTRIN_SUBP, {ILREG_O(operand2), ILREG_O(operand3)}));
3603+
break;
3604+
case ARM64_SUBPS:
3605+
il.AddInstruction(il.Intrinsic(
3606+
{RegisterOrFlag::Register(REG_O(operand1)), RegisterOrFlag::Flag(IL_FLAG_N),
3607+
RegisterOrFlag::Flag(IL_FLAG_Z), RegisterOrFlag::Flag(IL_FLAG_C), RegisterOrFlag::Flag(IL_FLAG_V)},
3608+
ARM64_INTRIN_SUBPS, {ILREG_O(operand2), ILREG_O(operand3)}));
3609+
break;
34533610
case ARM64_SVC:
34543611
case ARM64_HVC:
34553612
case ARM64_SMC:

arch/arm64/il.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ enum Arm64Intrinsic : uint32_t
9797
ARM64_INTRIN_TLBI,
9898
ARM64_INTRIN_TLBI_REG,
9999
ARM64_INTRIN_AT,
100+
ARM64_INTRIN_ADDG,
101+
ARM64_INTRIN_CMPP,
102+
ARM64_INTRIN_GMI,
103+
ARM64_INTRIN_IRG,
104+
ARM64_INTRIN_LDG,
105+
ARM64_INTRIN_LDGM,
106+
ARM64_INTRIN_ST2G,
107+
ARM64_INTRIN_STG,
108+
ARM64_INTRIN_STGM,
109+
ARM64_INTRIN_STGP,
110+
ARM64_INTRIN_STZ2G,
111+
ARM64_INTRIN_STZG,
112+
ARM64_INTRIN_STZGM,
113+
ARM64_INTRIN_SUBG,
114+
ARM64_INTRIN_SUBP,
115+
ARM64_INTRIN_SUBPS,
100116
ARM64_INTRIN_NORMAL_END, /* needed so intrinsics can be extended by other lists, like neon
101117
intrinsics */
102118
ARM64_INTRIN_INVALID = 0xFFFFFFFF,

0 commit comments

Comments
 (0)