Added x64 instructions.

This commit is contained in:
Christoffer Lerno
2022-09-13 22:09:44 +02:00
committed by Christoffer Lerno
parent 0805750f52
commit fa51402a16
5 changed files with 99 additions and 5 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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))

View 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}"

View 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}"