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 all commits
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
18 changes: 18 additions & 0 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5321,6 +5321,24 @@ 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,
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,
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
131 changes: 113 additions & 18 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,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 @@ -12766,6 +12783,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 @@ -23568,6 +23609,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 @@ -25228,11 +25289,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 @@ -25249,27 +25316,18 @@ void emitter::emitDispSveExtendOpts(insOpts opt)
* Prints the encoding for the Extend Type encoding along with the N value
*/

void emitter::emitDispSveExtendOptsModN(insOpts opt, int n)
void emitter::emitDispSveExtendOptsModN(insOpts opt, ssize_t imm)
{
assert(n >= 0 && n <= 3);
assert(imm >= 0 && imm <= 3);

emitDispSveExtendOpts(opt);
switch (n)
if (imm == 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 (imm > 0)
{
emitDispSveExtendOpts(opt);
printf(" #%d", (int)imm);
}
}

Expand Down Expand Up @@ -27528,6 +27586,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 @@ -31285,6 +31373,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
2 changes: 1 addition & 1 deletion src/coreclr/jit/emitarm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void emitDispBarrier(insBarrier barrier);
void emitDispShiftOpts(insOpts opt);
void emitDispExtendOpts(insOpts opt);
void emitDispSveExtendOpts(insOpts opt);
void emitDispSveExtendOptsModN(insOpts opt, int n);
void emitDispSveExtendOptsModN(insOpts opt, ssize_t imm);
void emitDispSveModAddr(instruction ins, regNumber reg1, regNumber reg2, insOpts opt, insFormat fmt);
void emitDispSveImm(regNumber reg1, ssize_t imm, insOpts opt);
void emitDispSveImmMulVl(regNumber reg1, ssize_t imm);
Expand Down
Loading