Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ARM64 encodings for group IF_SVE_BH_3A,3B,3B_A #98764

Merged
merged 7 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5283,6 +5283,25 @@ void CodeGen::genArm64EmitterUnitTestsSve()
theEmitter->emitIns_R_R_R(INS_sve_lsr, EA_SCALABLE, REG_V29, REG_V10, REG_V22, INS_OPTS_SCALABLE_S,
INS_SCALABLE_OPTS_UNPREDICATED_WIDE); // LSR <Zd>.<T>, <Zn>.<T>, <Zm>.D

// IF_SVE_BH_3A
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V4, REG_V2, REG_V0, 0, INS_OPTS_SCALABLE_D, EA_UNKNOWN,
INS_SCALABLE_OPTS_LSL_N); // ADR <Zd>.<T>, [<Zn>.<T>, <Zm>.<T>{, <mod><amount>}]
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V29, REG_V1, REG_V10, 1, INS_OPTS_SCALABLE_S,
EA_UNKNOWN,
INS_SCALABLE_OPTS_LSL_N); // ADR <Zd>.<T>, [<Zn>.<T>, <Zm>.<T>{, <mod><amount>}]

// IF_SVE_BH_3B
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V9, REG_V7, REG_V9, 0,
INS_OPTS_SCALABLE_D_SXTW); // ADR <Zd>.D, [<Zn>.D, <Zm>.D, SXTW{<amount>}]
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V12, REG_V3, REG_V5, 2,
INS_OPTS_SCALABLE_D_SXTW); // ADR <Zd>.D, [<Zn>.D, <Zm>.D, SXTW{<amount>}]

// IF_SVE_BH_3B_A
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V9, REG_V10, REG_V14, 0,
INS_OPTS_SCALABLE_D_UXTW); // ADR <Zd>.D, [<Zn>.D, <Zm>.D, UXTW{<amount>}]
theEmitter->emitInsSve_R_R_R_I(INS_sve_adr, EA_SCALABLE, REG_V3, REG_V15, REG_V11, 3,
INS_OPTS_SCALABLE_D_UXTW); // ADR <Zd>.D, [<Zn>.D, <Zm>.D, UXTW{<amount>}]

// IF_SVE_BK_3A
theEmitter->emitIns_R_R_R(INS_sve_ftssel, EA_SCALABLE, REG_V17, REG_V16, REG_V15,
INS_OPTS_SCALABLE_D); // FTSSEL <Zd>.<T>, <Zn>.<T>, <Zm>.<T>
Expand Down
161 changes: 129 additions & 32 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,23 @@ void emitter::emitInsSanityCheck(instrDesc* id)
assert(isValidScalarDatasize(elemsize));
break;

case IF_SVE_BH_3A: // .........x.mmmmm ....hhnnnnnddddd -- SVE address generation
assert(id->idInsOpt() == INS_OPTS_SCALABLE_S || id->idInsOpt() == INS_OPTS_SCALABLE_D);
assert(isVectorRegister(id->idReg1())); // ddddd
assert(isVectorRegister(id->idReg2())); // nnnnn
assert(isVectorRegister(id->idReg3())); // mmmmm
assert(isValidUimm2(emitGetInsSC(id))); // hh
break;

case IF_SVE_BH_3B: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
case IF_SVE_BH_3B_A: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
assert(id->idInsOpt() == INS_OPTS_SCALABLE_D_SXTW || id->idInsOpt() == INS_OPTS_SCALABLE_D_UXTW);
assert(isVectorRegister(id->idReg1())); // ddddd
assert(isVectorRegister(id->idReg2())); // nnnnn
assert(isVectorRegister(id->idReg3())); // mmmmm
assert(isValidUimm2(emitGetInsSC(id))); // hh
break;

