From: Cyrill G. <gor...@op...> - 2012-02-14 22:04:04
|
Hi, while disasm is not yet done, here what I thought about assembler part. It's not yet complete but just to share. At moment the idea is to try to guess if we need to emit additional lock prefix for xacquire/release instructions. (the patch for insns.dat +; +; transactional synchronization extensions +XABORT imm8 [i: c6 f8 ib] FUTURE,HLE +XBEGIN imm16 [i: c7 f8 iw] FUTURE,HLE +XBEGIN imm32 [i: c7 f8 id] FUTURE,HLE +XEND void [ 0f 01 d5] FUTURE,HLE +XTEST void [ 0f 01 d6] FUTURE,HLE,RTM + is in my tree already, simply desided to not push it upstream until everything is done). Commens, ideas? Cyrill --- diff --git a/assemble.c b/assemble.c index f1583fd..0734481 100644 --- a/assemble.c +++ b/assemble.c @@ -340,6 +340,36 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits, return (isize >= -128 && isize <= 127); /* is it byte size? */ } +static bool hle_should_emit_lock(const struct itemplate *t, int prefix) +{ + switch ((int)t->opcode) { + case I_ADD: + case I_ADC: + case I_AND: + case I_BTC: + case I_BTR: + case I_BTS: + case I_CMPXCHG: + case I_CMPXCHG8B: + case I_DEC: + case I_INC: + case I_NEG: + case I_NOT: + case I_OR: + case I_SBB: + case I_SUB: + case I_XOR: + case I_XADD: + return true; + case I_MOV: /* FIXME: Not all MOV requires lock on xrelease */ + return true; + case I_XCHG: + return false; + } + + return false; +} + int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, insn * instruction, struct ofmt *output, efunc error, ListGen * listgen) @@ -497,7 +527,8 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, else while (itimes--) { for (j = 0; j < MAXPREFIX; j++) { - uint8_t c = 0; + uint16_t c = 0; + int bytes = 1; switch (instruction->prefixes[j]) { case P_WAIT: c = 0x9B; @@ -514,6 +545,20 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, case P_REP: c = 0xF3; break; + case P_XACQUIRE: + if (hle_should_emit_lock(&temp, P_XACQUIRE)) { + c = (0xF0 << 8) | 0xF2; + bytes = 2; + } else + c = 0xF2; + break; + case P_XRELEASE: + if (hle_should_emit_lock(&temp, P_XRELEASE)) { + c = (0xF0 << 8) | 0xF3; + bytes = 2; + } else + c = 0xF3; + break; case R_CS: if (bits == 64) { error(ERR_WARNING | ERR_PASS2, @@ -594,9 +639,8 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, default: error(ERR_PANIC, "invalid instruction prefix"); } - if (c != 0) { - out(offset, segment, &c, OUT_RAWDATA, 1, - NO_SEG, NO_SEG); + if (c) { + out(offset, segment, &c, OUT_RAWDATA, bytes, NO_SEG, NO_SEG); offset++; } } diff --git a/nasm.h b/nasm.h index 1569667..23d7e4b 100644 --- a/nasm.h +++ b/nasm.h @@ -486,6 +486,8 @@ enum prefixes { /* instruction prefixes */ P_REPZ, P_TIMES, P_WAIT, + P_XACQUIRE, + P_XRELEASE, PREFIX_ENUM_LIMIT }; @@ -562,6 +564,7 @@ enum ea_type { enum prefix_pos { PPS_WAIT, /* WAIT (technically not a prefix!) */ PPS_LREP, /* Lock or REP prefix */ + PPS_HLE, /* xacquire/xrelease (hardware lock elision prefix) */ PPS_SEG, /* Segment override prefix */ PPS_OSIZE, /* Operand size prefix */ PPS_ASIZE, /* Address size prefix */ diff --git a/parser.c b/parser.c index 37d7138..825da0d 100644 --- a/parser.c +++ b/parser.c @@ -80,6 +80,9 @@ static int prefix_slot(int prefix) case R_FS: case R_GS: return PPS_SEG; + case P_XACQUIRE: + case P_XRELEASE: + return PPS_HLE; case P_LOCK: case P_REP: case P_REPE: diff --git a/tokens.dat b/tokens.dat index c7d3b97..eff15f6 100644 --- a/tokens.dat +++ b/tokens.dat @@ -52,6 +52,8 @@ repnz repz times wait +xacquire +xrelease % TOKEN_SPECIAL, 0, S_* abs |
From: H. P. A. <hp...@zy...> - 2012-02-14 23:06:05
|
On 02/14/2012 02:03 PM, Cyrill Gorcunov wrote: > Hi, while disasm is not yet done, here what I thought about > assembler part. It's not yet complete but just to share. > > At moment the idea is to try to guess if we need to emit > additional lock prefix for xacquire/release instructions. > > (the patch for insns.dat > > +; > +; transactional synchronization extensions > +XABORT imm8 [i: c6 f8 ib] FUTURE,HLE > +XBEGIN imm16 [i: c7 f8 iw] FUTURE,HLE > +XBEGIN imm32 [i: c7 f8 id] FUTURE,HLE > +XEND void [ 0f 01 d5] FUTURE,HLE > +XTEST void [ 0f 01 d6] FUTURE,HLE,RTM > + > > is in my tree already, simply desided to not push it upstream > until everything is done). > I pushed that one (with fixes) already. > > +static bool hle_should_emit_lock(const struct itemplate *t, int prefix) > +{ > + switch ((int)t->opcode) { > + case I_ADD: > + case I_ADC: > + case I_AND: > + case I_BTC: > + case I_BTR: > + case I_BTS: > + case I_CMPXCHG: > + case I_CMPXCHG8B: > + case I_DEC: > + case I_INC: > + case I_NEG: > + case I_NOT: > + case I_OR: > + case I_SBB: > + case I_SUB: > + case I_XOR: > + case I_XADD: > + return true; > + case I_MOV: /* FIXME: Not all MOV requires lock on xrelease */ > + return true; > + case I_XCHG: > + return false; > + } > + > + return false; > +} > + I would strongly suggest that this should be data-driven; either a byte code or a flag. IIRC MOV never requires LOCK, nor does it accept it. -hpa |
From: Cyrill G. <gor...@op...> - 2012-02-14 22:24:38
|
On Tue, Feb 14, 2012 at 02:17:22PM -0800, H. Peter Anvin wrote: > On 02/14/2012 02:03 PM, Cyrill Gorcunov wrote: > >Hi, while disasm is not yet done, here what I thought about > >assembler part. It's not yet complete but just to share. > > > >At moment the idea is to try to guess if we need to emit > >additional lock prefix for xacquire/release instructions. > > > >(the patch for insns.dat > > > >+; > >+; transactional synchronization extensions > >+XABORT imm8 [i: c6 f8 ib] FUTURE,HLE > >+XBEGIN imm16 [i: c7 f8 iw] FUTURE,HLE > >+XBEGIN imm32 [i: c7 f8 id] FUTURE,HLE > >+XEND void [ 0f 01 d5] FUTURE,HLE > >+XTEST void [ 0f 01 d6] FUTURE,HLE,RTM > >+ > > > >is in my tree already, simply desided to not push it upstream > >until everything is done). > > > > I pushed that one (with fixes) already. > Ah, I forgot to update repo ;) > I would strongly suggest that this should be data-driven; either a > byte code or a flag. ok, i'll think about it, thanks! > > IIRC MOV never requires LOCK, nor does it accept it. > quoting spec: The XRELEASE prefix hint can only be used with the following instructions: - The "MOV mem, reg" (Opcode 88H/89H) and "MOV mem, imm" (Opcode C6H/C7H) instructions. In these cases, the XRELEASE is recognized without the presence of the LOCK prefix. So I seem to miss something obvious? Cyrill |
From: H. P. A. <hp...@zy...> - 2012-02-14 23:06:05
|
On 02/14/2012 02:24 PM, Cyrill Gorcunov wrote: >> >> IIRC MOV never requires LOCK, nor does it accept it. >> > > quoting spec: > The XRELEASE prefix hint can only be used with the following instructions: > > - The "MOV mem, reg" (Opcode 88H/89H) and "MOV mem, imm" (Opcode C6H/C7H) instructions. > In these cases, the XRELEASE is recognized without the presence of the LOCK > prefix. > > So I seem to miss something obvious? > Not really... it's what it says up there... doesn't require a LOCK prefix. Note that only some form of MOV is supported, which is another reason this needs to be part of the instruction pattern in insns.dat. -hpa |
From: Cyrill G. <gor...@op...> - 2012-02-14 22:33:09
|
On Tue, Feb 14, 2012 at 02:27:52PM -0800, H. Peter Anvin wrote: > On 02/14/2012 02:24 PM, Cyrill Gorcunov wrote: > >> > >>IIRC MOV never requires LOCK, nor does it accept it. > >> > > > >quoting spec: > >The XRELEASE prefix hint can only be used with the following instructions: > > > > - The "MOV mem, reg" (Opcode 88H/89H) and "MOV mem, imm" (Opcode C6H/C7H) instructions. > > In these cases, the XRELEASE is recognized without the presence of the LOCK > > prefix. > > > >So I seem to miss something obvious? > > > > Not really... it's what it says up there... doesn't require a LOCK > prefix. Note that only some form of MOV is supported, which is > another reason this needs to be part of the instruction pattern in > insns.dat. > OK, I seem to understand. Will post patch once it get done (in a couple of days I hope). Cyrill |