Skip to content
Browse files

Merge branch 'feature/neg' into develop

  • Loading branch information...
2 parents b6351fd + 3d97d4f commit cda40c4df1e933553411193ccbb16abb6ec5249b @sarnesjo committed Jun 3, 2011
View
4 README.md
@@ -90,8 +90,8 @@ Example:
xo is a prototype, and has numerous shortcomings:
-* Support for many important instructions, such as neg, mul and lea, as well as
- shift and rotate instructions, is missing.
+* Support for many important instructions, such as mul and lea, as well as shift
+ and rotate instructions, is missing.
* Immediate values are not supported.
* Multiple output registers are not supported. The output register is assumed to
be the last register written to.
View
37 src/equivalence_checker_bdd.cpp
@@ -167,13 +167,13 @@ static void insn_inc_(bdd r0[XO_NUM_BITS], bdd r1[XO_NUM_BITS], bdd f[XO_NUM_FLA
{
bdd c[XO_NUM_BITS];
- c[0] = r0[0] & bdd_true();
- r0[0] = r0[0] ^ bdd_true();
+ c[0] = r0[0];
+ r0[0] = !r0[0];
for(int i = 1; i < XO_NUM_BITS; ++i)
{
- c[i] = r0[i] & bdd_false() | r0[i] & c[i-1] | bdd_false() & c[i-1];
- r0[i] = r0[i] ^ bdd_false() ^ c[i-1];
+ c[i] = r0[i] & c[i-1];
+ r0[i] = r0[i] ^ c[i-1];
}
f[1] = c[30] ^ c[31];
@@ -186,13 +186,13 @@ static void insn_dec_(bdd r0[XO_NUM_BITS], bdd r1[XO_NUM_BITS], bdd f[XO_NUM_FLA
{
bdd c[XO_NUM_BITS];
- c[0] = !r0[0] & bdd_true();
- r0[0] = r0[0] ^ bdd_true();
+ c[0] = !r0[0];
+ r0[0] = !r0[0];
for(int i = 1; i < XO_NUM_BITS; ++i)
{
- c[i] = !r0[i] & bdd_false() | !r0[i] & c[i-1] | bdd_false() & c[i-1];
- r0[i] = r0[i] ^ bdd_false() ^ c[i-1];
+ c[i] = !r0[i] & c[i-1];
+ r0[i] = r0[i] ^ c[i-1];
}
f[1] = c[30] ^ c[31];
@@ -201,6 +201,26 @@ static void insn_dec_(bdd r0[XO_NUM_BITS], bdd r1[XO_NUM_BITS], bdd f[XO_NUM_FLA
f[4] = zf_(r0);
}
+static void insn_neg_(bdd r0[XO_NUM_BITS], bdd r1[XO_NUM_BITS], bdd f[XO_NUM_FLAGS])
+{
+ bdd c[XO_NUM_BITS];
+
+ c[0] = !r0[0];
+ r0[0] = r0[0];
+
+ for(int i = 1; i < XO_NUM_BITS; ++i)
+ {
+ c[i] = !r0[i] & c[i-1];
+ r0[i] = !r0[i] ^ c[i-1];
+ }
+
+ f[0] = !zf_(r0);
+ f[1] = c[30] ^ c[31];
+ f[2] = pf_(r0);
+ f[3] = sf_(r0);
+ f[4] = zf_(r0);
+}
+
static void insn_and_(bdd r0[XO_NUM_BITS], bdd r1[XO_NUM_BITS], bdd f[XO_NUM_FLAGS])
{
for(int i = 0; i < XO_NUM_BITS; ++i)
@@ -308,6 +328,7 @@ bdd_impl_ impl_for_insn_(const xo_instruction *insn)
impls[XO_INSN_CMP] = insn_cmp_;
impls[XO_INSN_INC] = insn_inc_;
impls[XO_INSN_DEC] = insn_dec_;
+ impls[XO_INSN_NEG] = insn_neg_;
impls[XO_INSN_AND] = insn_and_;
impls[XO_INSN_OR] = insn_or_;
View
12 src/equivalence_checker_c.c
@@ -112,6 +112,17 @@ static void insn_dec_(xo_machine_state *st, size_t r0, size_t r1)
xo_machine_state_set_zf(st, zf_(st->regs[r0]));
}
+static void insn_neg_(xo_machine_state *st, size_t r0, size_t r1)
+{
+ st->regs[r0] = -st->regs[r0];
+
+ xo_machine_state_set_cf(st, st->regs[r0] != 0);
+ xo_machine_state_set_of(st, st->regs[r0] == 0x80000000);
+ xo_machine_state_set_pf(st, pf_(st->regs[r0]));
+ xo_machine_state_set_sf(st, sf_(st->regs[r0]));
+ xo_machine_state_set_zf(st, zf_(st->regs[r0]));
+}
+
static void insn_and_(xo_machine_state *st, size_t r0, size_t r1)
{
st->regs[r0] &= st->regs[r1];
@@ -221,6 +232,7 @@ c_impl_ impl_for_insn_(const xo_instruction *insn)
impls[XO_INSN_CMP] = insn_cmp_;
impls[XO_INSN_INC] = insn_inc_;
impls[XO_INSN_DEC] = insn_dec_;
+ impls[XO_INSN_NEG] = insn_neg_;
impls[XO_INSN_AND] = insn_and_;
impls[XO_INSN_OR] = insn_or_;
View
1 src/insns.c
@@ -25,6 +25,7 @@ xo_instruction xo_insns[] =
{XO_INSN_CMP, "cmp", 2, R0|R1, 0, 0, CF|OF|PF|SF|ZF, CF|OF|PF|SF|ZF}, // imm
{XO_INSN_INC, "inc", 1, R0, R0, 0, OF|PF|SF|ZF, OF|PF|SF|ZF},
{XO_INSN_DEC, "dec", 1, R0, R0, 0, OF|PF|SF|ZF, OF|PF|SF|ZF},
+ {XO_INSN_NEG, "neg", 1, R0, R0, 0, CF|OF|PF|SF|ZF, CF|OF|PF|SF|ZF},
// logic
{XO_INSN_AND, "and", 2, R0|R1, R0, 0, CF|OF|PF|SF|ZF, CF|OF|PF|SF|ZF}, // imm
View
1 src/insns.h
@@ -12,6 +12,7 @@ enum
XO_INSN_CMP,
XO_INSN_INC,
XO_INSN_DEC,
+ XO_INSN_NEG,
XO_INSN_AND,
XO_INSN_OR,
View
1 tests/asm_input_insns.c
@@ -11,6 +11,7 @@ int main()
// unary insns
CHECK(xo_parser_validate("dec r0;"));
CHECK(xo_parser_validate("inc r0;"));
+ CHECK(xo_parser_validate("neg r0;"));
CHECK(xo_parser_validate("not r0;"));
// binary insns
View
5 tests/insn_impl.c
@@ -92,6 +92,11 @@ int main()
CHECK(expected_output("dec r0;", 0x80000000, 0x00000000, 0, 0x7fffffff, OF|PF));
CHECK(expected_output("dec r0;", 0x80000000, 0x00000000, CF, 0x7fffffff, CF|OF|PF));
+ CHECK(expected_output("neg r0;", 0x00000000, 0x00000000, 0, 0x00000000, PF|ZF));
+ CHECK(expected_output("neg r0;", 0x00000001, 0x00000000, 0, 0xffffffff, CF|PF|SF));
+ CHECK(expected_output("neg r0;", 0xffffffff, 0x00000000, 0, 0x00000001, CF));
+ CHECK(expected_output("neg r0;", 0x80000000, 0x00000000, 0, 0x80000000, CF|OF|PF|SF));
+
// logic
CHECK(expected_output("and r0,r1;", 0x00000000, 0x00000000, 0, 0x00000000, PF|ZF));
View
1 tests/program_analysis.c
@@ -41,6 +41,7 @@ int main()
// unary insns
CHECK(program_regs("dec r0;", R0, R0));
CHECK(program_regs("inc r0;", R0, R0));
+ CHECK(program_regs("neg r0;", R0, R0));
CHECK(program_regs("not r0;", R0, R0));
// binary insns
View
6 tests/program_equivalence.c
@@ -34,6 +34,7 @@ int main()
CHECK(equivalent("sub r0,r1;", "sub r0,r1;"));
CHECK(equivalent("inc r0;", "inc r0;"));
CHECK(equivalent("dec r0;", "dec r0;"));
+ CHECK(equivalent("neg r0;", "neg r0;"));
CHECK(equivalent("and r0,r1;", "and r0,r1;"));
CHECK(equivalent("or r0,r1;", "or r0,r1;"));
CHECK(equivalent("xor r0,r1;", "xor r0,r1;"));
@@ -45,6 +46,7 @@ int main()
CHECK(!equivalent("sub r0,r1;", "sub r1,r0;"));
CHECK(!equivalent("inc r0;", "inc r1;"));
CHECK(!equivalent("dec r0;", "dec r1;"));
+ CHECK(!equivalent("neg r0;", "neg r1;"));
CHECK(!equivalent("and r0,r1;", "and r1,r0;"));
CHECK(!equivalent("or r0,r1;", "or r1,r0;"));
CHECK(!equivalent("xor r0,r1;", "xor r1,r0;"));
@@ -92,5 +94,9 @@ int main()
CHECK(!equivalent("xor r0,r0; xor r1,r1; xor r2,r2; inc r1; dec r2; cmp r3,r0; cmovg r3,r1; cmovl r3,r2;",
"add r3,r3; sbb r3,r3; add r3,r3; inc r3;"));
+ // -x is equivalent to 0-x
+ CHECK(equivalent("neg r0;", "mov r1,r0; xor r0,r0; sub r0,r1;"));
+ CHECK(equivalent("mov r1,r0; neg r1;", "xor r1,r1; sub r1,r0;"));
+
return EXIT_SUCCESS;
}
View
1 tests/program_generator.c
@@ -53,6 +53,7 @@ int main()
CHECK(generates_self("sub r0,r1;"));
CHECK(generates_self("inc r0;"));
CHECK(generates_self("dec r0;"));
+ CHECK(generates_self("neg r0;"));
CHECK(generates_self("and r0,r1;"));
CHECK(generates_self("or r0,r1;"));
CHECK(generates_self("xor r0,r1;"));

0 comments on commit cda40c4

Please sign in to comment.
Something went wrong with that request. Please try again.