support checking overflow flag everywhere
This commit is contained in:
parent
df68e6eddc
commit
f9f419af71
|
@ -405,3 +405,27 @@ void test_jle_disp8_greater() {
|
||||||
);
|
);
|
||||||
CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
|
CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//:: jump if overflow
|
||||||
|
|
||||||
|
:(before "End Initialize Op Names")
|
||||||
|
put_new(Name, "70", "jump disp8 bytes away if OF is set (jcc/jo)");
|
||||||
|
put_new(Name, "71", "jump disp8 bytes away if OF is unset (jcc/jno)");
|
||||||
|
|
||||||
|
:(before "End Single-Byte Opcodes")
|
||||||
|
case 0x70: { // jump disp8 if OF is set
|
||||||
|
const int8_t offset = static_cast<int>(next());
|
||||||
|
if (OF) {
|
||||||
|
trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
|
||||||
|
EIP += offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x71: { // jump disp8 if OF is unset
|
||||||
|
const int8_t offset = static_cast<int>(next());
|
||||||
|
if (!OF) {
|
||||||
|
trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
|
||||||
|
EIP += offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
|
@ -405,3 +405,27 @@ void test_jle_disp32_greater() {
|
||||||
);
|
);
|
||||||
CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
|
CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//:: jump if overflow
|
||||||
|
|
||||||
|
:(before "End Initialize Op Names")
|
||||||
|
put_new(Name_0f, "80", "jump disp32 bytes away if OF is set (jcc/jo)");
|
||||||
|
put_new(Name_0f, "81", "jump disp32 bytes away if OF is unset (jcc/jno)");
|
||||||
|
|
||||||
|
:(before "End Two-Byte Opcodes Starting With 0f")
|
||||||
|
case 0x80: { // jump disp8 if OF is set
|
||||||
|
const int32_t offset = next32();
|
||||||
|
if (OF) {
|
||||||
|
trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
|
||||||
|
EIP += offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x81: { // jump disp8 if OF is unset
|
||||||
|
const int32_t offset = next32();
|
||||||
|
if (!OF) {
|
||||||
|
trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
|
||||||
|
EIP += offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
fn foo {
|
||||||
|
$foo: {
|
||||||
|
break-if-=
|
||||||
|
break-if-= $foo
|
||||||
|
break-if-!=
|
||||||
|
break-if-!= $foo
|
||||||
|
break-if-<=
|
||||||
|
break-if-<= $foo
|
||||||
|
break-if->=
|
||||||
|
break-if->= $foo
|
||||||
|
break-if-<
|
||||||
|
break-if-< $foo
|
||||||
|
break-if->
|
||||||
|
break-if-> $foo
|
||||||
|
break-if-carry
|
||||||
|
break-if-carry $foo
|
||||||
|
break-if-overflow
|
||||||
|
break-if-overflow $foo
|
||||||
|
loop-if-=
|
||||||
|
loop-if-= $foo
|
||||||
|
loop-if-!=
|
||||||
|
loop-if-!= $foo
|
||||||
|
loop-if-<=
|
||||||
|
loop-if-<= $foo
|
||||||
|
loop-if->=
|
||||||
|
loop-if->= $foo
|
||||||
|
loop-if-<
|
||||||
|
loop-if-< $foo
|
||||||
|
loop-if->
|
||||||
|
loop-if-> $foo
|
||||||
|
loop-if-carry
|
||||||
|
loop-if-carry $foo
|
||||||
|
loop-if-not-carry
|
||||||
|
loop-if-not-carry $foo
|
||||||
|
loop-if-overflow
|
||||||
|
loop-if-overflow $foo
|
||||||
|
loop-if-not-overflow
|
||||||
|
loop-if-not-overflow $foo
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
== code
|
||||||
|
foo:
|
||||||
|
# . prologue
|
||||||
|
55/push-ebp
|
||||||
|
89/<- %ebp 4/r32/esp
|
||||||
|
{
|
||||||
|
$foo:0x00000001:loop:
|
||||||
|
{
|
||||||
|
$foo:loop:
|
||||||
|
{
|
||||||
|
0f 85/jump-if-!= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 85/jump-if-!= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 84/jump-if-= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 84/jump-if-= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8f/jump-if-> break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8f/jump-if-> break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8c/jump-if-< break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8c/jump-if-< break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8d/jump-if->= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8d/jump-if->= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8e/jump-if-<= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8e/jump-if-<= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 83/jump-if-addr>= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 83/jump-if-addr>= break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 81/jump-if-not-overflow break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 81/jump-if-not-overflow break/disp32
|
||||||
|
e9/jump $foo:break/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 85/jump-if-!= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 85/jump-if-!= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 84/jump-if-= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 84/jump-if-= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8f/jump-if-> break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8f/jump-if-> break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8c/jump-if-< break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8c/jump-if-< break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8d/jump-if->= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8d/jump-if->= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8e/jump-if-<= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 8e/jump-if-<= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 83/jump-if-addr>= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 83/jump-if-addr>= break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 82/jump-if-addr< break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 82/jump-if-addr< break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 81/jump-if-not-overflow break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 81/jump-if-not-overflow break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 80/jump-if-overflow break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
{
|
||||||
|
0f 80/jump-if-overflow break/disp32
|
||||||
|
e9/jump $foo:loop/disp32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$foo:break:
|
||||||
|
}
|
||||||
|
$foo:0x00000001:break:
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
248
linux/mu.subx
248
linux/mu.subx
|
@ -27610,9 +27610,9 @@ $emit-reverse-break:end:
|
||||||
# Table from Mu branch instructions to the reverse SubX opcodes for them.
|
# Table from Mu branch instructions to the reverse SubX opcodes for them.
|
||||||
Reverse-branch: # (table (handle array byte) (handle array byte))
|
Reverse-branch: # (table (handle array byte) (handle array byte))
|
||||||
# a table is a stream
|
# a table is a stream
|
||||||
0x1c0/imm32/write
|
0x240/imm32/write
|
||||||
0/imm32/read
|
0/imm32/read
|
||||||
0x1c0/imm32/size
|
0x240/imm32/size
|
||||||
# data
|
# data
|
||||||
0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
|
0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
|
||||||
0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
|
0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
|
||||||
|
@ -27642,6 +27642,14 @@ Reverse-branch: # (table (handle array byte) (handle array byte))
|
||||||
0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
|
0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
|
||||||
0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
||||||
0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-break-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-loop-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-break-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-loop-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-break-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-loop-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-break-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32
|
||||||
|
0x11/imm32/alloc-id _string-loop-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32
|
||||||
|
|
||||||
== code
|
== code
|
||||||
|
|
||||||
|
@ -32836,6 +32844,82 @@ _Primitive-break-if->: # (payload primitive)
|
||||||
0/imm32/no-xm32
|
0/imm32/no-xm32
|
||||||
0/imm32/no-x32
|
0/imm32/no-x32
|
||||||
0x11/imm32/alloc-id:fake
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-break-if-carry/imm32/next
|
||||||
|
_Primitive-break-if-carry: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-break-if-carry/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_82_jump_break/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-break-if-not-carry/imm32/next
|
||||||
|
_Primitive-break-if-not-carry: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-break-if-not-carry/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_83_jump_break/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-break-if-overflow/imm32/next
|
||||||
|
_Primitive-break-if-overflow: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-break-if-overflow/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_80_jump_break/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-break-if-not-overflow/imm32/next
|
||||||
|
_Primitive-break-if-not-overflow: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-break-if-not-overflow/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_81_jump_break/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
_Primitive-break/imm32/next
|
_Primitive-break/imm32/next
|
||||||
_Primitive-break: # (payload primitive)
|
_Primitive-break: # (payload primitive)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
@ -33045,6 +33129,82 @@ _Primitive-loop-if->: # (payload primitive)
|
||||||
0/imm32/no-xm32
|
0/imm32/no-xm32
|
||||||
0/imm32/no-x32
|
0/imm32/no-x32
|
||||||
0x11/imm32/alloc-id:fake
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-loop-if-carry/imm32/next
|
||||||
|
_Primitive-loop-if-carry: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-loop-if-carry/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_82_jump_loop/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-loop-if-not-carry/imm32/next
|
||||||
|
_Primitive-loop-if-not-carry: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-loop-if-not-carry/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_83_jump_loop/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-loop-if-overflow/imm32/next
|
||||||
|
_Primitive-loop-if-overflow: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-loop-if-overflow/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_80_jump_loop/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_Primitive-loop-if-not-overflow/imm32/next
|
||||||
|
_Primitive-loop-if-not-overflow: # (payload primitive)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string-loop-if-not-overflow/imm32/name
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-inouts
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0/imm32/no-outputs
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
|
_string_0f_81_jump_loop/imm32/subx-name
|
||||||
|
0/imm32/no-rm32
|
||||||
|
0/imm32/no-r32
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-imm8
|
||||||
|
0/imm32/no-disp32
|
||||||
|
0/imm32/no-xm32
|
||||||
|
0/imm32/no-x32
|
||||||
|
0x11/imm32/alloc-id:fake
|
||||||
_Primitive-loop/imm32/next # we probably don't need an unconditional break
|
_Primitive-loop/imm32/next # we probably don't need an unconditional break
|
||||||
_Primitive-loop: # (payload primitive)
|
_Primitive-loop: # (payload primitive)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
@ -33891,6 +34051,26 @@ _string-break-if-float>=: # (payload array byte)
|
||||||
# "break-if-float>="
|
# "break-if-float>="
|
||||||
0x10/imm32/size
|
0x10/imm32/size
|
||||||
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
|
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
|
||||||
|
_string-break-if-carry: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "break-if-carry"
|
||||||
|
0xe/imm32/size
|
||||||
|
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
|
||||||
|
_string-break-if-not-carry: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "break-if-not-carry"
|
||||||
|
0x12/imm32/size
|
||||||
|
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
|
||||||
|
_string-break-if-overflow: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "break-if-overflow"
|
||||||
|
0x11/imm32/size
|
||||||
|
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
|
_string-break-if-not-overflow: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "break-if-not-overflow"
|
||||||
|
0x15/imm32/size
|
||||||
|
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
_string-compare: # (payload array byte)
|
_string-compare: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "compare"
|
# "compare"
|
||||||
|
@ -33910,12 +34090,12 @@ _string-copy-byte:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "copy-byte"
|
# "copy-byte"
|
||||||
0x9/imm32/size
|
0x9/imm32/size
|
||||||
0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e
|
0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e
|
||||||
_string-copy-byte-to:
|
_string-copy-byte-to:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "copy-byte-to"
|
# "copy-byte-to"
|
||||||
0xc/imm32/size
|
0xc/imm32/size
|
||||||
0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o
|
0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o
|
||||||
_string-decrement: # (payload array byte)
|
_string-decrement: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "decrement"
|
# "decrement"
|
||||||
|
@ -34001,6 +34181,26 @@ _string-loop-if-float>=: # (payload array byte)
|
||||||
# "loop-if-float>="
|
# "loop-if-float>="
|
||||||
0xf/imm32/size
|
0xf/imm32/size
|
||||||
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
|
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
|
||||||
|
_string-loop-if-carry: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "loop-if-carry"
|
||||||
|
0xd/imm32/size
|
||||||
|
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
|
||||||
|
_string-loop-if-not-carry: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "loop-if-not-carry"
|
||||||
|
0x11/imm32/size
|
||||||
|
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
|
||||||
|
_string-loop-if-overflow: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "loop-if-overflow"
|
||||||
|
0x10/imm32/size
|
||||||
|
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
|
_string-loop-if-not-overflow: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "loop-if-not-overflow"
|
||||||
|
0x14/imm32/size
|
||||||
|
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
_string-multiply: # (payload array byte)
|
_string-multiply: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "multiply"
|
# "multiply"
|
||||||
|
@ -34045,12 +34245,12 @@ _string-square-root:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "square-root"
|
# "square-root"
|
||||||
0xb/imm32/size
|
0xb/imm32/size
|
||||||
0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/- 0x72/r 0x6f/o 0x6f/o 0x74/t
|
0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
|
||||||
_string-inverse-square-root:
|
_string-inverse-square-root:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "inverse-square-root"
|
# "inverse-square-root"
|
||||||
0x13/imm32/size
|
0x13/imm32/size
|
||||||
0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/- 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/- 0x72/r 0x6f/o 0x6f/o 0x74/t
|
0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
|
||||||
_string-negate: # (payload array byte)
|
_string-negate: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "negate"
|
# "negate"
|
||||||
|
@ -34133,6 +34333,36 @@ _string_0d_or_with_eax: # (payload array byte)
|
||||||
# "0d/or-with-eax"
|
# "0d/or-with-eax"
|
||||||
0xe/imm32/size
|
0xe/imm32/size
|
||||||
0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
|
0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
|
||||||
|
_string_0f_80_jump_label: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 80/jump-if-overflow"
|
||||||
|
0x16/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
|
_string_0f_80_jump_break: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 80/jump-if-overflow break/disp32"
|
||||||
|
0x23/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
||||||
|
_string_0f_80_jump_loop: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 80/jump-if-overflow loop/disp32"
|
||||||
|
0x22/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
||||||
|
_string_0f_81_jump_label: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 81/jump-if-not-overflow"
|
||||||
|
0x1a/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
|
||||||
|
_string_0f_81_jump_break: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 81/jump-if-not-overflow break/disp32"
|
||||||
|
0x27/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
||||||
|
_string_0f_81_jump_loop: # (payload array byte)
|
||||||
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
# "0f 81/jump-if-not-overflow loop/disp32"
|
||||||
|
0x26/imm32/size
|
||||||
|
0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
||||||
_string_0f_82_jump_label: # (payload array byte)
|
_string_0f_82_jump_label: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "0f 82/jump-if-addr<"
|
# "0f 82/jump-if-addr<"
|
||||||
|
@ -34176,7 +34406,7 @@ _string_0f_84_jump_break: # (payload array byte)
|
||||||
_string_0f_84_jump_loop: # (payload array byte)
|
_string_0f_84_jump_loop: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "0f 84/jump-if-= loop/disp32"
|
# "0f 84/jump-if-= loop/disp32"
|
||||||
0x1b/imm32/size
|
0x1a/imm32/size
|
||||||
0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
|
||||||
_string_0f_85_jump_label: # (payload array byte)
|
_string_0f_85_jump_label: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
|
@ -34527,12 +34757,12 @@ _string_8a_copy_byte:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "8a/byte->"
|
# "8a/byte->"
|
||||||
0x9/imm32/size
|
0x9/imm32/size
|
||||||
0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/>
|
0x38/8 0x61/a 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x3e/>
|
||||||
_string_88_copy_byte:
|
_string_88_copy_byte:
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "88/byte<-"
|
# "88/byte<-"
|
||||||
0x9/imm32/size
|
0x9/imm32/size
|
||||||
0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/-
|
0x38/8 0x38/8 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/-
|
||||||
_string_8d_copy_address: # (payload array byte)
|
_string_8d_copy_address: # (payload array byte)
|
||||||
0x11/imm32/alloc-id:fake:payload
|
0x11/imm32/alloc-id:fake:payload
|
||||||
# "8d/copy-address"
|
# "8d/copy-address"
|
||||||
|
|
|
@ -293,6 +293,31 @@ Similar float variants like `break-if-float<` are aliases for the corresponding
|
||||||
`addr` equivalents. The x86 instruction set stupidly has floating-point
|
`addr` equivalents. The x86 instruction set stupidly has floating-point
|
||||||
operations only update a subset of flags.
|
operations only update a subset of flags.
|
||||||
|
|
||||||
|
Four sets of conditional jumps are useful for detecting overflow.
|
||||||
|
|
||||||
|
break-if-carry => "0f 82/jump-if-carry break/disp32"
|
||||||
|
break-if-carry label => "0f 82/jump-if-carry " label "/disp32"
|
||||||
|
loop-if-carry => "0f 82/jump-if-carry break/disp32"
|
||||||
|
loop-if-carry label => "0f 82/jump-if-carry " label "/disp32"
|
||||||
|
|
||||||
|
break-if-not-carry => "0f 83/jump-if-not-carry break/disp32"
|
||||||
|
break-if-not-carry label => "0f 83/jump-if-not-carry " label "/disp32"
|
||||||
|
loop-if-not-carry => "0f 83/jump-if-not-carry break/disp32"
|
||||||
|
loop-if-not-carry label => "0f 83/jump-if-not-carry " label "/disp32"
|
||||||
|
|
||||||
|
break-if-overflow => "0f 80/jump-if-overflow break/disp32"
|
||||||
|
break-if-overflow label => "0f 80/jump-if-overflow " label ":break/disp32"
|
||||||
|
loop-if-overflow => "0f 80/jump-if-overflow loop/disp32"
|
||||||
|
loop-if-overflow label => "0f 80/jump-if-overflow " label ":loop/disp32"
|
||||||
|
|
||||||
|
break-if-not-overflow => "0f 81/jump-if-not-overflow break/disp32"
|
||||||
|
break-if-not-overflow label => "0f 81/jump-if-not-overflow " label ":break/disp32"
|
||||||
|
loop-if-not-overflow => "0f 81/jump-if-not-overflow loop/disp32"
|
||||||
|
loop-if-not-overflow label => "0f 81/jump-if-not-overflow " label ":loop/disp32"
|
||||||
|
|
||||||
|
All this relies on a convention that every `{}` block is delimited by labels
|
||||||
|
ending in `:loop` and `:break`.
|
||||||
|
|
||||||
## Returns
|
## Returns
|
||||||
|
|
||||||
The `return` instruction cleans up variable declarations just like an unconditional
|
The `return` instruction cleans up variable declarations just like an unconditional
|
||||||
|
|
|
@ -51,6 +51,8 @@ Opcodes currently supported by SubX:
|
||||||
5f: pop top of stack to EDI (pop)
|
5f: pop top of stack to EDI (pop)
|
||||||
68: push imm32 to stack (push)
|
68: push imm32 to stack (push)
|
||||||
69: multiply rm32 by imm32 and store result in r32 (imul)
|
69: multiply rm32 by imm32 and store result in r32 (imul)
|
||||||
|
70: jump disp8 bytes away if OF is set (jcc/jo)
|
||||||
|
71: jump disp8 bytes away if OF is unset (jcc/jno)
|
||||||
72: jump disp8 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
|
72: jump disp8 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
|
||||||
73: jump disp8 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
|
73: jump disp8 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
|
||||||
74: jump disp8 bytes away if equal, if ZF is set (jcc/jz/je)
|
74: jump disp8 bytes away if equal, if ZF is set (jcc/jz/je)
|
||||||
|
@ -91,6 +93,8 @@ Opcodes currently supported by SubX:
|
||||||
f7: negate/multiply/divide rm32 (with EAX and EDX if necessary) depending on subop (neg/mul/idiv)
|
f7: negate/multiply/divide rm32 (with EAX and EDX if necessary) depending on subop (neg/mul/idiv)
|
||||||
ff: increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)
|
ff: increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)
|
||||||
0f 2f: compare: set CF if x32 < xm32 (comiss)
|
0f 2f: compare: set CF if x32 < xm32 (comiss)
|
||||||
|
0f 80: jump disp32 bytes away if OF is set (jcc/jo)
|
||||||
|
0f 81: jump disp32 bytes away if OF is unset (jcc/jno)
|
||||||
0f 82: jump disp32 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
|
0f 82: jump disp32 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
|
||||||
0f 83: jump disp32 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
|
0f 83: jump disp32 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
|
||||||
0f 84: jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)
|
0f 84: jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)
|
||||||
|
|
Loading…
Reference in New Issue