aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm.peg24
-rw-r--r--main.c23
-rw-r--r--minias.h4
-rw-r--r--test/test.sh28
4 files changed, 68 insertions, 11 deletions
diff --git a/asm.peg b/asm.peg
index a2e90b1..f958b8c 100644
--- a/asm.peg
+++ b/asm.peg
@@ -113,10 +113,14 @@ instr =
| i:cqto { $$ = i; }
| i:nop { $$ = i; }
# Floating point is less common, so check last.
+ | i:addss { $$ = i; }
+ | i:addsd { $$ = i; }
| i:divsd { $$ = i; }
| i:pxor { $$ = i; }
| i:xorpd { $$ = i; }
| i:xorps { $$ = i; }
+ | i:subsd { $$ = i; }
+ | i:subss { $$ = i; }
| i:ucomisd { $$ = i; }
| i:ucomiss { $$ = i; }
| (& 'c'
@@ -422,6 +426,26 @@ test = "test" (
# Floating point instructions.
+addsd = "addsd" (
+ ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+) { $$.instr.kind = ASM_ADDSD; }
+
+addss = "addss" (
+ ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+) { $$.instr.kind = ASM_ADDSS; }
+
+subsd = "subsd" (
+ ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+) { $$.instr.kind = ASM_SUBSD; }
+
+subss = "subss" (
+ ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+) { $$.instr.kind = ASM_SUBSS; }
+
cvtsi2sd = "cvtsi2sd" (
ws s:r32 ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
| ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
diff --git a/main.c b/main.c
index c5e2e96..c5c5746 100644
--- a/main.c
+++ b/main.c
@@ -108,13 +108,11 @@ static void initsections(void) {
secaddbyte(shstrtab, 0);
shstrtab->hdr.sh_name = elfstr(shstrtab, ".shstrtab");
shstrtab->hdr.sh_type = SHT_STRTAB;
- shstrtab->hdr.sh_entsize = 1;
strtab = newsection();
secaddbyte(strtab, 0);
strtab->hdr.sh_name = elfstr(shstrtab, ".strtab");
strtab->hdr.sh_type = SHT_STRTAB;
- strtab->hdr.sh_entsize = 1;
symtab = newsection();
symtab->hdr.sh_name = elfstr(shstrtab, ".symtab");
@@ -128,21 +126,18 @@ static void initsections(void) {
bss->hdr.sh_name = elfstr(shstrtab, ".bss");
bss->hdr.sh_type = SHT_NOBITS;
bss->hdr.sh_flags = SHF_ALLOC | SHF_WRITE;
- bss->hdr.sh_entsize = 1;
bss->hdr.sh_addralign = 16; // XXX right value?
data = newsection();
data->hdr.sh_name = elfstr(shstrtab, ".data");
data->hdr.sh_type = SHT_PROGBITS;
data->hdr.sh_flags = SHF_ALLOC | SHF_WRITE;
- data->hdr.sh_entsize = 1;
data->hdr.sh_addralign = 16; // XXX right value?
text = newsection();
text->hdr.sh_name = elfstr(shstrtab, ".text");
text->hdr.sh_type = SHT_PROGBITS;
text->hdr.sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- text->hdr.sh_entsize = 1;
text->hdr.sh_addralign = 4;
textrel = newsection();
@@ -547,7 +542,7 @@ static void assemblexchg(const Instr *xchg) {
rex = (Rex){
.required = isrexreg(xchg->arg1->kind) || isrexreg(xchg->arg2->kind),
.w = isreg64(xchg->arg1->kind) || isreg64(xchg->arg2->kind),
- .r = !!(reg & (1 << 3)),
+ .r = !!(regbits(reg) & (1 << 3)),
};
assembleplusr(rex, prefix, opcode, regbits(reg));
} else {
@@ -1014,6 +1009,12 @@ static void assemble(void) {
assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x07);
break;
}
+ case ASM_ADDSS:
+ assemblerrm(&v->instr, 0xf3, 0x01000f58, 1);
+ break;
+ case ASM_ADDSD:
+ assemblerrm(&v->instr, 0xf2, 0x01000f58, 1);
+ break;
case ASM_DIV:
assembledivmulneg(&v->instr, 0x06);
break;
@@ -1090,6 +1091,12 @@ static void assemble(void) {
assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x05);
break;
}
+ case ASM_SUBSS:
+ assemblerrm(&v->instr, 0xf3, 0x01000f5c, 1);
+ break;
+ case ASM_SUBSD:
+ assemblerrm(&v->instr, 0xf2, 0x01000f5c, 1);
+ break;
case ASM_TEST:
assembletest(&v->instr);
break;
@@ -1129,12 +1136,10 @@ static void addtosymtab(Symbol *sym) {
int stype;
int sbind;
+ stype = 0;
if (sym->defined) {
- stype =
- (sym->section->hdr.sh_flags & SHF_EXECINSTR) ? STT_FUNC : STT_OBJECT;
sbind = sym->global ? STB_GLOBAL : STB_LOCAL;
} else {
- stype = 0;
sbind = STB_GLOBAL;
}
diff --git a/minias.h b/minias.h
index d4b1f48..9ddef20 100644
--- a/minias.h
+++ b/minias.h
@@ -70,6 +70,8 @@ typedef enum {
ASM_JMP,
ASM_LEAVE,
ASM_ADD,
+ ASM_ADDSS,
+ ASM_ADDSD,
ASM_AND,
ASM_CMP,
ASM_CVTSS2SD,
@@ -102,6 +104,8 @@ typedef enum {
ASM_SHL,
ASM_SHR,
ASM_SUB,
+ ASM_SUBSS,
+ ASM_SUBSD,
ASM_TEST,
ASM_UCOMISD,
ASM_UCOMISS,
diff --git a/test/test.sh b/test/test.sh
index 0a89b61..256654e 100644
--- a/test/test.sh
+++ b/test/test.sh
@@ -128,6 +128,32 @@ t "movss %xmm0, %xmm1"
t "movss %xmm10, (%rax)"
t "movss (%rax), %xmm10"
+t "addsd %xmm0, %xmm1"
+t "addsd (%rax), %xmm1"
+t "addsd %xmm10, %xmm1"
+t "addsd %xmm1, %xmm10"
+t "addsd %xmm10, %xmm11"
+t "addsd (%rax), %xmm11"
+t "addss %xmm0, %xmm1"
+t "addss (%rax), %xmm1"
+t "addss %xmm10, %xmm1"
+t "addss %xmm1, %xmm10"
+t "addss %xmm10, %xmm11"
+t "addss (%rax), %xmm11"
+
+t "subsd %xmm0, %xmm1"
+t "subsd (%rax), %xmm1"
+t "subsd %xmm10, %xmm1"
+t "subsd %xmm1, %xmm10"
+t "subsd %xmm10, %xmm11"
+t "subsd (%rax), %xmm11"
+t "subss %xmm0, %xmm1"
+t "subss (%rax), %xmm1"
+t "subss %xmm10, %xmm1"
+t "subss %xmm1, %xmm10"
+t "subss %xmm10, %xmm11"
+t "subss (%rax), %xmm11"
+
t "mulsd %xmm0, %xmm1"
t "mulsd (%rax), %xmm1"
t "mulsd %xmm10, %xmm1"
@@ -270,8 +296,6 @@ t "movb \$127, (%rbp)"
t "movb \$127, 2147483647(%rsp)"
t "movb \$127, 2147483647(%rbp)"
-
-
for x in s z
do
t "mov${x}bw %al, %bx"