Commit 7081df40 authored by Matthias Braun's avatar Matthias Braun
Browse files

add encoding field to register

The encoding field specifies the register number used when encoding an
instruction as machine code (and not as assembly)
parent 5c607398
......@@ -218,6 +218,8 @@ struct arch_register_t {
const arch_register_req_t *single_req;
/** register number in dwarf debugging format */
unsigned short dwarf_number;
/** register number in instruction encoding */
unsigned short encoding;
};
/**
......
......@@ -1745,22 +1745,6 @@ static const lc_opt_table_entry_t ia32_emitter_options[] = {
/* ==== Experimental binary emitter ==== */
static unsigned char reg_gp_map[N_ia32_gp_REGS];
//static unsigned char reg_mmx_map[N_ia32_mmx_REGS];
//static unsigned char reg_sse_map[N_ia32_xmm_REGS];
static void build_reg_map(void)
{
reg_gp_map[REG_GP_EAX] = 0x0;
reg_gp_map[REG_GP_ECX] = 0x1;
reg_gp_map[REG_GP_EDX] = 0x2;
reg_gp_map[REG_GP_EBX] = 0x3;
reg_gp_map[REG_GP_ESP] = 0x4;
reg_gp_map[REG_GP_EBP] = 0x5;
reg_gp_map[REG_GP_ESI] = 0x6;
reg_gp_map[REG_GP_EDI] = 0x7;
}
/** Returns the encoding for a pnc field. */
static unsigned char pnc2cc(ia32_condition_code_t cc)
{
......@@ -1877,8 +1861,8 @@ static void bemit_modrr(const arch_register_t *src1,
const arch_register_t *src2)
{
unsigned char modrm = MOD_REG;
modrm |= ENC_RM(reg_gp_map[src1->index]);
modrm |= ENC_REG(reg_gp_map[src2->index]);
modrm |= ENC_RM(src1->encoding);
modrm |= ENC_REG(src2->encoding);
bemit8(modrm);
}
......@@ -1887,8 +1871,8 @@ static void bemit_modrr8(reg_modifier_t high_part1, const arch_register_t *src1,
reg_modifier_t high_part2, const arch_register_t *src2)
{
unsigned char modrm = MOD_REG;
modrm |= ENC_RM(reg_gp_map[src1->index] + (high_part1 == REG_HIGH ? 4 : 0));
modrm |= ENC_REG(reg_gp_map[src2->index] + (high_part2 == REG_HIGH ? 4 : 0));
modrm |= ENC_RM(src1->encoding + (high_part1 == REG_HIGH ? 4 : 0));
modrm |= ENC_REG(src2->encoding + (high_part2 == REG_HIGH ? 4 : 0));
bemit8(modrm);
}
......@@ -1897,7 +1881,7 @@ static void bemit_modru(const arch_register_t *reg, unsigned ext)
{
unsigned char modrm = MOD_REG;
assert(ext <= 7);
modrm |= ENC_RM(reg_gp_map[reg->index]);
modrm |= ENC_RM(reg->encoding);
modrm |= ENC_REG(ext);
bemit8(modrm);
}
......@@ -1906,8 +1890,8 @@ static void bemit_modru(const arch_register_t *reg, unsigned ext)
static void bemit_modrm8(reg_modifier_t high_part, const arch_register_t *reg)
{
unsigned char modrm = MOD_REG;
assert(reg_gp_map[reg->index] < 4);
modrm |= ENC_RM(reg_gp_map[reg->index] + (high_part == REG_HIGH ? 4 : 0));
assert(reg->encoding < 4);
modrm |= ENC_RM(reg->encoding + (high_part == REG_HIGH ? 4 : 0));
modrm |= MOD_REG;
bemit8(modrm);
}
......@@ -1965,7 +1949,7 @@ static void bemit_mod_am(unsigned reg, const ir_node *node)
if (has_base) {
const arch_register_t *base_reg = arch_get_irn_register(base);
base_enc = reg_gp_map[base_reg->index];
base_enc = base_reg->encoding;
} else {
/* Use the EBP encoding + MOD_IND if NO base register. There is
* always a 32bit offset present in this case. */
......@@ -1981,7 +1965,7 @@ static void bemit_mod_am(unsigned reg, const ir_node *node)
assert(scale < 4);
/* R/M set to ESP means SIB in 32bit mode. */
modrm |= ENC_RM(0x04);
sib = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
sib = ENC_SIB(scale, reg_index->encoding, base_enc);
emitsib = true;
} else if (base_enc == 0x04) {
/* for the above reason we are forced to emit a SIB when base is ESP.
......@@ -2032,7 +2016,7 @@ static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ex
static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
{
const arch_register_t *out = arch_get_irn_register_out(node, 0);
bemit_unop(node, code, reg_gp_map[out->index], input);
bemit_unop(node, code, out->encoding, input);
}
static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
......@@ -2082,9 +2066,9 @@ static void bemit_perm(const ir_node *node)
if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
if (reg0->index == REG_GP_EAX) {
bemit8(0x90 + reg_gp_map[reg1->index]);
bemit8(0x90 + reg1->encoding);
} else if (reg1->index == REG_GP_EAX) {
bemit8(0x90 + reg_gp_map[reg0->index]);
bemit8(0x90 + reg0->encoding);
} else {
bemit8(0x87);
bemit_modrr(reg0, reg1);
......@@ -2111,7 +2095,7 @@ static void bemit_xor0(const ir_node *node)
static void bemit_mov_const(const ir_node *node)
{
const arch_register_t *out = arch_get_irn_register_out(node, 0);
bemit8(0xB8 + reg_gp_map[out->index]);
bemit8(0xB8 + out->encoding);
bemit_immediate(node, false);
}
......@@ -2163,7 +2147,7 @@ static void bemit_binop(ir_node const *const node, unsigned const code)
arch_register_t const *const src = arch_get_irn_register(right);
bemit_modrr(src, dst);
} else {
bemit_mod_am(reg_gp_map[dst->index], node);
bemit_mod_am(dst->encoding, node);
}
}
}
......@@ -2215,7 +2199,7 @@ static void bemit_binop_mem(ir_node const *const node, unsigned const code)
}
} else {
bemit8(code << 3 | op);
bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node);
bemit_mod_am(arch_get_irn_register(val)->encoding, node);
}
}
......@@ -2335,7 +2319,7 @@ static void bemit_shrd(const ir_node *node)
static void bemit_sbb0(ir_node const *const node)
{
arch_register_t const *const out = arch_get_irn_register_out(node, pn_ia32_Sbb0_res);
unsigned char const reg = reg_gp_map[out->index];
unsigned char const reg = out->encoding;
bemit8(0x1B);
bemit8(MOD_REG | ENC_REG(reg) | ENC_RM(reg));
}
......@@ -2460,7 +2444,7 @@ static void bemit_cmovcc(const ir_node *node)
if (get_ia32_op_type(node) == ia32_Normal) {
bemit_modrr(in_true, out);
} else {
bemit_mod_am(reg_gp_map[out->index], node);
bemit_mod_am(out->encoding, node);
}
}
......@@ -2502,7 +2486,7 @@ static void bemit_test(ir_node const *const node)
arch_register_t const *const src = arch_get_irn_register(right);
bemit_modrr(src, dst);
} else {
bemit_mod_am(reg_gp_map[dst->index], node);
bemit_mod_am(dst->encoding, node);
}
}
}
......@@ -2528,13 +2512,13 @@ static void bemit_imul(const ir_node *node)
static void bemit_dec(const ir_node *node)
{
const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Dec_res);
bemit8(0x48 + reg_gp_map[out->index]);
bemit8(0x48 + out->encoding);
}
static void bemit_inc(const ir_node *node)
{
const arch_register_t *out = arch_get_irn_register_out(node, pn_ia32_Inc_res);
bemit8(0x40 + reg_gp_map[out->index]);
bemit8(0x40 + out->encoding);
}
#define UNOPMEM(op, code, ext) \
......@@ -2557,7 +2541,7 @@ static void bemit_ldtls(const ir_node *node)
bemit8(0xA1); // movl 0, %eax
} else {
bemit8(0x8B); // movl 0, %reg
bemit8(MOD_IND | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x05));
bemit8(MOD_IND | ENC_REG(out->encoding) | ENC_RM(0x05));
}
bemit32(0);
}
......@@ -2569,7 +2553,7 @@ static void bemit_lea(const ir_node *node)
{
const arch_register_t *out = arch_get_irn_register_out(node, 0);
bemit8(0x8D);
bemit_mod_am(reg_gp_map[out->index], node);
bemit_mod_am(out->encoding, node);
}
/* helper function for bemit_minus64bit */
......@@ -2605,9 +2589,9 @@ static void bemit_helper_sbb(const arch_register_t *src, const arch_register_t *
static void bemit_helper_xchg(const arch_register_t *src, const arch_register_t *dst)
{
if (src->index == REG_GP_EAX) {
bemit8(0x90 + reg_gp_map[dst->index]); // xchgl %eax, %dst
bemit8(0x90 + dst->encoding); // xchgl %eax, %dst
} else if (dst->index == REG_GP_EAX) {
bemit8(0x90 + reg_gp_map[src->index]); // xchgl %src, %eax
bemit8(0x90 + src->encoding); // xchgl %src, %eax
} else {
bemit8(0x87); // xchgl %src, %dst
bemit_modrr(src, dst);
......@@ -2730,7 +2714,7 @@ static void bemit_load(const ir_node *node)
}
}
bemit8(0x8B);
bemit_mod_am(reg_gp_map[out->index], node);
bemit_mod_am(out->encoding, node);
}
/**
......@@ -2788,7 +2772,7 @@ static void bemit_store(const ir_node *node)
bemit8(0x66);
bemit8(0x89);
}
bemit_mod_am(reg_gp_map[in->index], node);
bemit_mod_am(in->encoding, node);
}
}
......@@ -2839,7 +2823,7 @@ static void bemit_push(const ir_node *node)
bemit_mod_am(6, node);
} else {
const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_Push_val);
bemit8(0x50 + reg_gp_map[reg->index]);
bemit8(0x50 + reg->encoding);
}
}
......@@ -2849,7 +2833,7 @@ static void bemit_push(const ir_node *node)
static void bemit_pop(const ir_node *node)
{
const arch_register_t *reg = arch_get_irn_register_out(node, pn_ia32_Pop_res);
bemit8(0x58 + reg_gp_map[reg->index]);
bemit8(0x58 + reg->encoding);
}
static void bemit_popmem(const ir_node *node)
......@@ -2986,7 +2970,7 @@ static void bemit_subsp(const ir_node *node)
/* mov %esp, %out */
bemit8(0x8B);
out = arch_get_irn_register_out(node, 1);
bemit8(MOD_REG | ENC_REG(reg_gp_map[out->index]) | ENC_RM(0x04));
bemit8(MOD_REG | ENC_REG(out->encoding) | ENC_RM(0x04));
}
static void bemit_incsp(const ir_node *node)
......@@ -3047,7 +3031,7 @@ static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsig
if (attr->pop) op0 |= 0x02;
bemit8(op0);
bemit8(MOD_REG | ENC_REG(op) | ENC_RM(attr->reg->index));
bemit8(MOD_REG | ENC_REG(op) | ENC_RM(attr->reg->encoding));
} else {
assert(!attr->reg);
assert(!attr->pop);
......@@ -3061,7 +3045,7 @@ static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsig
static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
{
bemit8(op0);
bemit8(op1 + get_ia32_x87_attr_const(node)->reg->index);
bemit8(op1 + get_ia32_x87_attr_const(node)->reg->encoding);
}
static void bemit_fabs(const ir_node *node)
......@@ -3258,14 +3242,14 @@ static void bemit_fucomi(const ir_node *node)
{
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(attr->pop ? 0xDF : 0xDB); // fucom[p]i
bemit8(0xE8 + attr->reg->index);
bemit8(0xE8 + attr->reg->encoding);
}
static void bemit_fucomfnstsw(const ir_node *node)
{
const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
bemit8(0xDD); // fucom[p]
bemit8((attr->pop ? 0xE8 : 0xE0) + attr->reg->index);
bemit8((attr->pop ? 0xE8 : 0xE0) + attr->reg->encoding);
bemit_fnstsw();
}
......@@ -3464,7 +3448,5 @@ void ia32_init_emitter(void)
lc_opt_add_table(ia32_grp, ia32_emitter_options);
build_reg_map();
FIRM_DBG_REGISTER(dbg, "firm.be.ia32.emitter");
}
......@@ -11,14 +11,14 @@ $mode_fpcw = "ia32_mode_fpcw";
%reg_classes = (
gp => [
{ name => "edx", dwarf => 2 },
{ name => "ecx", dwarf => 1 },
{ name => "eax", dwarf => 0 },
{ name => "ebx", dwarf => 3 },
{ name => "esi", dwarf => 6 },
{ name => "edi", dwarf => 7 },
{ name => "ebp", dwarf => 5 },
{ name => "esp", dwarf => 4, type => "ignore" },
{ name => "edx", encoding => 2, dwarf => 2 },
{ name => "ecx", encoding => 1, dwarf => 1 },
{ name => "eax", encoding => 0, dwarf => 0 },
{ name => "ebx", encoding => 3, dwarf => 3 },
{ name => "esi", encoding => 6, dwarf => 6 },
{ name => "edi", encoding => 7, dwarf => 7 },
{ name => "ebp", encoding => 5, dwarf => 5 },
{ name => "esp", encoding => 4, dwarf => 4, type => "ignore" },
{ name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
{ mode => $mode_gp }
],
......@@ -46,14 +46,14 @@ $mode_fpcw = "ia32_mode_fpcw";
{ mode => $mode_xmm }
],
fp => [
{ name => "st0", realname => "st", dwarf => 11 },
{ name => "st1", realname => "st(1)", dwarf => 12 },
{ name => "st2", realname => "st(2)", dwarf => 13 },
{ name => "st3", realname => "st(3)", dwarf => 14 },
{ name => "st4", realname => "st(4)", dwarf => 15 },
{ name => "st5", realname => "st(5)", dwarf => 16 },
{ name => "st6", realname => "st(6)", dwarf => 17 },
{ name => "st7", realname => "st(7)", dwarf => 18 },
{ name => "st0", realname => "st", encoding => 0, dwarf => 11 },
{ name => "st1", realname => "st(1)", encoding => 1, dwarf => 12 },
{ name => "st2", realname => "st(2)", encoding => 2, dwarf => 13 },
{ name => "st3", realname => "st(3)", encoding => 3, dwarf => 14 },
{ name => "st4", realname => "st(4)", encoding => 4, dwarf => 15 },
{ name => "st5", realname => "st(5)", encoding => 5, dwarf => 16 },
{ name => "st6", realname => "st(6)", encoding => 6, dwarf => 17 },
{ name => "st7", realname => "st(7)", encoding => 7, dwarf => 18 },
{ name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
{ mode => $mode_fp87 }
],
......
......@@ -166,6 +166,10 @@ EOF
if (defined($_->{dwarf})) {
$dwarf_number = $_->{dwarf};
}
my $encoding = "REG_${classuc}_${ucname}";
if (defined($_->{encoding})) {
$encoding = $_->{encoding};
}
$regtypes_def .= <<EOF;
{
......@@ -175,7 +179,8 @@ EOF
REG_${ucname},
${type},
&${arch}_single_reg_req_${old_classname}_${name},
${dwarf_number}
${dwarf_number},
${encoding}
},
EOF
......
......@@ -14,41 +14,41 @@ $mode_fp4 = "mode_Q";
gp => [
# Note: locals come first here since they're usually constrained last
# (by calls and others)
{ name => "l0", dwarf => 16 },
{ name => "l1", dwarf => 17 },
{ name => "l2", dwarf => 18 },
{ name => "l3", dwarf => 19 },
{ name => "l4", dwarf => 20 },
{ name => "l5", dwarf => 21 },
{ name => "l6", dwarf => 22 },
{ name => "l7", dwarf => 23 },
{ name => "g0", dwarf => 0 },
{ name => "g1", dwarf => 1 },
{ name => "g2", dwarf => 2 },
{ name => "g3", dwarf => 3 },
{ name => "g4", dwarf => 4 },
{ name => "g5", dwarf => 5 },
{ name => "g6", dwarf => 6 },
{ name => "g7", dwarf => 7 },
{ name => "o0", dwarf => 8 },
{ name => "o1", dwarf => 9 },
{ name => "o2", dwarf => 10 },
{ name => "o3", dwarf => 11 },
{ name => "o4", dwarf => 12 },
{ name => "o5", dwarf => 13 },
{ name => "sp", dwarf => 14 },
{ name => "o7", dwarf => 15 },
{ name => "i0", dwarf => 24 },
{ name => "i1", dwarf => 25 },
{ name => "i2", dwarf => 26 },
{ name => "i3", dwarf => 27 },
{ name => "i4", dwarf => 28 },
{ name => "i5", dwarf => 29 },
{ name => "frame_pointer", dwarf => 30, realname => "fp" },
{ name => "i7", dwarf => 31 },
{ name => "l0", encoding => 16, dwarf => 16 },
{ name => "l1", encoding => 17, dwarf => 17 },
{ name => "l2", encoding => 18, dwarf => 18 },
{ name => "l3", encoding => 19, dwarf => 19 },
{ name => "l4", encoding => 20, dwarf => 20 },
{ name => "l5", encoding => 21, dwarf => 21 },
{ name => "l6", encoding => 22, dwarf => 22 },
{ name => "l7", encoding => 23, dwarf => 23 },
{ name => "g0", encoding => 0, dwarf => 0 },
{ name => "g1", encoding => 1, dwarf => 1 },
{ name => "g2", encoding => 2, dwarf => 2 },
{ name => "g3", encoding => 3, dwarf => 3 },
{ name => "g4", encoding => 4, dwarf => 4 },
{ name => "g5", encoding => 5, dwarf => 5 },
{ name => "g6", encoding => 6, dwarf => 6 },
{ name => "g7", encoding => 7, dwarf => 7 },
{ name => "o0", encoding => 8, dwarf => 8 },
{ name => "o1", encoding => 9, dwarf => 9 },
{ name => "o2", encoding => 10, dwarf => 10 },
{ name => "o3", encoding => 11, dwarf => 11 },
{ name => "o4", encoding => 12, dwarf => 12 },
{ name => "o5", encoding => 13, dwarf => 13 },
{ name => "sp", encoding => 14, dwarf => 14 },
{ name => "o7", encoding => 15, dwarf => 15 },
{ name => "i0", encoding => 24, dwarf => 24 },
{ name => "i1", encoding => 25, dwarf => 25 },
{ name => "i2", encoding => 26, dwarf => 26 },
{ name => "i3", encoding => 27, dwarf => 27 },
{ name => "i4", encoding => 28, dwarf => 28 },
{ name => "i5", encoding => 29, dwarf => 29 },
{ name => "frame_pointer", encoding => 30, dwarf => 30, realname => "fp" },
{ name => "i7", encoding => 31, dwarf => 31 },
{ mode => $mode_gp }
],
fpflags_class => [
......@@ -65,38 +65,38 @@ $mode_fp4 = "mode_Q";
],
# fp registers can be accessed any time
fp => [
{ name => "f0", dwarf => 32 },
{ name => "f1", dwarf => 33 },
{ name => "f2", dwarf => 34 },
{ name => "f3", dwarf => 35 },
{ name => "f4", dwarf => 36 },
{ name => "f5", dwarf => 37 },
{ name => "f6", dwarf => 38 },
{ name => "f7", dwarf => 39 },
{ name => "f8", dwarf => 40 },
{ name => "f9", dwarf => 41 },
{ name => "f10", dwarf => 42 },
{ name => "f11", dwarf => 43 },
{ name => "f12", dwarf => 44 },
{ name => "f13", dwarf => 45 },
{ name => "f14", dwarf => 46 },
{ name => "f15", dwarf => 47 },
{ name => "f16", dwarf => 48 },
{ name => "f17", dwarf => 49 },
{ name => "f18", dwarf => 50 },
{ name => "f19", dwarf => 51 },
{ name => "f20", dwarf => 52 },
{ name => "f21", dwarf => 53 },
{ name => "f22", dwarf => 54 },
{ name => "f23", dwarf => 55 },
{ name => "f24", dwarf => 56 },
{ name => "f25", dwarf => 57 },
{ name => "f26", dwarf => 58 },
{ name => "f27", dwarf => 59 },
{ name => "f28", dwarf => 60 },
{ name => "f29", dwarf => 61 },
{ name => "f30", dwarf => 62 },
{ name => "f31", dwarf => 63 },
{ name => "f0", encoding => 0, dwarf => 32 },
{ name => "f1", encoding => 1, dwarf => 33 },
{ name => "f2", encoding => 2, dwarf => 34 },
{ name => "f3", encoding => 3, dwarf => 35 },
{ name => "f4", encoding => 4, dwarf => 36 },
{ name => "f5", encoding => 5, dwarf => 37 },
{ name => "f6", encoding => 6, dwarf => 38 },
{ name => "f7", encoding => 7, dwarf => 39 },
{ name => "f8", encoding => 8, dwarf => 40 },
{ name => "f9", encoding => 9, dwarf => 41 },
{ name => "f10", encoding => 10, dwarf => 42 },
{ name => "f11", encoding => 11, dwarf => 43 },
{ name => "f12", encoding => 12, dwarf => 44 },
{ name => "f13", encoding => 13, dwarf => 45 },
{ name => "f14", encoding => 14, dwarf => 46 },
{ name => "f15", encoding => 15, dwarf => 47 },
{ name => "f16", encoding => 16, dwarf => 48 },
{ name => "f17", encoding => 17, dwarf => 49 },
{ name => "f18", encoding => 18, dwarf => 50 },
{ name => "f19", encoding => 19, dwarf => 51 },
{ name => "f20", encoding => 20, dwarf => 52 },
{ name => "f21", encoding => 21, dwarf => 53 },
{ name => "f22", encoding => 22, dwarf => 54 },
{ name => "f23", encoding => 23, dwarf => 55 },
{ name => "f24", encoding => 24, dwarf => 56 },
{ name => "f25", encoding => 25, dwarf => 57 },
{ name => "f26", encoding => 26, dwarf => 58 },
{ name => "f27", encoding => 27, dwarf => 59 },
{ name => "f28", encoding => 28, dwarf => 60 },
{ name => "f29", encoding => 29, dwarf => 61 },
{ name => "f30", encoding => 30, dwarf => 62 },
{ name => "f31", encoding => 31, dwarf => 63 },
{ mode => $mode_fp }
]
); # %reg_classes
......
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