mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Feat/asm x86 (#1046)
* 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
This commit is contained in:
@@ -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");
|
||||
@@ -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}";
|
||||
|
||||
@@ -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;
|
||||
@@ -1415,4 +1416,4 @@ Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool require_eos)
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.682"
|
||||
#define COMPILER_VERSION "0.4.683"
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
test/test_suite/asm/syscall.c3t
Normal file
17
test/test_suite/asm/syscall.c3t
Normal file
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user