Commit d55ba6b0 authored by Christian Würdig's avatar Christian Würdig
Browse files

added 16bit and 8bit register name emits

added comments
parent f3e84222
......@@ -678,7 +678,12 @@ static ia32_isa_t ia32_isa_template = {
&ia32_gp_regs[REG_EBP], /* base pointer register */
-1, /* stack direction */
0, /* number of code generator objects so far */
NULL /* name obstack */
NULL, /* 16bit register names */
NULL, /* 8bit register names */
#ifndef NDEBUG
NULL, /* name obstack */
0 /* name obst size */
#endif
};
/**
......@@ -697,6 +702,12 @@ static void *ia32_init(void) {
ia32_register_init(isa);
ia32_create_opcodes();
isa->regs_16bit = pmap_create();
isa->regs_8bit = pmap_create();
ia32_build_16bit_reg_map(isa->regs_16bit);
ia32_build_8bit_reg_map(isa->regs_8bit);
#ifndef NDEBUG
isa->name_obst = xcalloc(1, sizeof(*(isa->name_obst)));
obstack_init(isa->name_obst);
......@@ -716,6 +727,9 @@ static void *ia32_init(void) {
static void ia32_done(void *self) {
ia32_isa_t *isa = self;
pmap_destroy(isa->regs_16bit);
pmap_destroy(isa->regs_8bit);
#ifndef NDEBUG
//printf("name obst size = %d bytes\n", isa->name_obst_size);
obstack_free(isa->name_obst, NULL);
......
......@@ -34,10 +34,12 @@ typedef struct _ia32_code_gen_t {
typedef struct _ia32_isa_t {
const arch_isa_if_t *impl;
const arch_register_t *sp; /** The stack pointer register. */
const arch_register_t *bp; /** The base pointer register. */
const int stack_dir; /** -1 for decreasing, 1 for increasing. */
int num_codegens;
const arch_register_t *sp; /**< The stack pointer register. */
const arch_register_t *bp; /**< The base pointer register. */
const int stack_dir; /**< -1 for decreasing, 1 for increasing. */
int num_codegens; /**< The number of code generator objects created so far */
pmap *regs_16bit; /**< Contains the 16bits names of the gp registers */
pmap *regs_8bit; /**< Contains the 8bits names of the gp registers */
#ifndef NDEBUG
struct obstack *name_obst; /**< holds the original node names (for debugging) */
unsigned long name_obst_size;
......
......@@ -234,7 +234,7 @@ const lc_arg_env_t *ia32_get_arg_env(void) {
/**
* Emits registers and/or address mode of a binary operation.
*/
char *ia32_emit_binop(const ir_node *n) {
char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
static char *buf = NULL;
/* verify that this function is never called on non-AM supporting operations */
......@@ -266,14 +266,35 @@ char *ia32_emit_binop(const ir_node *n) {
}
break;
case ia32_AddrModeS:
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n));
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n, env));
break;
case ia32_AddrModeD:
if (get_ia32_cnst(n)) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n), get_ia32_cnst(n));
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n, env), get_ia32_cnst(n));
}
else {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %3S", ia32_emit_am(n), n);
const arch_register_t *in1 = get_in_reg(n, 2);
const char *reg_name;
ir_mode *mode = get_ia32_res_mode(n);
mode = mode ? mode : get_ia32_ls_mode(n);
switch(get_mode_size_bits(mode)) {
case 8:
reg_name = ia32_get_mapped_reg_name(env->isa->regs_8bit, in1);
break;
case 16:
reg_name = ia32_get_mapped_reg_name(env->isa->regs_16bit, in1);
break;
case 32:
reg_name = arch_register_get_name(in1);
break;
default:
assert(0 && "unsupported mode size");
break;
}
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n, env), reg_name);
}
break;
default:
......@@ -286,7 +307,7 @@ char *ia32_emit_binop(const ir_node *n) {
/**
* Emits registers and/or address mode of a unary operation.
*/
char *ia32_emit_unop(const ir_node *n) {
char *ia32_emit_unop(const ir_node *n, ia32_emit_env_t *env) {
static char *buf = NULL;
if (! buf) {
......@@ -301,7 +322,7 @@ char *ia32_emit_unop(const ir_node *n) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D", n);
break;
case ia32_am_Dest:
snprintf(buf, SNPRINTF_BUF_LEN, ia32_emit_am(n));
snprintf(buf, SNPRINTF_BUF_LEN, ia32_emit_am(n, env));
break;
default:
assert(0 && "unsupported op type");
......@@ -311,9 +332,9 @@ char *ia32_emit_unop(const ir_node *n) {
}
/**
* Emits adress mode.
* Emits address mode.
*/
char *ia32_emit_am(const ir_node *n) {
char *ia32_emit_am(const ir_node *n, ia32_emit_env_t *env) {
ia32_am_flavour_t am_flav = get_ia32_am_flavour(n);
int had_output = 0;
char *s;
......@@ -532,12 +553,12 @@ static void finish_CondJmp(FILE *F, const ir_node *irn) {
/**
* Emits code for conditional jump.
*/
static void CondJmp_emitter(const ir_node *irn, emit_env_t *env) {
static void CondJmp_emitter(const ir_node *irn, ia32_emit_env_t *env) {
FILE *F = env->out;
char cmd_buf[SNPRINTF_BUF_LEN];
char cmnt_buf[SNPRINTF_BUF_LEN];
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn));
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmp %s", ia32_emit_binop(irn, env));
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
IA32_DO_EMIT;
finish_CondJmp(F, irn);
......@@ -546,14 +567,14 @@ static void CondJmp_emitter(const ir_node *irn, emit_env_t *env) {
/**
* Emits code for conditional jump with two variables.
*/
static void emit_ia32_CondJmp(const ir_node *irn, emit_env_t *env) {
static void emit_ia32_CondJmp(const ir_node *irn, ia32_emit_env_t *env) {
CondJmp_emitter(irn, env);
}
/**
* Emits code for conditional jump with immediate.
*/
void emit_ia32_CondJmp_i(const ir_node *irn, emit_env_t *env) {
void emit_ia32_CondJmp_i(const ir_node *irn, ia32_emit_env_t *env) {
CondJmp_emitter(irn, env);
}
......@@ -604,7 +625,7 @@ static int ia32_cmp_branch_t(const void *a, const void *b) {
* possible otherwise a cmp-jmp cascade). Port from
* cggg ia32 backend
*/
void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
unsigned long interval;
char buf[SNPRINTF_BUF_LEN];
int last_value, i, pn, do_jmp_tbl = 1;
......@@ -743,7 +764,7 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits code for a unconditional jump.
*/
void emit_Jmp(const ir_node *irn, emit_env_t *env) {
void emit_Jmp(const ir_node *irn, ia32_emit_env_t *env) {
FILE *F = env->out;
char buf[SNPRINTF_BUF_LEN], cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
......@@ -768,7 +789,7 @@ void emit_Jmp(const ir_node *irn, emit_env_t *env) {
/**
* Emits code for a proj -> node
*/
void emit_Proj(const ir_node *irn, emit_env_t *env) {
void emit_Proj(const ir_node *irn, ia32_emit_env_t *env) {
ir_node *pred = get_Proj_pred(irn);
if (get_irn_op(pred) == op_Start) {
......@@ -829,7 +850,7 @@ static void emit_CopyB_prolog(FILE *F, int rem, int size) {
/**
* Emit rep movsd instruction for memcopy.
*/
void emit_ia32_CopyB(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_CopyB(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
tarval *tv = get_ia32_Immop_tarval(irn);
int rem = get_tarval_long(tv);
......@@ -846,7 +867,7 @@ void emit_ia32_CopyB(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits unrolled memcopy.
*/
void emit_ia32_CopyB_i(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_CopyB_i(const ir_node *irn, ia32_emit_env_t *emit_env) {
tarval *tv = get_ia32_Immop_tarval(irn);
int size = get_tarval_long(tv);
FILE *F = emit_env->out;
......@@ -877,7 +898,7 @@ void emit_ia32_CopyB_i(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emit code for conversions (I, FP), (FP, I) and (FP, FP).
*/
static void emit_ia32_Conv(const ir_node *irn, emit_env_t *emit_env) {
static void emit_ia32_Conv(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
const lc_arg_env_t *env = ia32_get_arg_env();
char *from, *to, buf[64];
......@@ -895,7 +916,7 @@ static void emit_ia32_Conv(const ir_node *irn, emit_env_t *emit_env) {
lc_esnprintf(env, buf, sizeof(buf), "%1D, %3S", irn, irn);
break;
case ia32_AddrModeS:
lc_esnprintf(env, buf, sizeof(buf), "%1D, %s", irn, ia32_emit_am(irn));
lc_esnprintf(env, buf, sizeof(buf), "%1D, %s", irn, ia32_emit_am(irn, emit_env));
break;
default:
assert(0 && "unsupported op type for Conv");
......@@ -906,15 +927,15 @@ static void emit_ia32_Conv(const ir_node *irn, emit_env_t *emit_env) {
IA32_DO_EMIT;
}
void emit_ia32_Conv_I2FP(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_Conv_I2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
emit_ia32_Conv(irn, emit_env);
}
void emit_ia32_Conv_FP2I(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_Conv_FP2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
emit_ia32_Conv(irn, emit_env);
}
void emit_ia32_Conv_FP2FP(const ir_node *irn, emit_env_t *emit_env) {
void emit_ia32_Conv_FP2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
emit_ia32_Conv(irn, emit_env);
}
......@@ -933,7 +954,7 @@ void emit_ia32_Conv_FP2FP(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits a backend call
*/
void emit_be_Call(const ir_node *irn, emit_env_t *emit_env) {
void emit_be_Call(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
entity *ent = be_Call_get_entity(irn);
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
......@@ -953,7 +974,7 @@ void emit_be_Call(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits code to increase stack pointer.
*/
void emit_be_IncSP(const ir_node *irn, emit_env_t *emit_env) {
void emit_be_IncSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
unsigned offs = be_get_IncSP_offset(irn);
be_stack_dir_t dir = be_get_IncSP_direction(irn);
......@@ -975,7 +996,7 @@ void emit_be_IncSP(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits code to set stack pointer.
*/
void emit_be_SetSP(const ir_node *irn, emit_env_t *emit_env) {
void emit_be_SetSP(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
......@@ -987,7 +1008,7 @@ void emit_be_SetSP(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits code for Copy.
*/
void emit_be_Copy(const ir_node *irn, emit_env_t *emit_env) {
void emit_be_Copy(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
......@@ -999,7 +1020,7 @@ void emit_be_Copy(const ir_node *irn, emit_env_t *emit_env) {
/**
* Emits code for exchange.
*/
void emit_be_Perm(const ir_node *irn, emit_env_t *emit_env) {
void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
......@@ -1063,7 +1084,7 @@ static void ia32_register_emitters(void) {
* Emits code for a node.
*/
static void ia32_emit_node(const ir_node *irn, void *env) {
emit_env_t *emit_env = env;
ia32_emit_env_t *emit_env = env;
firm_dbg_module_t *mod = emit_env->mod;
FILE *F = emit_env->out;
ir_op *op = get_irn_op(irn);
......@@ -1089,7 +1110,7 @@ static void ia32_gen_block(ir_node *block, void *env) {
if (! is_Block(block))
return;
fprintf(((emit_env_t *)env)->out, "BLOCK_%ld:\n", get_irn_node_nr(block));
fprintf(((ia32_emit_env_t *)env)->out, "BLOCK_%ld:\n", get_irn_node_nr(block));
sched_foreach(block, irn) {
ia32_emit_node(irn, env);
}
......@@ -1136,12 +1157,13 @@ static void ia32_gen_labels(ir_node *block, void *env) {
* Main driver. Emits the code for one routine.
*/
void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
emit_env_t emit_env;
ia32_emit_env_t emit_env;
emit_env.mod = firm_dbg_register("ir.be.codegen.ia32");
emit_env.out = F;
emit_env.arch_env = cg->arch_env;
emit_env.cg = cg;
emit_env.isa = (ia32_isa_t *)cg->arch_env->isa;
/* set the global arch_env (needed by print hooks) */
arch_env = cg->arch_env;
......
......@@ -9,18 +9,19 @@
#include "bearch_ia32_t.h"
typedef struct _emit_env_t {
typedef struct _ia32_emit_env_t {
firm_dbg_module_t *mod;
FILE *out;
const arch_env_t *arch_env;
const ia32_code_gen_t *cg;
} emit_env_t;
ia32_isa_t *isa;
} ia32_emit_env_t;
const lc_arg_env_t *ia32_get_arg_env(void);
char *ia32_emit_binop(const ir_node *irn);
char *ia32_emit_unop(const ir_node *irn);
char *ia32_emit_am(const ir_node *irn);
char *ia32_emit_binop(const ir_node *irn, ia32_emit_env_t *env);
char *ia32_emit_unop(const ir_node *irn, ia32_emit_env_t *env);
char *ia32_emit_am(const ir_node *irn, ia32_emit_env_t *env);
int get_ia32_reg_nr(ir_node *irn, int posi, int in_out);
const char *get_ia32_in_reg_name(ir_node *irn, int pos);
......
......@@ -8,6 +8,8 @@
#include <stdlib.h>
#include "pmap.h"
#include "ia32_map_regs.h"
#include "ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
......@@ -95,7 +97,31 @@ const arch_register_t *ia32_get_firm_reg(const ir_node *irn, set *reg_set) {
return assoc->reg;
}
void ia32_build_16bit_reg_map(pmap *reg_map) {
pmap_insert(reg_map, &ia32_gp_regs[REG_EAX], "ax");
pmap_insert(reg_map, &ia32_gp_regs[REG_EBX], "bx");
pmap_insert(reg_map, &ia32_gp_regs[REG_ECX], "cx");
pmap_insert(reg_map, &ia32_gp_regs[REG_EDX], "dx");
pmap_insert(reg_map, &ia32_gp_regs[REG_ESI], "si");
pmap_insert(reg_map, &ia32_gp_regs[REG_EDI], "di");
pmap_insert(reg_map, &ia32_gp_regs[REG_EBP], "bp");
pmap_insert(reg_map, &ia32_gp_regs[REG_ESP], "sp");
}
void ia32_build_8bit_reg_map(pmap *reg_map) {
pmap_insert(reg_map, &ia32_gp_regs[REG_EAX], "al");
pmap_insert(reg_map, &ia32_gp_regs[REG_EBX], "bl");
pmap_insert(reg_map, &ia32_gp_regs[REG_ECX], "cl");
pmap_insert(reg_map, &ia32_gp_regs[REG_EDX], "dl");
}
char *ia32_get_mapped_reg_name(pmap *reg_map, const arch_register_t *reg) {
pmap_entry *e = pmap_find(reg_map, (void *)reg);
assert(e && "missing map init?");
return e->value;
}
/**
* Check all parameters and determine the maximum number of parameters
......
......@@ -15,15 +15,65 @@
((arch_register_get_class(out) == arch_register_get_class(in)) && \
(arch_register_get_index(out) == arch_register_get_index(in)))
/**
* Set compare function
*/
int ia32_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
/**
* Assigns a register to a firm node.
*/
void ia32_set_firm_reg(ir_node *irn, const arch_register_t *reg, set *reg_set);
/**
* Gets the register assigned to a firm node.
*/
const arch_register_t *ia32_get_firm_reg(const ir_node *irn, set *reg_set);
/**
* Enters for each general purpose register the corresponding 16bit
* name into a pmap.
*/
void ia32_build_16bit_reg_map(pmap *reg_map);
/**
* Enters for each general purpose register the corresponding 8bit
* name into a pmap.
*/
void ia32_build_8bit_reg_map(pmap *reg_map);
/**
* Returns the corresponding mapped name for a register.
*/
char *ia32_get_mapped_reg_name(pmap *reg_map, const arch_register_t *reg);
/**
* Check all parameters and determine the maximum number of parameters
* to pass in gp regs resp. in fp regs.
*
* @param n The number of parameters
* @param modes The list of the parameter modes
* @param n_int Holds the number of int parameters to be passed in regs after the call
* @param n_float Holds the number of float parameters to be passed in regs after the call
* @return The number of the last parameter to be passed in register
*/
int ia32_get_n_regparam_class(int n, ir_mode **modes, int *n_int, int *n_float);
/**
* Returns the register for parameter nr.
*
* @param n The number of parameters
* @param modes The list of the parameter modes
* @param nr The number of the parameter to return the requirements for
* @param cc The calling convention
* @return The register
*/
const arch_register_t *ia32_get_RegParam_reg(int n, ir_mode **modes, long nr, unsigned cc);
/**
* Translates the projnum into a "real" argument position for register
* requirements dependent on the predecessor.
*/
long ia32_translate_proj_pos(const ir_node *proj);
#endif /* _IA32_MAP_REGS_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment