@@ -2123,7 +2123,7 @@ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) const
21232123 return sizeof (code_t );
21242124}
21252125
2126- static inline void assertCodeLength (unsigned code, uint8_t size)
2126+ static inline void assertCodeLength (size_t code, uint8_t size)
21272127{
21282128 assert ((code >> size) == 0 );
21292129}
@@ -2298,7 +2298,9 @@ static inline void assertCodeLength(unsigned code, uint8_t size)
22982298
22992299static constexpr unsigned kInstructionOpcodeMask = 0x7f ;
23002300static constexpr unsigned kInstructionFunct3Mask = 0x7000 ;
2301+ static constexpr unsigned kInstructionFunct5Mask = 0xf8000000 ;
23012302static constexpr unsigned kInstructionFunct7Mask = 0xfe000000 ;
2303+ static constexpr unsigned kInstructionFunct2Mask = 0x06000000 ;
23022304
23032305#ifdef DEBUG
23042306
@@ -2338,34 +2340,44 @@ static constexpr unsigned kInstructionFunct7Mask = 0xfe000000;
23382340 assert (isGeneralRegisterOrR0 (rs1));
23392341 assert (isGeneralRegisterOrR0 (rs2));
23402342 break ;
2341- case INS_fadd_s:
2342- case INS_fsub_s:
2343- case INS_fmul_s:
2344- case INS_fdiv_s:
23452343 case INS_fsgnj_s:
23462344 case INS_fsgnjn_s:
23472345 case INS_fsgnjx_s:
23482346 case INS_fmin_s:
23492347 case INS_fmax_s:
2350- case INS_feq_s:
2351- case INS_flt_s:
2352- case INS_fle_s:
2353- case INS_fadd_d:
2354- case INS_fsub_d:
2355- case INS_fmul_d:
2356- case INS_fdiv_d:
23572348 case INS_fsgnj_d:
23582349 case INS_fsgnjn_d:
23592350 case INS_fsgnjx_d:
23602351 case INS_fmin_d:
23612352 case INS_fmax_d:
2353+ assert (isFloatReg (rd));
2354+ assert (isFloatReg (rs1));
2355+ assert (isFloatReg (rs2));
2356+ break ;
2357+ case INS_feq_s:
23622358 case INS_feq_d:
23632359 case INS_flt_d:
2360+ case INS_flt_s:
2361+ case INS_fle_s:
23642362 case INS_fle_d:
2365- assert (isFloatReg (rd));
2363+ assert (isGeneralRegisterOrR0 (rd));
23662364 assert (isFloatReg (rs1));
23672365 assert (isFloatReg (rs2));
23682366 break ;
2367+ case INS_fmv_w_x:
2368+ case INS_fmv_d_x:
2369+ assert (isFloatReg (rd));
2370+ assert (isGeneralRegisterOrR0 (rs1));
2371+ assert (rs2 == 0 );
2372+ break ;
2373+ case INS_fmv_x_d:
2374+ case INS_fmv_x_w:
2375+ case INS_fclass_s:
2376+ case INS_fclass_d:
2377+ assert (isGeneralRegisterOrR0 (rd));
2378+ assert (isFloatReg (rs1));
2379+ assert (rs2 == 0 );
2380+ break ;
23692381 default :
23702382 NO_WAY (" Illegal ins within emitOutput_RTypeInstr!" );
23712383 break ;
@@ -2377,6 +2389,7 @@ static constexpr unsigned kInstructionFunct7Mask = 0xfe000000;
23772389{
23782390 switch (ins)
23792391 {
2392+ case INS_mov:
23802393 case INS_jalr:
23812394 case INS_lb:
23822395 case INS_lh:
@@ -2392,7 +2405,6 @@ static constexpr unsigned kInstructionFunct7Mask = 0xfe000000;
23922405 case INS_lwu:
23932406 case INS_ld:
23942407 case INS_addiw:
2395- case INS_fence_i:
23962408 case INS_csrrw:
23972409 case INS_csrrs:
23982410 case INS_csrrc:
@@ -2427,6 +2439,15 @@ static constexpr unsigned kInstructionFunct7Mask = 0xfe000000;
24272439 assert (rs1 < 32 );
24282440 assert ((opcode & kInstructionFunct7Mask ) == 0 );
24292441 break ;
2442+ case INS_fence:
2443+ {
2444+ assert (rd == REG_ZERO);
2445+ assert (rs1 == REG_ZERO);
2446+ ssize_t format = immediate >> 8 ;
2447+ assert ((format == 0 ) || (format == 0x8 ));
2448+ assert ((opcode & kInstructionFunct7Mask ) == 0 );
2449+ }
2450+ break ;
24302451 default :
24312452 NO_WAY (" Illegal ins within emitOutput_ITypeInstr!" );
24322453 break ;
@@ -2867,7 +2888,7 @@ BYTE* emitter::emitOutputInstr_OptsI8(BYTE* dst, const instrDesc* id, ssize_t im
28672888 if (id->idReg2 ())
28682889 {
28692890 // special for INT64_MAX or UINT32_MAX
2870- dst += emitOutput_ITypeInstr (dst, INS_addi, reg1, REG_R0, 0xfff );
2891+ dst += emitOutput_ITypeInstr (dst, INS_addi, reg1, REG_R0, NBitMask ( 12 ) );
28712892 const ssize_t shiftValue = (immediate == INT64_MAX) ? 1 : 32 ;
28722893 dst += emitOutput_ITypeInstr (dst, INS_srli, reg1, reg1, shiftValue);
28732894 }
@@ -2881,10 +2902,10 @@ BYTE* emitter::emitOutputInstr_OptsI8(BYTE* dst, const instrDesc* id, ssize_t im
28812902
28822903BYTE* emitter::emitOutputInstr_OptsI32 (BYTE* dst, ssize_t immediate, regNumber reg1)
28832904{
2884- ssize_t upperWord = UpperWordOfDoubleWord (immediate);
2905+ const ssize_t upperWord = UpperWordOfDoubleWord (immediate);
28852906 dst += emitOutput_UTypeInstr (dst, INS_lui, reg1, UpperNBitsOfWordSignExtend<20 >(upperWord));
28862907 dst += emitOutput_ITypeInstr (dst, INS_addi, reg1, reg1, LowerNBitsOfWord<12 >(upperWord));
2887- ssize_t lowerWord = LowerWordOfDoubleWord (immediate);
2908+ const ssize_t lowerWord = LowerWordOfDoubleWord (immediate);
28882909 dst += emitOutput_ITypeInstr (dst, INS_slli, reg1, reg1, 11 );
28892910 dst += emitOutput_ITypeInstr (dst, INS_addi, reg1, reg1, LowerNBitsOfWord<11 >(lowerWord >> 21 ));
28902911 dst += emitOutput_ITypeInstr (dst, INS_slli, reg1, reg1, 11 );
@@ -2899,39 +2920,37 @@ BYTE* emitter::emitOutputInstr_OptsRc(BYTE* dst, const instrDesc* id, instructio
28992920 assert (id->idAddr ()->iiaIsJitDataOffset ());
29002921 assert (id->idGCref () == GCT_NONE);
29012922
2902- int dataOffs = id->idAddr ()->iiaGetJitDataOffset ();
2923+ const int dataOffs = id->idAddr ()->iiaGetJitDataOffset ();
29032924 assert (dataOffs >= 0 );
29042925
2905- ssize_t immediate = emitGetInsSC (id);
2926+ const ssize_t immediate = emitGetInsSC (id);
29062927 assert ((immediate >= 0 ) && (immediate < 0x4000 )); // 0x4000 is arbitrary, currently 'imm' is always 0.
29072928
2908- unsigned offset = static_cast <unsigned >(dataOffs + immediate);
2929+ const unsigned offset = static_cast <unsigned >(dataOffs + immediate);
29092930 assert (offset < emitDataSize ());
29102931
2911- *ins = id->idIns ();
2912- regNumber reg1 = id->idReg1 ();
2932+ *ins = id->idIns ();
2933+ const regNumber reg1 = id->idReg1 ();
29132934
29142935 if (id->idIsReloc ())
29152936 {
2916- return emitOutputInstr_OptsRcReloc (dst, ins, reg1);
2937+ return emitOutputInstr_OptsRcReloc (dst, ins, offset, reg1);
29172938 }
29182939 return emitOutputInstr_OptsRcNoReloc (dst, ins, offset, reg1);
29192940}
29202941
2921- BYTE* emitter::emitOutputInstr_OptsRcReloc (BYTE* dst, instruction* ins, regNumber reg1)
2942+ BYTE* emitter::emitOutputInstr_OptsRcReloc (BYTE* dst, instruction* ins, unsigned offset, regNumber reg1)
29222943{
2923- ssize_t immediate = emitConsBlock - dst;
2924- assert (immediate > 0 );
2925- assert ((immediate & 0x03 ) == 0 );
2944+ const ssize_t immediate = (emitConsBlock - dst) + offset;
2945+ assert ((immediate > 0 ) && ((immediate & 0x03 ) == 0 ));
29262946
2927- regNumber rsvdReg = codeGen->rsGetRsvdReg ();
2947+ const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
29282948 dst += emitOutput_UTypeInstr (dst, INS_auipc, rsvdReg, UpperNBitsOfWordSignExtend<20 >(immediate));
29292949
29302950 instruction lastIns = *ins;
29312951
29322952 if (*ins == INS_jal)
29332953 {
2934- assert (isGeneralRegister (reg1));
29352954 *ins = lastIns = INS_addi;
29362955 }
29372956 dst += emitOutput_ITypeInstr (dst, lastIns, reg1, rsvdReg, LowerNBitsOfWord<12 >(immediate));
@@ -2940,12 +2959,12 @@ BYTE* emitter::emitOutputInstr_OptsRcReloc(BYTE* dst, instruction* ins, regNumbe
29402959
29412960BYTE* emitter::emitOutputInstr_OptsRcNoReloc (BYTE* dst, instruction* ins, unsigned offset, regNumber reg1)
29422961{
2943- ssize_t immediate = reinterpret_cast <ssize_t >(emitConsBlock) + offset;
2944- assert ( (immediate >> 40 ) == 0 );
2945- regNumber rsvdReg = codeGen->rsGetRsvdReg ();
2962+ const ssize_t immediate = reinterpret_cast <ssize_t >(emitConsBlock) + offset;
2963+ assertCodeLength ( static_cast < size_t > (immediate), 40 );
2964+ const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
29462965
2947- instruction lastIns = (*ins == INS_jal) ? (*ins = INS_addi) : *ins;
2948- UINT32 high = immediate >> 11 ;
2966+ const instruction lastIns = (*ins == INS_jal) ? (*ins = INS_addi) : *ins;
2967+ const UINT32 high = immediate >> 11 ;
29492968
29502969 dst += emitOutput_UTypeInstr (dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20 >(high));
29512970 dst += emitOutput_ITypeInstr (dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12 >(high));
@@ -2959,9 +2978,8 @@ BYTE* emitter::emitOutputInstr_OptsRl(BYTE* dst, instrDesc* id, instruction* ins
29592978 insGroup* targetInsGroup = static_cast <insGroup*>(emitCodeGetCookie (id->idAddr ()->iiaBBlabel ));
29602979 id->idAddr ()->iiaIGlabel = targetInsGroup;
29612980
2962- regNumber reg1 = id->idReg1 ();
2963- assert (isGeneralRegister (reg1));
2964- ssize_t igOffs = targetInsGroup->igOffs ;
2981+ const regNumber reg1 = id->idReg1 ();
2982+ const ssize_t igOffs = targetInsGroup->igOffs ;
29652983
29662984 if (id->idIsReloc ())
29672985 {
@@ -2974,7 +2992,7 @@ BYTE* emitter::emitOutputInstr_OptsRl(BYTE* dst, instrDesc* id, instruction* ins
29742992
29752993BYTE* emitter::emitOutputInstr_OptsRlReloc (BYTE* dst, ssize_t igOffs, regNumber reg1)
29762994{
2977- ssize_t immediate = (emitCodeBlock - dst) + igOffs;
2995+ const ssize_t immediate = (emitCodeBlock - dst) + igOffs;
29782996 assert ((immediate & 0x03 ) == 0 );
29792997
29802998 dst += emitOutput_UTypeInstr (dst, INS_auipc, reg1, UpperNBitsOfWordSignExtend<20 >(immediate));
@@ -2984,11 +3002,11 @@ BYTE* emitter::emitOutputInstr_OptsRlReloc(BYTE* dst, ssize_t igOffs, regNumber
29843002
29853003BYTE* emitter::emitOutputInstr_OptsRlNoReloc (BYTE* dst, ssize_t igOffs, regNumber reg1)
29863004{
2987- ssize_t immediate = reinterpret_cast <ssize_t >(emitCodeBlock) + igOffs;
2988- assert ( (immediate >> ( 32 + 20 )) == 0 );
3005+ const ssize_t immediate = reinterpret_cast <ssize_t >(emitCodeBlock) + igOffs;
3006+ assertCodeLength ( static_cast < size_t > (immediate), 32 + 20 );
29893007
2990- regNumber rsvdReg = codeGen->rsGetRsvdReg ();
2991- ssize_t upperSignExt = UpperWordOfDoubleWordDoubleSignExtend<32 , 52 >(immediate);
3008+ const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
3009+ const ssize_t upperSignExt = UpperWordOfDoubleWordDoubleSignExtend<32 , 52 >(immediate);
29923010
29933011 dst += emitOutput_UTypeInstr (dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20 >(immediate));
29943012 dst += emitOutput_ITypeInstr (dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12 >(immediate));
@@ -3000,32 +3018,32 @@ BYTE* emitter::emitOutputInstr_OptsRlNoReloc(BYTE* dst, ssize_t igOffs, regNumbe
30003018
30013019BYTE* emitter::emitOutputInstr_OptsJalr (BYTE* dst, instrDescJmp* jmp, const insGroup* ig, instruction* ins)
30023020{
3003- ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, jmp) - 4 ;
3021+ const ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, jmp) - 4 ;
30043022 assert ((immediate & 0x03 ) == 0 );
30053023
30063024 *ins = jmp->idIns ();
3007- assert (jmp->idCodeSize () > 4 ); // The original INS_OPTS_JALR: not used by now!!!
30083025 switch (jmp->idCodeSize ())
30093026 {
30103027 case 8 :
3011- return emitOutputInstr_OptsJalr8 (dst, jmp, *ins, immediate);
3028+ return emitOutputInstr_OptsJalr8 (dst, jmp, immediate);
30123029 case 24 :
3013- assert ((*ins == INS_jal) || (*ins == INS_j));
3030+ assert (jmp-> idInsIs ( INS_jal, INS_j));
30143031 return emitOutputInstr_OptsJalr24 (dst, immediate);
30153032 case 28 :
3016- return emitOutputInstr_OptsJalr28 (dst, jmp, *ins, immediate);
3033+ return emitOutputInstr_OptsJalr28 (dst, jmp, immediate);
30173034 default :
3035+ // case 0 - 4: The original INS_OPTS_JALR: not used by now!!!
30183036 break ;
30193037 }
30203038 unreached ();
30213039 return nullptr ;
30223040}
30233041
3024- BYTE* emitter::emitOutputInstr_OptsJalr8 (BYTE* dst, const instrDescJmp* jmp, instruction ins, ssize_t immediate)
3042+ BYTE* emitter::emitOutputInstr_OptsJalr8 (BYTE* dst, const instrDescJmp* jmp, ssize_t immediate)
30253043{
3026- regNumber reg2 = ((ins != INS_beqz) && (ins != INS_bnez)) ? jmp->idReg2 () : REG_R0 ;
3044+ const regNumber reg2 = jmp-> idInsIs ( INS_beqz, INS_bnez) ? REG_R0 : jmp->idReg2 ();
30273045
3028- dst += emitOutput_BTypeInstr_InvertComparation (dst, ins , jmp->idReg1 (), reg2, 0x8 );
3046+ dst += emitOutput_BTypeInstr_InvertComparation (dst, jmp-> idIns () , jmp->idReg1 (), reg2, 0x8 );
30293047 dst += emitOutput_JTypeInstr (dst, INS_jal, REG_ZERO, TrimSignedToImm21 (immediate));
30303048 return dst;
30313049}
@@ -3034,14 +3052,14 @@ BYTE* emitter::emitOutputInstr_OptsJalr24(BYTE* dst, ssize_t immediate)
30343052{
30353053 // Make target address with offset, then jump (JALR) with the target address
30363054 immediate -= 2 * 4 ;
3037- ssize_t high = UpperWordOfDoubleWordSingleSignExtend<0 >(immediate);
3055+ const ssize_t high = UpperWordOfDoubleWordSingleSignExtend<0 >(immediate);
30383056
30393057 dst += emitOutput_UTypeInstr (dst, INS_lui, REG_RA, UpperNBitsOfWordSignExtend<20 >(high));
30403058 dst += emitOutput_ITypeInstr (dst, INS_addi, REG_RA, REG_RA, LowerNBitsOfWord<12 >(high));
30413059 dst += emitOutput_ITypeInstr (dst, INS_slli, REG_RA, REG_RA, 32 );
30423060
3043- regNumber rsvdReg = codeGen->rsGetRsvdReg ();
3044- ssize_t low = LowerWordOfDoubleWord (immediate);
3061+ const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
3062+ const ssize_t low = LowerWordOfDoubleWord (immediate);
30453063
30463064 dst += emitOutput_UTypeInstr (dst, INS_auipc, rsvdReg, UpperNBitsOfWordSignExtend<20 >(low));
30473065 dst += emitOutput_RTypeInstr (dst, INS_add, rsvdReg, REG_RA, rsvdReg);
@@ -3050,17 +3068,18 @@ BYTE* emitter::emitOutputInstr_OptsJalr24(BYTE* dst, ssize_t immediate)
30503068 return dst;
30513069}
30523070
3053- BYTE* emitter::emitOutputInstr_OptsJalr28 (BYTE* dst, const instrDescJmp* jmp, instruction ins, ssize_t immediate)
3071+ BYTE* emitter::emitOutputInstr_OptsJalr28 (BYTE* dst, const instrDescJmp* jmp, ssize_t immediate)
30543072{
3055- regNumber reg2 = ((ins != INS_beqz) && (ins != INS_bnez)) ? jmp->idReg2 () : REG_R0;
3056- dst += emitOutput_BTypeInstr_InvertComparation (dst, ins, jmp->idReg1 (), reg2, 0x1c );
3073+ regNumber reg2 = jmp->idInsIs (INS_beqz, INS_bnez) ? REG_R0 : jmp->idReg2 ();
3074+
3075+ dst += emitOutput_BTypeInstr_InvertComparation (dst, jmp->idIns (), jmp->idReg1 (), reg2, 0x1c );
30573076
30583077 return emitOutputInstr_OptsJalr24 (dst, immediate);
30593078}
30603079
30613080BYTE* emitter::emitOutputInstr_OptsJCond (BYTE* dst, instrDesc* id, const insGroup* ig, instruction* ins)
30623081{
3063- ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, static_cast <instrDescJmp*>(id));
3082+ const ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, static_cast <instrDescJmp*>(id));
30643083
30653084 *ins = id->idIns ();
30663085
@@ -3070,7 +3089,7 @@ BYTE* emitter::emitOutputInstr_OptsJCond(BYTE* dst, instrDesc* id, const insGrou
30703089
30713090BYTE* emitter::emitOutputInstr_OptsJ (BYTE* dst, instrDesc* id, const insGroup* ig, instruction* ins)
30723091{
3073- ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, static_cast <instrDescJmp*>(id));
3092+ const ssize_t immediate = emitOutputInstrJumpDistance (dst, ig, static_cast <instrDescJmp*>(id));
30743093 assert ((immediate & 0x03 ) == 0 );
30753094
30763095 *ins = id->idIns ();
@@ -3133,11 +3152,13 @@ BYTE* emitter::emitOutputInstr_OptsC(BYTE* dst, instrDesc* id, const insGroup* i
31333152size_t emitter::emitOutputInstr (insGroup* ig, instrDesc* id, BYTE** dp)
31343153{
31353154 BYTE* dst = *dp;
3155+ BYTE* dst2 = dst + 4 ;
31363156 const BYTE* const odst = *dp;
31373157 instruction ins;
31383158 size_t sz = 0 ;
31393159
31403160 assert (REG_NA == static_cast <int >(REG_NA));
3161+ assert (writeableOffset == 0 );
31413162
31423163 insOpts insOp = id->idInsOpt ();
31433164
@@ -3174,8 +3195,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
31743195 sz = sizeof (instrDescJmp);
31753196 break ;
31763197 case INS_OPTS_C:
3177- dst = emitOutputInstr_OptsC (dst, id, ig, &sz);
3178- ins = INS_nop;
3198+ dst = emitOutputInstr_OptsC (dst, id, ig, &sz);
3199+ dst2 = dst;
3200+ ins = INS_nop;
31793201 break ;
31803202 default : // case INS_OPTS_NONE:
31813203 dst += emitOutput_Instr (dst, id->idAddr ()->iiaGetInstrEncode ());
@@ -3193,11 +3215,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
31933215 // We assume that "idReg1" is the primary destination register for all instructions
31943216 if (id->idGCref () != GCT_NONE)
31953217 {
3196- emitGCregLiveUpd (id->idGCref (), id->idReg1 (), dst );
3218+ emitGCregLiveUpd (id->idGCref (), id->idReg1 (), dst2 );
31973219 }
31983220 else
31993221 {
3200- emitGCregDeadUpd (id->idReg1 (), dst );
3222+ emitGCregDeadUpd (id->idReg1 (), dst2 );
32013223 }
32023224 }
32033225
@@ -3211,7 +3233,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
32113233 int adr = emitComp->lvaFrameAddress (varNum, &FPbased);
32123234 if (id->idGCref () != GCT_NONE)
32133235 {
3214- emitGCvarLiveUpd (adr + ofs, varNum, id->idGCref (), dst DEBUG_ARG (varNum));
3236+ emitGCvarLiveUpd (adr + ofs, varNum, id->idGCref (), dst2 DEBUG_ARG (varNum));
32153237 }
32163238 else
32173239 {
@@ -3228,7 +3250,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
32283250 vt = tmpDsc->tdTempType ();
32293251 }
32303252 if (vt == TYP_REF || vt == TYP_BYREF)
3231- emitGCvarDeadUpd (adr + ofs, dst DEBUG_ARG (varNum));
3253+ emitGCvarDeadUpd (adr + ofs, dst2 DEBUG_ARG (varNum));
32323254 }
32333255 // if (emitInsWritesToLclVarStackLocPair(id))
32343256 // {
0 commit comments