@@ -2040,6 +2040,28 @@ void emitter::emitInsSanityCheck(instrDesc* id)
2040
2040
assert(isScalableVectorSize(elemsize));
2041
2041
break;
2042
2042
2043
+ case IF_SVE_ID_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE load predicate register
2044
+ case IF_SVE_JG_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE store predicate register
2045
+ elemsize = id->idOpSize();
2046
+ assert(insOptsNone(id->idInsOpt()));
2047
+ assert(isScalableVectorSize(elemsize));
2048
+ assert(isPredicateRegister(id->idReg1())); // TTTT
2049
+ assert(isGeneralRegister(id->idReg2())); // nnnnn
2050
+ assert(isValidSimm9(emitGetInsSC(id))); // iii
2051
+ // iiiiii
2052
+ break;
2053
+
2054
+ case IF_SVE_IE_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE load vector register
2055
+ case IF_SVE_JH_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE store vector register
2056
+ elemsize = id->idOpSize();
2057
+ assert(insOptsNone(id->idInsOpt()));
2058
+ assert(isScalableVectorSize(elemsize));
2059
+ assert(isVectorRegister(id->idReg1())); // ttttt
2060
+ assert(isGeneralRegister(id->idReg2())); // nnnnn
2061
+ assert(isValidSimm9(emitGetInsSC(id))); // iii
2062
+ // iiiiii
2063
+ break;
2064
+
2043
2065
default:
2044
2066
printf("unexpected format %s\n", emitIfName(id->idInsFmt()));
2045
2067
assert(!"Unexpected format");
@@ -8768,6 +8790,46 @@ void emitter::emitIns_R_R_I(instruction ins,
8768
8790
}
8769
8791
break;
8770
8792
8793
+ case INS_sve_ldr:
8794
+ assert(insOptsNone(opt));
8795
+ assert(isScalableVectorSize(size));
8796
+ assert(isGeneralRegister(reg2)); // nnnnn
8797
+ assert(isValidSimm9(imm)); // iii
8798
+ // iiiiii
8799
+
8800
+ if (sopt == INS_SCALABLE_OPTS_UNPREDICATED)
8801
+ {
8802
+ assert(isVectorRegister(reg1));
8803
+ fmt = IF_SVE_IE_2A;
8804
+ }
8805
+ else
8806
+ {
8807
+ assert(insScalableOptsNone(sopt));
8808
+ assert(isPredicateRegister(reg1));
8809
+ fmt = IF_SVE_ID_2A;
8810
+ }
8811
+ break;
8812
+
8813
+ case INS_sve_str:
8814
+ assert(insOptsNone(opt));
8815
+ assert(isScalableVectorSize(size));
8816
+ assert(isGeneralRegister(reg2)); // nnnnn
8817
+ assert(isValidSimm9(imm)); // iii
8818
+ // iiiiii
8819
+
8820
+ if (sopt == INS_SCALABLE_OPTS_UNPREDICATED)
8821
+ {
8822
+ assert(isVectorRegister(reg1));
8823
+ fmt = IF_SVE_JH_2A;
8824
+ }
8825
+ else
8826
+ {
8827
+ assert(insScalableOptsNone(sopt));
8828
+ assert(isPredicateRegister(reg1));
8829
+ fmt = IF_SVE_JG_2A;
8830
+ }
8831
+ break;
8832
+
8771
8833
default:
8772
8834
unreached();
8773
8835
break;
@@ -16432,6 +16494,10 @@ void emitter::emitIns_Call(EmitCallType callType,
16432
16494
assert((regpos == 2) || (regpos == 3));
16433
16495
return ((regpos == 2) ? PREDICATE_NONE : PREDICATE_SIZED);
16434
16496
16497
+ case IF_SVE_ID_2A:
16498
+ case IF_SVE_JG_2A:
16499
+ return PREDICATE_NONE;
16500
+
16435
16501
default:
16436
16502
break;
16437
16503
}
@@ -17578,6 +17644,26 @@ void emitter::emitIns_Call(EmitCallType callType,
17578
17644
return (code_t)imm << 16;
17579
17645
}
17580
17646
17647
+ /*****************************************************************************
17648
+ *
17649
+ * Returns the encoding for the immediate value as 9-bits at bit locations '21-16' for high and '12-10' for low.
17650
+ */
17651
+
17652
+ /*static*/ emitter::code_t emitter::insEncodeSimm9h9l_21_to_16_and_12_to_10(ssize_t imm)
17653
+ {
17654
+ assert(isValidSimm9(imm));
17655
+
17656
+ if (imm < 0)
17657
+ {
17658
+ imm = (imm & 0x1FF);
17659
+ }
17660
+
17661
+ code_t h = (code_t)(imm & 0x1F8) << 13; // encode high 6-bits at locations '21-16'
17662
+ code_t l = (code_t)((imm & ~0x1F8) & 0x7) << 10; // encode low 3-bits at locations '12-10'
17663
+
17664
+ return (h | l);
17665
+ }
17666
+
17581
17667
/*****************************************************************************
17582
17668
*
17583
17669
* Returns the encoding for the immediate value that is a multiple of 2 as 4-bits at bit locations '19-16'.
@@ -20820,6 +20906,28 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id)
20820
20906
dst += emitOutput_Instr(dst, code);
20821
20907
break;
20822
20908
20909
+ case IF_SVE_ID_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE load predicate register
20910
+ case IF_SVE_JG_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE store predicate register
20911
+ imm = emitGetInsSC(id);
20912
+ code = emitInsCodeSve(ins, fmt);
20913
+ code |= insEncodeReg_P_3_to_0(id->idReg1()); // TTTT
20914
+ code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn
20915
+ code |= insEncodeSimm9h9l_21_to_16_and_12_to_10(imm); // iii
20916
+ // iiiiii
20917
+ dst += emitOutput_Instr(dst, code);
20918
+ break;
20919
+
20920
+ case IF_SVE_IE_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE load vector register
20921
+ case IF_SVE_JH_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE store vector register
20922
+ imm = emitGetInsSC(id);
20923
+ code = emitInsCodeSve(ins, fmt);
20924
+ code |= insEncodeReg_V_4_to_0(id->idReg1()); // ttttt
20925
+ code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn
20926
+ code |= insEncodeSimm9h9l_21_to_16_and_12_to_10(imm); // iii
20927
+ // iiiiii
20928
+ dst += emitOutput_Instr(dst, code);
20929
+ break;
20930
+
20823
20931
default:
20824
20932
assert(!"Unexpected format");
20825
20933
break;
@@ -21205,6 +21313,22 @@ void emitter::emitDispSveModAddr(instruction ins, regNumber reg1, regNumber reg2
21205
21313
printf("]");
21206
21314
}
21207
21315
21316
+ /*****************************************************************************
21317
+ *
21318
+ * Prints the encoding for format [<Xn|SP>{, #<imm>, MUL VL}]
21319
+ */
21320
+ void emitter::emitDispSveImmMulVl(regNumber reg1, ssize_t imm)
21321
+ {
21322
+ printf("[");
21323
+ emitDispReg(reg1, EA_8BYTE, imm != 0);
21324
+ if (imm != 0)
21325
+ {
21326
+ emitDispImm(imm, true);
21327
+ printf("mul vl");
21328
+ }
21329
+ printf("]");
21330
+ }
21331
+
21208
21332
/*****************************************************************************
21209
21333
*
21210
21334
* Prints the encoding for the Extend Type encoding in loads/stores
@@ -24016,29 +24140,33 @@ void emitter::emitDispInsHelp(
24016
24140
imm = emitGetInsSC(id);
24017
24141
emitDispSveConsecutiveRegList(id->idReg1(), insGetSveReg1ListSize(ins), id->idInsOpt(), true); // ttttt
24018
24142
emitDispPredicateReg(id->idReg2(), insGetPredicateType(fmt), id->idInsOpt(), true); // ggg
24019
- printf("[");
24020
- emitDispReg(id->idReg3(), EA_8BYTE, imm != 0); // nnnnn
24021
- if (imm != 0)
24022
- {
24023
- emitDispImm(emitGetInsSC(id), true); // iiii
24024
- printf("mul vl");
24025
- }
24026
- printf("]");
24143
+ emitDispSveImmMulVl(id->idReg3(), imm);
24027
24144
break;
24028
24145
24029
24146
// {<Zt>.<T>}, <Pg>, [<Xn|SP>{, #<imm>, MUL VL}]
24030
24147
case IF_SVE_JN_3B: // ..........x.iiii ...gggnnnnnttttt -- SVE contiguous store (scalar plus immediate)
24031
24148
imm = emitGetInsSC(id);
24032
24149
emitDispSveConsecutiveRegList(id->idReg1(), insGetSveReg1ListSize(ins), id->idInsOpt(), true); // ttttt
24033
24150
emitDispPredicateReg(id->idReg2(), insGetPredicateType(fmt), id->idInsOpt(), true); // ggg
24034
- printf("[");
24035
- emitDispReg(id->idReg3(), EA_8BYTE, imm != 0); // nnnnn
24036
- if (imm != 0)
24037
- {
24038
- emitDispImm(emitGetInsSC(id), true); // iiii
24039
- printf("mul vl");
24040
- }
24041
- printf("]");
24151
+ emitDispSveImmMulVl(id->idReg3(), imm);
24152
+ break;
24153
+
24154
+ // <Pt>, [<Xn|SP>{, #<imm>, MUL VL}]
24155
+ case IF_SVE_ID_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE load predicate register
24156
+ // <Pt>, [<Xn|SP>{, #<imm>, MUL VL}]
24157
+ case IF_SVE_JG_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE store predicate register
24158
+ imm = emitGetInsSC(id);
24159
+ emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), id->idInsOpt(), true); // TTTT
24160
+ emitDispSveImmMulVl(id->idReg2(), imm);
24161
+ break;
24162
+
24163
+ // <Zt>, [<Xn|SP>{, #<imm>, MUL VL}]
24164
+ case IF_SVE_IE_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE load vector register
24165
+ // <Zt>, [<Xn|SP>{, #<imm>, MUL VL}]
24166
+ case IF_SVE_JH_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE store vector register
24167
+ imm = emitGetInsSC(id);
24168
+ emitDispReg(id->idReg1(), EA_SCALABLE, true); // ttttt
24169
+ emitDispSveImmMulVl(id->idReg2(), imm);
24042
24170
break;
24043
24171
24044
24172
default:
@@ -27458,6 +27586,18 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins
27458
27586
result.insLatency = PERFSCORE_LATENCY_2C;
27459
27587
break;
27460
27588
27589
+ case IF_SVE_ID_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE load predicate register
27590
+ case IF_SVE_IE_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE load vector register
27591
+ result.insThroughput = PERFSCORE_THROUGHPUT_3C;
27592
+ result.insLatency = PERFSCORE_LATENCY_6C;
27593
+ break;
27594
+
27595
+ case IF_SVE_JG_2A: // ..........iiiiii ...iiinnnnn.TTTT -- SVE store predicate register
27596
+ case IF_SVE_JH_2A: // ..........iiiiii ...iiinnnnnttttt -- SVE store vector register
27597
+ result.insThroughput = PERFSCORE_THROUGHPUT_2C;
27598
+ result.insLatency = PERFSCORE_LATENCY_2C;
27599
+ break;
27600
+
27461
27601
default:
27462
27602
// all other instructions
27463
27603
perfScoreUnhandledInstruction(id, &result);
0 commit comments