diff --git a/compiler/src/dmd/backend/cgcod.d b/compiler/src/dmd/backend/cgcod.d index 1d0db13769..f6bdaed4ed 100644 --- a/compiler/src/dmd/backend/cgcod.d +++ b/compiler/src/dmd/backend/cgcod.d @@ -2146,9 +2146,9 @@ regm_t getscratch() * before. * Look first to see if it is already in a register. * Params: - * cdb = sink for generated code - * e = the elem - * pretregs = input is mask of registers, output is result register + * cdb = sink for generated code + * e = the elem + * pretregs = input is mask of registers, output is result register */ @trusted diff --git a/compiler/src/dmd/backend/cod3.d b/compiler/src/dmd/backend/cod3.d index 62b5cb392e..612dd0e835 100644 --- a/compiler/src/dmd/backend/cod3.d +++ b/compiler/src/dmd/backend/cod3.d @@ -6491,7 +6491,7 @@ uint calccodsize(code *c) size = 9; // 64 bit immediate value for MOV to/from RAX goto Lret; } - goto Ldefault; + goto default; case 0xF6: /* TEST mem8,immed8 */ ins = inssize[op]; @@ -6511,8 +6511,16 @@ uint calccodsize(code *c) size += (i32 ^ ((iflags & CFopsize) !=0)) ? 4 : 2; break; + case 0xFA: + case 0xFB: + if (c.Iop == ENDBR32 || c.Iop == ENDBR64) + { + size = 4; + break; + } + goto default; + default: - Ldefault: ins = inssize[op]; size = ins & 7; if (i32) @@ -6992,7 +7000,7 @@ uint codout(int seg, code *c, Barray!ubyte* disasmBuf) else if ((op & 0xFF00) == 0x0F00) ins = inssize2[op & 0xFF]; - if (op & 0xFF000000) + if (op & 0xFF_00_00_00) { ubyte op1 = op >> 24; if (op1 == 0xF2 || op1 == 0xF3 || op1 == 0x66) diff --git a/compiler/src/dmd/backend/code_x86.d b/compiler/src/dmd/backend/code_x86.d index 0107d28ffa..96aa4f3206 100644 --- a/compiler/src/dmd/backend/code_x86.d +++ b/compiler/src/dmd/backend/code_x86.d @@ -464,6 +464,8 @@ enum ESCAPE = SEGDS, // marker that special information is here // (Iop2 is the type of special information) + ENDBR32 = 0xF30F1EFB, + ENDBR64 = 0xF30F1EFA, } diff --git a/compiler/src/dmd/backend/ptrntab.d b/compiler/src/dmd/backend/ptrntab.d index 160ee8763d..34ec577736 100644 --- a/compiler/src/dmd/backend/ptrntab.d +++ b/compiler/src/dmd/backend/ptrntab.d @@ -51,6 +51,8 @@ alias aptb0AAA = OPTABLE0!( 0x37 ,_i64_bit | _modax); alias aptb0AAD = OPTABLE0!( 0xd50a,_i64_bit | _modax); alias aptb0AAM = OPTABLE0!( 0xd40a,_i64_bit | _modax); alias aptb0AAS = OPTABLE0!( 0x3f, _i64_bit | _modax); +alias aptb0ENDBR32 = OPTABLE0!( ENDBR32, _I386); +alias aptb0ENDBR64 = OPTABLE0!( ENDBR64, _I386); alias aptb0CBW = OPTABLE0!( 0x98,_16_bit | _modax); alias aptb0CWDE = OPTABLE0!( 0x98,_32_bit | _I386 | _modax); alias aptb0CDQE = OPTABLE0!( 0x98,_64_bit | _modax); @@ -4933,6 +4935,8 @@ immutable OP[] optab = [ { "dt", ITdata | OPdt, { null } }, { "dw", ITdata | OPdw, { null } }, { "emms", 0, { &aptb0EMMS[0] } }, + { "endbr32", 0, { &aptb0ENDBR32[0] } }, + { "endbr64", 0, { &aptb0ENDBR64[0] } }, { "enter", 2, { &aptb2ENTER[0] } }, { "extractps", 3, { &aptb3EXTRACTPS[0] } }, { "f2xm1", ITfloat | 0, { &aptb0F2XM1[0] } }, diff --git a/compiler/src/dmd/iasmdmd.d b/compiler/src/dmd/iasmdmd.d index 1ddd1ba886..a0724c7579 100644 --- a/compiler/src/dmd/iasmdmd.d +++ b/compiler/src/dmd/iasmdmd.d @@ -1765,6 +1765,14 @@ code *asm_emit(Loc loc, case 0x0F0000: // an AMD instruction const puc = (cast(ubyte *) &opcode); + if (opcode == ENDBR32 || opcode == ENDBR64) + { + emit(puc[3]); + emit(puc[2]); + emit(puc[1]); + emit(puc[0]); + goto L3; + } emit(puc[2]); emit(puc[1]); emit(puc[0]); diff --git a/compiler/test/runnable/iasm64.d b/compiler/test/runnable/iasm64.d index 1883c87387..4fd7879744 100644 --- a/compiler/test/runnable/iasm64.d +++ b/compiler/test/runnable/iasm64.d @@ -3718,6 +3718,8 @@ void test50() 0x9B, // wait 0x91, // xchg EAX,ECX 0xD7, // xlat + 0xF3, 0x0F, 0x1E, 0xFB, // endbr32 + 0xF3, 0x0F, 0x1E, 0xFA, // endbr64 0x48, 0x8D, 0x1D, 0x02, 0x00, 0x00, 0x00, // lea RBX,L1; 0x89, 0xC0, // mov EAX,EAX ]; @@ -3844,6 +3846,8 @@ L10: nop; nop; // put instructions above this or L10 changes wait ; xchg EAX,ECX ; xlat ; + endbr32 ; + endbr64 ; lea RBX,L1 ; mov EAX,EAX ; @@ -3853,6 +3857,7 @@ L1: ; } for (i = 0; i < data.length; i++) { + //printf("[%d] %02x %02x\n", i, p[i], data[i]); assert(p[i] == data[i]); } }