Skip to content

Commit

Permalink
Feat/asm x86 (#1046)
Browse files Browse the repository at this point in the history
* fix(asm): consider asm blocks as volatile
When asm blocks are not marked as volatile, they may be (wrongly)
discarded by LLVM optimization passes.
* fix(asm): mark syscall as clobbering return register
The `syscall` instruction returns the system call result in the `rax`
register.
* feat(asm): add push instructions.
* feat(asm): add pop instructions
  • Loading branch information
pinicarus authored Oct 14, 2023
1 parent 682dfd0 commit 76fa404
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 7 deletions.
9 changes: 8 additions & 1 deletion src/compiler/asm_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,14 @@ static void init_asm_x86(void)
{
reg_instr_clob("aaa", rax_mask, 0);
reg_instr_clob("into", cc_flag_mask, NULL);
reg_instr("pushl", "r32/mem/imm32");
reg_instr("popl", "w:r32/mem/imm32");
}
if (is_x64)
{
reg_instr_clob("syscall", clobbers_make_from(cc_flag_mask, X86_R11, X86_RCX, -1), NULL);
reg_instr_clob("syscall", clobbers_make_from(cc_flag_mask, X86_RAX, X86_R11, X86_RCX, -1), NULL);
reg_instr("pushq", "r64/mem");
reg_instr("popq", "w:r64/mem");
}
reg_instr_clob("adcb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8");
reg_instr_clob("adcw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16/immi8");
Expand Down Expand Up @@ -404,6 +408,9 @@ static void init_asm_x86(void)
reg_instr("rdtsc", NULL);
reg_instr("rdtscp", NULL);
reg_instr("ret", NULL);
reg_instr("push", "imm8");
reg_instr("pushw", "r16/mem/imm16");
reg_instr("popw", "w:r16/mem");

asm_target.clobber_name_list = X86ClobberNames;
asm_target.extra_clobbers = "~{flags},~{dirflag},~{fspr}";
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/parse_stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ static inline Ast* parse_asm_block_stmt(ParseContext *c)
prev = &block_stmt->next;
}
ast->asm_block_stmt.block = block;
ast->asm_block_stmt.is_volatile = true;
return ast;
}
ast->asm_block_stmt.is_string = true;
Expand Down Expand Up @@ -1415,4 +1416,4 @@ Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool require_eos)
CONSUME_EOS_OR_RET(poisoned_ast);
}
return ast;
}
}
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define COMPILER_VERSION "0.4.682"
#define COMPILER_VERSION "0.4.683"
10 changes: 9 additions & 1 deletion test/test_suite/asm/asm_ops_x64_1.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,17 @@ fn void main(String[] args)
iretl;
iretw;
iretq;
push 1;
pushw 2;
pushw $ax;
pushw [&x];
pushq $rax;
pushq [&x];
popw $ax;
popq $rax;
}
}

/* #expect: test.ll

"in $$3, %eax\0Ain %dx, %ax\0Aincb %al\0Aincw %bx\0Aincl %eax\0Aincq %rax\0Aincl $0\0Ainsb \0Ainsw \0Ainsl \0Aint $$8\0Aint3 \0Ainvd \0Ainvlpg $0\0Ainvpcid $1, %rax\0Ainvlpga %rax, %ecx\0Airet \0Airetl \0Airetw \0Airetq \0A", "=*&m,*m,~{cc},~{rax},~{rbx},~{flags},~{dirflag},~{fspr}"
"in $$3, %eax\0Ain %dx, %ax\0Aincb %al\0Aincw %bx\0Aincl %eax\0Aincq %rax\0Aincl $0\0Ainsb \0Ainsw \0Ainsl \0Aint $$8\0Aint3 \0Ainvd \0Ainvlpg $0\0Ainvpcid $1, %rax\0Ainvlpga %rax, %ecx\0Airet \0Airetl \0Airetw \0Airetq \0Apush $$1\0Apushw $$2\0Apushw %ax\0Apushw $1\0Apushq %rax\0Apushq $1\0Apopw %ax\0Apopq %rax\0A", "=*&m,*m,~{cc},~{rax},~{rbx},~{flags},~{dirflag},~{fspr}"
4 changes: 2 additions & 2 deletions test/test_suite/asm/asm_regression.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ fn void main()
%7 = load i32, ptr %x, align 4
%add3 = add i32 23, %7
%8 = load i32, ptr %aa, align 4
%9 = call { i32, i32 } asm alignstack "movl $$4, $0\0Amovl $0, ($3)\0Amovl $$1, $0\0Amovl $0, 4($4,$5,4)\0Amovl $6, %eax\0Amovl %eax, $0\0Amovq $$33, $1\0Aaddl $$22, $2\0A", "=&r,=*&m,=r,r,r,r,r,2,~{cc},~{rax},~{flags},~{dirflag},~{fspr}"(ptr elementtype(i64) %z, ptr %4, ptr %5, i64 %6, i32 %add3, i32 %8)
%9 = call { i32, i32 } asm sideeffect alignstack "movl $$4, $0\0Amovl $0, ($3)\0Amovl $$1, $0\0Amovl $0, 4($4,$5,4)\0Amovl $6, %eax\0Amovl %eax, $0\0Amovq $$33, $1\0Aaddl $$22, $2\0A", "=&r,=*&m,=r,r,r,r,r,2,~{cc},~{rax},~{flags},~{dirflag},~{fspr}"(ptr elementtype(i64) %z, ptr %4, ptr %5, i64 %6, i32 %add3, i32 %8)
%10 = extractvalue { i32, i32 } %9, 0
store i32 %10, ptr %x, align 4
%11 = extractvalue { i32, i32 } %9, 1
store i32 %11, ptr %aa, align 4
store i32 %11, ptr %aa, align 4
2 changes: 1 addition & 1 deletion test/test_suite/asm/naked.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn void start() @export("_start") @naked @nostrip {

define void @_start() #0 {
entry:
call void asm alignstack "movq $$60, %rax\0Amovq $$42, %rdi\0Asyscall \0A", "~{cc},~{rax},~{rcx},~{r8},~{r11},~{flags},~{dirflag},~{fspr}"()
call void asm sideeffect alignstack "movq $$60, %rax\0Amovq $$42, %rdi\0Asyscall \0A", "~{cc},~{rax},~{rcx},~{r8},~{r11},~{flags},~{dirflag},~{fspr}"()
ret void
}

17 changes: 17 additions & 0 deletions test/test_suite/asm/syscall.c3t
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// #target: macos-x64
module testing;

fn void start() @export("_start") @naked @nostrip {
asm {
syscall;
}
}

/* #expect: testing.ll

define void @_start() #0 {
entry:
call void asm sideeffect alignstack "syscall \0A", "~{cc},~{rax},~{rcx},~{r11},~{flags},~{dirflag},~{fspr}"()
ret void
}

0 comments on commit 76fa404

Please sign in to comment.