X86: Distinguish between the rep and repe prefixes.

STOS and MOVS only accept the rep prefix which always loops until rcx becomes
0. The other string instructions accept repe (same encoding as rep) and repne
which also check the condition code flags each iteration.

--HG--
extra : convert_revision : 544149f640302070810fb53e53bfeb0e87160ffc
This commit is contained in:
Gabe Black 2007-10-02 23:02:18 -07:00
parent 504f90f763
commit c2d60abf52
4 changed files with 33 additions and 41 deletions

View file

@ -332,8 +332,8 @@
0x3: mov_Ov_rAX();
0x4: StringInst::MOVS(Yb,Xb);
0x5: StringInst::MOVS(Yv,Xv);
0x6: StringInst::CMPS(Yb,Xb);
0x7: StringInst::CMPS(Yv,Xv);
0x6: StringTestInst::CMPS(Yb,Xb);
0x7: StringTestInst::CMPS(Yv,Xv);
}
0x15: decode OPCODE_OP_BOTTOM3 {
0x0: Inst::TEST(rAb,Ib);
@ -342,8 +342,8 @@
0x3: StringInst::STOS(Yv);
0x4: lods_Al_Xb();
0x5: lods_rAX_Xv();
0x6: StringInst::SCAS(Yb);
0x7: StringInst::SCAS(Yv);
0x6: StringTestInst::SCAS(Yb);
0x7: StringTestInst::SCAS(Yv);
}
format Inst {
0x16: MOV(Bb,Ib);

View file

@ -61,7 +61,7 @@
//
//////////////////////////////////////////////////////////////////////////
def format StringInst(*opTypeSet) {{
def format StringTestInst(*opTypeSet) {{
allBlocks = OutputBlocks()
regBlocks = specializeInst(Name, list(opTypeSet), EmulEnv())
@ -86,3 +86,29 @@ def format StringInst(*opTypeSet) {{
(header_output, decoder_output,
decode_block, exec_output) = allBlocks.makeList()
}};
def format StringInst(*opTypeSet) {{
allBlocks = OutputBlocks()
regBlocks = specializeInst(Name, list(opTypeSet), EmulEnv())
eBlocks = specializeInst(Name + "_E", list(opTypeSet), EmulEnv())
for blocks in (regBlocks, eBlocks):
allBlocks.header_output += blocks.header_output
allBlocks.decoder_output += blocks.decoder_output
allBlocks.exec_output += blocks.exec_output
allBlocks.decode_block = '''
if (LEGACY_REP) {
%s
} else if (LEGACY_REPNE) {
// The repne prefix is illegal
return new MicroFault(machInst, "illprefix", new InvalidOpcode);
} else {
%s
}
''' % (eBlocks.decode_block, regBlocks.decode_block)
(header_output, decoder_output,
decode_block, exec_output) = allBlocks.makeList()
}};

View file

@ -82,25 +82,7 @@ topOfLoop:
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
add rsi, rsi, t3, dataSize=asz
bri t0, label("topOfLoop"), flags=(CSTRZnEZF,)
fault "NoFault"
};
def macroop MOVS_N_M_M {
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
topOfLoop:
ld t1, seg, [1, t0, rsi]
st t1, es, [1, t0, rdi]
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
add rsi, rsi, t3, dataSize=asz
bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,)
bri t0, label("topOfLoop"), flags=(nCEZF,)
fault "NoFault"
};
'''

View file

@ -78,23 +78,7 @@ topOfLoop:
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
bri t0, label("topOfLoop"), flags=(CSTRZnEZF,)
fault "NoFault"
};
def macroop STOS_N_M {
# Find the constant we need to either add or subtract from rdi
ruflag t0, 10
movi t3, t3, dsz, flags=(CEZF,), dataSize=asz
subi t4, t0, dsz, dataSize=asz
mov t3, t3, t4, flags=(nCEZF,), dataSize=asz
topOfLoop:
st rax, es, [1, t0, rdi]
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t3, dataSize=asz
bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,)
bri t0, label("topOfLoop"), flags=(nCEZF,)
fault "NoFault"
};
'''