Skip to content

Commit

Permalink
Add ARM64 encodings for group IF_SVE_BH_3A,3B,3B_A (#98764)
Browse files Browse the repository at this point in the history
* Add ARM64 encodings for group IF_SVE_BH_3A,3B,3B_A

* Remove unnecessary argument

* Fix conversion warning in MSVC

* Fix merge issue
  • Loading branch information
snickolls-arm authored Feb 29, 2024
1 parent 028eda8 commit fd48b6f
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 19 deletions.
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 @@ -12953,6 +12970,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 @@ -23770,6 +23811,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 @@ -25464,11 +25525,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 @@ -25485,27 +25552,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 @@ -27793,6 +27851,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 @@ -31650,6 +31738,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

0 comments on commit fd48b6f

Please sign in to comment.