Files
rifle/backend/x86_64.c
2026-02-23 13:56:24 -05:00

126 lines
2.1 KiB
C

#include <stdio.h>
#include "rifle/mu.h"
#define retreg(msize) \
((msize) >= MSIZE_MAX) \
? "bad" \
: rettab[(msize)]
#define secname(secid) \
((secid) >= SECTION_MAX) \
? "bad" \
: secttab[(secid)]
/* Size to return register table */
static const char *rettab[] = {
[MSIZE_BYTE] = "al",
[MSIZE_WORD] = "ax",
[MSIZE_DWORD] = "eax",
[MSIZE_QWORD] = "rax"
};
/* Section ID to name table */
static const char *secttab[] = {
[SECTION_NONE] = ".none",
[SECTION_TEXT] = ".text",
[SECTION_DATA] = ".data",
[SECTION_RODATA] = ".rodata",
[SECTION_BSS] = ".bss"
};
static inline void
force_section(struct rifle_state *state, section_t section)
{
if (state == NULL) {
return;
}
if (state->section != section) {
state->section = section;
fprintf(
state->out_fp,
"[section %s]\n",
secname(section)
);
}
}
int
mu_gen_label(struct rifle_state *state, section_t section, const char *name,
bool global)
{
if (state == NULL || name == NULL) {
return -1;
}
if (global) {
fprintf(
state->out_fp,
"[global %s]\n",
name
);
}
force_section(state, section);
fprintf(
state->out_fp,
"%s:\n",
name
);
return 0;
}
int
mu_gen_retimm(struct rifle_state *state, ssize_t v, msize_t size)
{
if (state == NULL) {
return -1;
}
if (size >= MSIZE_MAX) {
return -1;
}
fprintf(
state->out_fp,
INST("mov %s, %zd")
INST("ret"),
retreg(size),
v
);
return 0;
}
int
mu_gen_ret(struct rifle_state *state)
{
if (state == NULL) {
return -1;
}
fprintf(
state->out_fp,
INST("ret")
);
return 0;
}
int
mu_gen_blab(struct rifle_state *state, const char *name)
{
if (state == NULL || name == NULL) {
return -1;
}
fprintf(
state->out_fp,
INST("jmp %s"),
name
);
return 0;
}