case IF_SVE_BL_1A: // ............iiii ......pppppddddd -- SVE element count
elemsize = id->idOpSize();
assert(id->idInsOpt() == INS_OPTS_NONE);
Expand Down Expand Up @@ -11722,14 +11739,15 @@ void emitter::emitIns_R_R_R_I_LdStPair(instruction ins,
* Add an instruction referencing three registers and a constant.
*/

void emitter::emitIns_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt /* = INS_OPTS_NONE */,
emitAttr attrReg2 /* = EA_UNKNOWN */)
void emitter::emitIns_R_R_R_I(instruction ins,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change isn't needed as your not touching this function otherwise.

emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt /* = INS_OPTS_NONE */,
emitAttr attrReg2 /* = EA_UNKNOWN */,
insScalableOpts sopt /* = INS_SCALABLE_OPTS_NONE */)
{
emitAttr size = EA_SIZE(attr);
emitAttr elemsize = EA_UNKNOWN;
Expand Down Expand Up @@ -12181,14 +12199,15 @@ void emitter::emitIns_R_R_R_I(instruction ins,
* Add a SVE instruction referencing three registers and a constant.
*/

void emitter::emitInsSve_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt /* = INS_OPTS_NONE */,
emitAttr attrReg2 /* = EA_UNKNOWN */)
void emitter::emitInsSve_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt /* = INS_OPTS_NONE */,
emitAttr attrReg2 /* = EA_UNKNOWN */,
insScalableOpts sopt /* = INS_SCALABLE_OPTS_NONE */)
{
emitAttr size = EA_SIZE(attr);
emitAttr elemsize = EA_UNKNOWN;
Expand All @@ -12197,6 +12216,30 @@ void emitter::emitInsSve_R_R_R_I(instruction ins,
/* Figure out the encoding format of the instruction */
switch (ins)
{
case INS_sve_adr:
assert(isVectorRegister(reg1)); // ddddd
assert(isVectorRegister(reg2)); // nnnnn
assert(isVectorRegister(reg3)); // mmmmm
assert(isValidUimm2(imm));
switch (opt)
{
case INS_OPTS_SCALABLE_S:
case INS_OPTS_SCALABLE_D:
assert(sopt == INS_SCALABLE_OPTS_LSL_N);
fmt = IF_SVE_BH_3A;
break;
case INS_OPTS_SCALABLE_D_SXTW:
fmt = IF_SVE_BH_3B;
break;
case INS_OPTS_SCALABLE_D_UXTW:
fmt = IF_SVE_BH_3B_A;
break;
default:
assert(!"invalid instruction");
break;
}
break;

case INS_sve_cmpeq:
case INS_sve_cmpgt:
case INS_sve_cmpge:
Expand Down Expand Up @@ -22742,6 +22785,26 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id)
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_BH_3A: // .........x.mmmmm ....hhnnnnnddddd -- SVE address generation
code = emitInsCodeSve(ins, fmt);
code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd
code |= insEncodeReg_V_9_to_5(id->idReg2()); // nnnnn
code |= insEncodeReg_V_20_to_16(id->idReg3()); // mmmmm
code |= insEncodeUimm2_11_to_10(emitGetInsSC(id)); // hh
code |= insEncodeImm1_22(id->idInsOpt() == INS_OPTS_SCALABLE_D ? 1 : 0);
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_BH_3B: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
case IF_SVE_BH_3B_A: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
code = emitInsCodeSve(ins, fmt);
code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd
code |= insEncodeReg_V_9_to_5(id->idReg2()); // nnnnn
code |= insEncodeReg_V_20_to_16(id->idReg3()); // mmmmm
code |= insEncodeUimm2_11_to_10(emitGetInsSC(id)); // hh
dst += emitOutput_Instr(dst, code);
break;

// Immediate and patterm to general purpose.
case IF_SVE_BL_1A: // ............iiii ......pppppddddd -- SVE element count
imm = emitGetInsSC(id);
Expand Down Expand Up @@ -24305,11 +24368,17 @@ void emitter::emitDispSveExtendOpts(insOpts opt)
{
switch (opt)
{
case INS_OPTS_LSL:
printf("lsl");
break;

case INS_OPTS_UXTW:
case INS_OPTS_SCALABLE_S_UXTW:
case INS_OPTS_SCALABLE_D_UXTW:
printf("uxtw");
break;

case INS_OPTS_SXTW:
case INS_OPTS_SCALABLE_S_SXTW:
case INS_OPTS_SCALABLE_D_SXTW:
printf("sxtw");
Expand All @@ -24330,23 +24399,14 @@ void emitter::emitDispSveExtendOptsModN(insOpts opt, int n)
{
assert(n >= 0 && n <= 3);

emitDispSveExtendOpts(opt);
switch (n)
if (n == 0 && opt != INS_OPTS_LSL)
{
case 3:
printf(" #3");
break;

case 2:
printf(" #2");
break;

case 1:
printf(" #1");
break;

default:
break;
emitDispSveExtendOpts(opt);
}
else if (n > 0)
{
emitDispSveExtendOpts(opt);
printf(" #%d", n);
}
}

Expand Down Expand Up @@ -26583,6 +26643,36 @@ void emitter::emitDispInsHelp(
emitDispSveReg(id->idReg3(), INS_OPTS_SCALABLE_D, false); // mmmmm
break;

// <Zd>.<T>, [<Zn>.<T>, <Zm>.<T>{, <mod> <amount>}]
case IF_SVE_BH_3A: // .........x.mmmmm ....hhnnnnnddddd -- SVE address generation
emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd
printf("[");
emitDispSveReg(id->idReg2(), id->idInsOpt(), true);
emitDispSveReg(id->idReg3(), id->idInsOpt(), emitGetInsSC(id) > 0);
emitDispSveExtendOptsModN(INS_OPTS_LSL, emitGetInsSC(id));
printf("]");
break;

// <Zd>.D, [<Zn>.D, <Zm>.D, SXTW{ <amount>}]
case IF_SVE_BH_3B: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd
printf("[");
emitDispSveReg(id->idReg2(), id->idInsOpt(), true);
emitDispSveReg(id->idReg3(), id->idInsOpt(), true);
emitDispSveExtendOptsModN(INS_OPTS_SXTW, emitGetInsSC(id));
printf("]");
break;

// <Zd>.D, [<Zn>.D, <Zm>.D, UXTW{ <amount>}]
case IF_SVE_BH_3B_A: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd
printf("[");
emitDispSveReg(id->idReg2(), id->idInsOpt(), true);
emitDispSveReg(id->idReg3(), id->idInsOpt(), true);
emitDispSveExtendOptsModN(INS_OPTS_UXTW, emitGetInsSC(id));
printf("]");
break;

// <Pd>.H, <Pn>.B
case IF_SVE_CK_2A: // ................ .......NNNN.DDDD -- SVE unpack predicate elements
emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), INS_OPTS_SCALABLE_H, true); // DDDD
Expand Down Expand Up @@ -30178,6 +30268,13 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins
result.insLatency = PERFSCORE_LATENCY_8C;
break;

case IF_SVE_BH_3A: // .........x.mmmmm ....hhnnnnnddddd -- SVE address generation
case IF_SVE_BH_3B: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
case IF_SVE_BH_3B_A: // ...........mmmmm ....hhnnnnnddddd -- SVE address generation
result.insThroughput = PERFSCORE_THROUGHPUT_2C;
result.insLatency = PERFSCORE_LATENCY_2C;
break;

case IF_SVE_BL_1A: // ............iiii ......pppppddddd -- SVE element count
result.insThroughput = PERFSCORE_THROUGHPUT_2C;
result.insLatency = PERFSCORE_LATENCY_2C;
Expand Down
36 changes: 19 additions & 17 deletions src/coreclr/jit/emitarm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -1438,23 +1438,25 @@ void emitIns_R_R_R(instruction ins,
insOpts opt = INS_OPTS_NONE,
insScalableOpts sopt = INS_SCALABLE_OPTS_NONE);

void emitIns_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt = INS_OPTS_NONE,
emitAttr attrReg2 = EA_UNKNOWN);

void emitInsSve_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt = INS_OPTS_NONE,
emitAttr attrReg2 = EA_UNKNOWN);
void emitIns_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt = INS_OPTS_NONE,
emitAttr attrReg2 = EA_UNKNOWN,
insScalableOpts sopt = INS_SCALABLE_OPTS_NONE);

void emitInsSve_R_R_R_I(instruction ins,
emitAttr attr,
regNumber reg1,
regNumber reg2,
regNumber reg3,
ssize_t imm,
insOpts opt = INS_OPTS_NONE,
emitAttr attrReg2 = EA_UNKNOWN,
insScalableOpts sopt = INS_SCALABLE_OPTS_NONE);

void emitIns_R_R_R_I_I(instruction ins,
emitAttr attr,
Expand Down
Loading