mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Added x64 instructions.
This commit is contained in:
committed by
Christoffer Lerno
parent
0805750f52
commit
fa51402a16
@@ -5,7 +5,7 @@
|
||||
#include "compiler/asm/x86.h"
|
||||
#include "compiler/asm/aarch64.h"
|
||||
|
||||
#define ASM_PTR_HASH(name__) (uint32_t)(((uintptr_t)name__ >> 9) ^ ((uintptr_t)name__ >> 1))
|
||||
#define ASM_PTR_HASH(name__) (uint32_t)(((uintptr_t)name__ * 31) ^ ((uintptr_t)name__ >> 15))
|
||||
|
||||
const Clobbers NO_CLOBBER = { .mask[0] = 0 };
|
||||
|
||||
@@ -178,6 +178,7 @@ INLINE void reg_register(const char *name, AsmRegisterType reg_type, AsmArgBits
|
||||
if (!reg->name)
|
||||
{
|
||||
*reg = (AsmRegister) { .name = interned, .type = reg_type, .bits = bits, .clobber_index = clobber_id };
|
||||
asm_target.register_count++;
|
||||
return;
|
||||
}
|
||||
slot = (slot + 1) & ASM_REGISTER_MASK;
|
||||
@@ -284,7 +285,6 @@ static void init_asm_x86(void)
|
||||
if (!is_x64)
|
||||
{
|
||||
reg_instr_clob("aaa", rax_mask, 0);
|
||||
reg_instr("int", "imm8");
|
||||
reg_instr_clob("into", cc_flag_mask, NULL);
|
||||
}
|
||||
if (is_x64)
|
||||
@@ -356,6 +356,27 @@ static void init_asm_x86(void)
|
||||
reg_instr_clob("subl", rax_cc_mask, "rw:r32/mem, r32/mem/imm32");
|
||||
reg_instr_clob("subq", rax_cc_mask, "rw:r64/mem, r64/mem/immi32/imm64");
|
||||
reg_instr("hlt", NULL);
|
||||
reg_instr("in", "w:r8/r16/r32, r16/imm8"); // Actually ensure reg_al_ax and dx
|
||||
reg_instr_clob("incb", cc_flag_mask, "rw:r8/mem");
|
||||
reg_instr_clob("incw", cc_flag_mask, "rw:r16/mem");
|
||||
reg_instr_clob("incl", cc_flag_mask, "rw:r32/mem");
|
||||
reg_instr_clob("incq", cc_flag_mask, "rw:r64/mem");
|
||||
reg_instr("insb", NULL);
|
||||
reg_instr("insw", NULL);
|
||||
reg_instr("insl", NULL);
|
||||
reg_instr_clob("int", cc_flag_mask, "imm8");
|
||||
reg_instr_clob("int3", cc_flag_mask, NULL);
|
||||
reg_instr_clob("int1", cc_flag_mask, NULL);
|
||||
reg_instr("invd", NULL);
|
||||
reg_instr("invpcid", "r32/r64, mem");
|
||||
reg_instr("invlpg", "w:mem");
|
||||
reg_instr("invlpga", "r32, r64"); // c, a check this one!
|
||||
reg_instr("iret", NULL);
|
||||
reg_instr("iretl", NULL);
|
||||
reg_instr("iretw", NULL);
|
||||
reg_instr("iretq", NULL);
|
||||
reg_instr("ret", NULL);
|
||||
|
||||
asm_target.clobber_name_list = X86ClobberNames;
|
||||
asm_target.extra_clobbers = "~{flags},~{dirflag},~{fspr}";
|
||||
if (platform_target.arch == ARCH_TYPE_X86)
|
||||
|
||||
@@ -162,7 +162,7 @@ typedef struct
|
||||
|
||||
#define ASM_INSTRUCTION_MAX 0x1000
|
||||
#define ASM_INSTRUCTION_MASK (ASM_INSTRUCTION_MAX - 1)
|
||||
#define ASM_REGISTER_MAX 1024
|
||||
#define ASM_REGISTER_MAX 4096
|
||||
#define ASM_REGISTER_MASK (ASM_REGISTER_MAX - 1)
|
||||
|
||||
typedef struct
|
||||
@@ -172,6 +172,7 @@ typedef struct
|
||||
const char *extra_clobbers;
|
||||
AsmRegister registers[ASM_REGISTER_MAX];
|
||||
AsmInstruction instructions[ASM_INSTRUCTION_MAX];
|
||||
unsigned register_count;
|
||||
} AsmTarget;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -254,13 +254,13 @@ static inline Expr *parse_asm_expr(ParseContext *c)
|
||||
static inline Ast *parse_asm_stmt(ParseContext *c)
|
||||
{
|
||||
Ast *asm_stmt = ast_new_curr(c, AST_ASM_STMT);
|
||||
if (!tok_is(c, TOKEN_IDENT))
|
||||
if (!tok_is(c, TOKEN_IDENT) && !tok_is(c, TOKEN_INT))
|
||||
{
|
||||
SEMA_ERROR_HERE("Expected an asm instruction here.");
|
||||
return poisoned_ast;
|
||||
}
|
||||
asm_stmt->asm_stmt.instruction = symstr(c);
|
||||
advance_and_verify(c, TOKEN_IDENT);
|
||||
advance(c);
|
||||
if (try_consume(c, TOKEN_DOT))
|
||||
{
|
||||
if (!tok_is(c, TOKEN_IDENT))
|
||||
|
||||
36
test/test_suite/asm/asm_ops_x64_1.c3t
Normal file
36
test/test_suite/asm/asm_ops_x64_1.c3t
Normal file
@@ -0,0 +1,36 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
fn void main(char[][] args)
|
||||
{
|
||||
int x;
|
||||
if (args.len < 10) return;
|
||||
asm
|
||||
{
|
||||
in $eax, 3;
|
||||
in $ax, $dx;
|
||||
incb $al;
|
||||
incw $bx;
|
||||
incl $eax;
|
||||
incq $rax;
|
||||
incl [&x];
|
||||
insb;
|
||||
insw;
|
||||
insl;
|
||||
int 0x08;
|
||||
int3;
|
||||
// int1; Broken in LLVM
|
||||
invd;
|
||||
invlpg [&x];
|
||||
invpcid $rax, [&x];
|
||||
invlpga $ecx, $rax;
|
||||
iret;
|
||||
iretl;
|
||||
iretw;
|
||||
iretq;
|
||||
}
|
||||
}
|
||||
|
||||
/* #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}"
|
||||
36
test/test_suite2/asm/asm_ops_x64_1.c3t
Normal file
36
test/test_suite2/asm/asm_ops_x64_1.c3t
Normal file
@@ -0,0 +1,36 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
fn void main(char[][] args)
|
||||
{
|
||||
int x;
|
||||
if (args.len < 10) return;
|
||||
asm
|
||||
{
|
||||
in $eax, 3;
|
||||
in $ax, $dx;
|
||||
incb $al;
|
||||
incw $bx;
|
||||
incl $eax;
|
||||
incq $rax;
|
||||
incl [&x];
|
||||
insb;
|
||||
insw;
|
||||
insl;
|
||||
int 0x08;
|
||||
int3;
|
||||
// int1; Broken in LLVM
|
||||
invd;
|
||||
invlpg [&x];
|
||||
invpcid $rax, [&x];
|
||||
invlpga $ecx, $rax;
|
||||
iret;
|
||||
iretl;
|
||||
iretw;
|
||||
iretq;
|
||||
}
|
||||
}
|
||||
|
||||
/* #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}"
|
||||
Reference in New Issue
Block a user