Start factoring out the hardware op code.
This commit is contained in:
parent
39aa672422
commit
416b13fd76
39
mach/proto/mcg/hop.c
Normal file
39
mach/proto/mcg/hop.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "mcg.h"
|
||||||
|
|
||||||
|
struct hop* new_hop(int insn_no, struct ir* ir)
|
||||||
|
{
|
||||||
|
struct hop* hop = calloc(1, sizeof *hop);
|
||||||
|
hop->insn_no = insn_no;
|
||||||
|
hop->ir = ir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_reg(struct vreg* vregs[], struct vreg* vreg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<HOP_INOUT_REGS; i++)
|
||||||
|
if (!vregs[i])
|
||||||
|
{
|
||||||
|
vregs[i] = vreg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal("too many input registers for instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void hop_add_in_reg(struct hop* hop, struct vreg* vreg)
|
||||||
|
{
|
||||||
|
add_reg(hop->invregs, vreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hop_add_out_reg(struct hop* hop, struct vreg* vreg)
|
||||||
|
{
|
||||||
|
add_reg(hop->outvregs, vreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hop_emit(struct hop* hop, const struct burm_emitter_data* ed)
|
||||||
|
{
|
||||||
|
const struct burm_instruction_data* insndata = &burm_instruction_data[hop->insn_no];
|
||||||
|
insndata->emitter(hop->ir, ed);
|
||||||
|
}
|
||||||
|
|
27
mach/proto/mcg/hop.h
Normal file
27
mach/proto/mcg/hop.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef HOP_H
|
||||||
|
#define HOP_H
|
||||||
|
|
||||||
|
struct vreg
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
int regclass;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HOP_INOUT_REGS 4
|
||||||
|
|
||||||
|
struct hop
|
||||||
|
{
|
||||||
|
int insn_no;
|
||||||
|
struct ir* ir;
|
||||||
|
struct vreg* invregs[HOP_INOUT_REGS];
|
||||||
|
struct vreg* outvregs[HOP_INOUT_REGS];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct hop* new_hop(int insn_no, struct ir* ir);
|
||||||
|
|
||||||
|
extern void hop_add_in_reg(struct hop* hop, struct vreg* reg);
|
||||||
|
extern void hop_add_out_reg(struct hop* hop, struct vreg* reg);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct ir
|
||||||
|
|
||||||
void* state_label; /* used by the iburg instruction selector */
|
void* state_label; /* used by the iburg instruction selector */
|
||||||
int insn_no;
|
int insn_no;
|
||||||
|
int vreg;
|
||||||
|
|
||||||
bool is_sequence : 1;
|
bool is_sequence : 1;
|
||||||
bool is_generated : 1;
|
bool is_generated : 1;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "ir.h"
|
#include "ir.h"
|
||||||
|
#include "mcgg.h"
|
||||||
|
#include "hop.h"
|
||||||
|
|
||||||
extern char em_pseu[][4];
|
extern char em_pseu[][4];
|
||||||
extern char em_mnem[][4];
|
extern char em_mnem[][4];
|
||||||
|
@ -80,6 +82,7 @@ struct basicblock
|
||||||
const char* name;
|
const char* name;
|
||||||
ARRAY(struct em, ems);
|
ARRAY(struct em, ems);
|
||||||
ARRAY(struct ir, irs);
|
ARRAY(struct ir, irs);
|
||||||
|
ARRAY(struct hop, hops);
|
||||||
bool is_fake : 1;
|
bool is_fake : 1;
|
||||||
bool is_root : 1;
|
bool is_root : 1;
|
||||||
bool is_terminated : 1;
|
bool is_terminated : 1;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "mcg.h"
|
#include "mcg.h"
|
||||||
#include "mcgg.h"
|
|
||||||
|
static int vregcount;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
|
static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
|
||||||
|
@ -26,8 +27,8 @@ static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
|
||||||
|
|
||||||
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
|
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
|
||||||
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
|
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
|
||||||
tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
|
//tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
|
||||||
insndata->name, cost, bestcost);
|
// insndata->name, cost, bestcost);
|
||||||
}
|
}
|
||||||
|
|
||||||
void burm_panic_cannot_match(struct ir* ir)
|
void burm_panic_cannot_match(struct ir* ir)
|
||||||
|
@ -51,7 +52,7 @@ static void emit_reg(struct ir* ir)
|
||||||
if (insndata->is_fragment)
|
if (insndata->is_fragment)
|
||||||
insndata->emitter(ir, &emitter_data);
|
insndata->emitter(ir, &emitter_data);
|
||||||
else
|
else
|
||||||
tracef('I', "I: emit reg $%d\n", ir->id);
|
tracef('I', "I: emit reg %d\n", ir->vreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_value(struct ir* ir)
|
static void emit_value(struct ir* ir)
|
||||||
|
@ -85,13 +86,26 @@ static void walk_instructions(struct ir* ir, int goal)
|
||||||
const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
|
const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
|
||||||
const short* nts = burm_nts[insn_no];
|
const short* nts = burm_nts[insn_no];
|
||||||
int i;
|
int i;
|
||||||
|
int resultreg = 0;
|
||||||
|
|
||||||
ir->insn_no = insn_no;
|
ir->insn_no = insn_no;
|
||||||
|
|
||||||
|
if (insndata->allocate)
|
||||||
|
{
|
||||||
|
resultreg = vregcount++;
|
||||||
|
tracef('I', "I: new %s %d\n",
|
||||||
|
burm_register_class_names[insndata->allocate], resultreg);
|
||||||
|
}
|
||||||
|
|
||||||
burm_kids(ir, insn_no, children);
|
burm_kids(ir, insn_no, children);
|
||||||
for (i=0; nts[i]; i++)
|
for (i=0; nts[i]; i++)
|
||||||
walk_instructions(children[i], nts[i]);
|
walk_instructions(children[i], nts[i]);
|
||||||
|
|
||||||
|
if (ir->vreg)
|
||||||
|
tracef('I', "I: use %d\n", ir->vreg);
|
||||||
|
if (resultreg)
|
||||||
|
ir->vreg = resultreg;
|
||||||
|
|
||||||
tracef('I', "I: $%d %s selected %s %d: %s\n",
|
tracef('I', "I: $%d %s selected %s %d: %s\n",
|
||||||
ir->id,
|
ir->id,
|
||||||
ir->is_sequence ? "S" : " ",
|
ir->is_sequence ? "S" : " ",
|
||||||
|
@ -100,8 +114,6 @@ static void walk_instructions(struct ir* ir, int goal)
|
||||||
insndata->name);
|
insndata->name);
|
||||||
ir->is_generated = true;
|
ir->is_generated = true;
|
||||||
|
|
||||||
if (insndata->allocate)
|
|
||||||
tracef('I', "I: allocate reg of class %d\n", insndata->allocate);
|
|
||||||
if (!insndata->is_fragment && insndata->emitter)
|
if (!insndata->is_fragment && insndata->emitter)
|
||||||
insndata->emitter(ir, &emitter_data);
|
insndata->emitter(ir, &emitter_data);
|
||||||
}
|
}
|
||||||
|
@ -131,6 +143,8 @@ void pass_instruction_selector(struct procedure* proc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
vregcount = 1;
|
||||||
|
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks_count; i++)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = proc->blocks[i];
|
struct basicblock* bb = proc->blocks[i];
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct burm_emitter_data
|
||||||
void (*emit_value)(struct ir* ir);
|
void (*emit_value)(struct ir* ir);
|
||||||
void (*emit_resultreg)(void);
|
void (*emit_resultreg)(void);
|
||||||
void (*emit_eoi)(void);
|
void (*emit_eoi)(void);
|
||||||
|
void (*emit_usereg)(struct ir* ir);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data);
|
typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data);
|
||||||
|
@ -44,6 +45,7 @@ struct burm_instruction_data
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct burm_instruction_data burm_instruction_data[];
|
extern const struct burm_instruction_data burm_instruction_data[];
|
||||||
|
extern const char* burm_register_class_names[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue