aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-06 05:22:38 +1300
committerAndrew Chambers <[email protected]>2021-10-06 05:22:38 +1300
commite0ff42fe7eb739d4320ec9f089eaa247bfca9fc8 (patch)
treeea8ed9d97688d8b391eed1c7c6fee14d21076d55
parent513cfa84f2e6b06e2ac8133cf1d3432fdbaf2f20 (diff)
More opcodes.
-rw-r--r--main.c49
-rw-r--r--test/test.sh57
2 files changed, 82 insertions, 24 deletions
diff --git a/main.c b/main.c
index 4e8f24f..38ce100 100644
--- a/main.c
+++ b/main.c
@@ -309,27 +309,39 @@ static void assemble() {
}
}
- if (isregkind(op->src->kind) && isregkind(op->dst->kind)) {
+ if (isregkind(op->dst->kind)) {
+ rm = rbits(op->dst->kind);
+ }
+
+ if (isregkind(op->src->kind)) {
- if (op->kind == ASM_ADD)
- opcode = 0x03;
- else if (op->kind == ASM_SUB)
- opcode = 0x2b;
- else {
+ if (op->kind == ASM_ADD) {
+ opcode = 0x01;
+ } else if (op->kind == ASM_AND) {
+ opcode = 0x21;
+ } else if (op->kind == ASM_SUB) {
+ opcode = 0x29;
+ } else if (op->kind == ASM_XOR) {
+ opcode = 0x31;
+ } else {
fatal("unreachable");
}
- reg = rbits(op->dst->kind);
- rm = rbits(op->src->kind);
-
+ reg = rbits(op->src->kind);
} else if (op->src->kind == ASM_IMM) {
if (op->kind == ASM_ADD) {
opcode = 0x81;
reg = 0x00;
+ } else if (op->kind == ASM_AND) {
+ opcode = 0x81;
+ reg = 0x05;
} else if (op->kind == ASM_SUB) {
opcode = 0x81;
reg = 0x05;
+ } else if (op->kind == ASM_XOR) {
+ opcode = 0x81;
+ reg = 0x05;
} else {
fatal("unreachable");
}
@@ -340,23 +352,8 @@ static void assemble() {
rm = rbits(op->dst->kind);
}
- } else if (isregkind(op->src->kind)) {
- assert(memarg);
-
- if (op->kind == ASM_ADD) {
- opcode = 0x01;
- } else if (op->kind == ASM_SUB) {
- opcode = 0x29;
- } else {
- fatal("unreachable");
- }
-
- reg = rbits(op->src->kind);
-
} else if (op->src->kind == ASM_MEMARG) {
fatal("todo");
- } else {
- fatal("unreachable");
}
rex = REX(op->type == 'q', reg & (1 << 4), 0, rm & (1 << 4));
@@ -372,6 +369,8 @@ static void assemble() {
}
switch (dispsz) {
+ case 0:
+ break;
case 1:
sb((uint8_t)disp);
break;
@@ -383,6 +382,8 @@ static void assemble() {
}
switch (immsz) {
+ case 0:
+ break;
case 1:
sb((uint8_t)imm);
break;
diff --git a/test/test.sh b/test/test.sh
new file mode 100644
index 0000000..cd174e7
--- /dev/null
+++ b/test/test.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+set -eu
+
+tmps="$(mktemp --suffix .s)"
+tmpo="$(mktemp --suffix .o)"
+tmpb="$(mktemp --suffix .bin)"
+
+trap "rm -f \"$tmps\" \"$tmpo\" \"$tmpb\"" EXIT
+
+t () {
+ echo "$1" > "$tmps"
+ clang -Wno-everything -c -s "$tmps" -o "$tmpo"
+ objcopy -j ".text" -O binary "$tmpo" "$tmpb"
+ want="$(xxd -ps "$tmpb" | head -n 1 | cut -d ' ' -f 2-)"
+ ./minias < "$tmps" > "$tmpo"
+ objcopy -j ".text" -O binary "$tmpo" "$tmpb"
+ got="$(xxd -ps "$tmpb" | head -n 1 | cut -d ' ' -f 2-)"
+ if test "$got" != "$want"
+ then
+ echo ""
+ echo "want: $1 -> $want"
+ echo "got: $1 -> $got"
+ exit 1
+ fi
+ echo -n "."
+}
+
+t "nop"
+t "ret"
+t "leave"
+t "addq %rax, %rax"
+t "addl %eax, %eax"
+t "subq %rax, %rax"
+t "subl %eax, %eax"
+t "addq %rax, %rbx"
+t "addl %eax, %ebx"
+t "addq %rax, (%rax)"
+t "addq %rax, (%rbx)"
+t "addl %eax, (%rax)"
+t "addl %eax, (%r9)"
+t "addl %ebx, (%r9)"
+
+t "xorq %rax, %rax"
+t "xorq %rax, (%rax)"
+t "xorl %eax, %eax"
+
+t "andq %rax, %rax"
+t "andq %rax, (%rax)"
+t "andl %eax, %eax"
+
+
+
+#t "addq %rbp, (%rax)"
+
+
+#t "addq %rax, %rbx"
+#t "addl %eax, %ebx"