- Update the romcc version.
- Add an additional consistency check to romcc and fix the more obvious problems it has uncovered With this update there are no known silent failures in romcc. - Update the memory initialization code to setup all 3 of the memory sizing registers properly - In auto.c test our dynamic maximum amount of ram. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@885 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
9dbd460776
commit
f7a0ba84dc
|
@ -177,7 +177,6 @@ static void main(void)
|
|||
print_debug_hex32(msr.hi);
|
||||
print_debug_hex32(msr.lo);
|
||||
print_debug("\r\n");
|
||||
#warning "FIXME if I pass msr.lo somehow I get the value 0x00000030 as stop in ram_check"
|
||||
ram_check(0x00000000, 0x20000000);
|
||||
ram_check(0x00000000, msr.lo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include "southbridge/amd/amd8111/amd8111_enable_rom.c"
|
||||
#include "northbridge/amd/amdk8/early_ht.c"
|
||||
|
||||
|
||||
|
||||
static void main(void)
|
||||
{
|
||||
if (do_normal_boot()) {
|
||||
|
|
|
@ -657,18 +657,20 @@ static void sdram_set_registers(void)
|
|||
* address that define the memory address space. These
|
||||
* bits decode 32-MByte blocks of memory.
|
||||
*/
|
||||
PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
|
||||
#if MEMORY_CONFIG == MEMORY_LNXI_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x01000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x02000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x03000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
|
||||
#endif
|
||||
#if MEMORY_CONFIG == MEMORY_SUSE_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00800001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x01000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x01800001,
|
||||
#endif
|
||||
#if MEMORY_CONFIG == MEMORY_LNXI_HDAMA
|
||||
PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00001001,
|
||||
PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
|
||||
|
@ -697,10 +699,10 @@ static void sdram_set_registers(void)
|
|||
*
|
||||
*/
|
||||
#if MEMORY_CONFIG == MEMORY_LNXI_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00e0fe00,
|
||||
PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00e0fe00,
|
||||
PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00e0fe00,
|
||||
PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00e0fe00,
|
||||
PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00000000,
|
||||
PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00000000,
|
||||
#endif
|
||||
#if MEMORY_CONFIG == MEMORY_SUSE_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x0060fe00,
|
||||
|
@ -739,7 +741,7 @@ static void sdram_set_registers(void)
|
|||
* [31:15]
|
||||
*/
|
||||
#if MEMORY_CONFIG == MEMORY_LNXI_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000033,
|
||||
PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000000,
|
||||
#endif
|
||||
#if MEMORY_CONFIG == MEMORY_SUSE_SOLO
|
||||
PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000022,
|
||||
|
@ -1173,29 +1175,53 @@ static struct dimm_size spd_get_dimm_size(unsigned device)
|
|||
return sz;
|
||||
}
|
||||
|
||||
static unsigned spd_to_dimm_side0(unsigned device)
|
||||
static unsigned spd_to_dimm(unsigned device)
|
||||
{
|
||||
return (device - SMBUS_MEM_DEVICE_START) << 1;
|
||||
return (device - SMBUS_MEM_DEVICE_START);
|
||||
}
|
||||
|
||||
static unsigned spd_to_dimm_side1(unsigned device)
|
||||
static void set_dimm_size(struct dimm_size sz, unsigned index)
|
||||
{
|
||||
return ((device - SMBUS_MEM_DEVICE_START) << 1) + 1;
|
||||
}
|
||||
uint32_t base0, base1, map;
|
||||
|
||||
static void set_dimm_size(unsigned long size, unsigned index)
|
||||
{
|
||||
unsigned value = 0;
|
||||
/* Make certain the dimm is at least 32MB */
|
||||
if (size >= (25 + 3)) {
|
||||
/* Place the dimm size in 32 MB quantities in the bits 31 - 21.
|
||||
* The initialize dimm size is in bits.
|
||||
* Set the base enable bit0.
|
||||
*/
|
||||
value = (1 << ((size - (25 + 3)) + 21)) | 1;
|
||||
#if 1
|
||||
print_debug("set_dimm_size: (");
|
||||
print_debug_hex32(sz.side1);
|
||||
print_debug_char(',');
|
||||
print_debug_hex32(sz.side2);
|
||||
print_debug_char(',');
|
||||
print_debug_hex32(index);
|
||||
print_debug(")\r\n");
|
||||
#endif
|
||||
if (sz.side1 != sz.side2) {
|
||||
sz.side2 = 0;
|
||||
}
|
||||
map = pci_read_config32(PCI_DEV(0, 0x18, 2), 0x80);
|
||||
map &= ~(0xf << (index + 4));
|
||||
|
||||
/* For each base register.
|
||||
* Place the dimm size in 32 MB quantities in the bits 31 - 21.
|
||||
* The initialize dimm size is in bits.
|
||||
* Set the base enable bit0.
|
||||
*/
|
||||
|
||||
base0 = base1 = 0;
|
||||
|
||||
/* Make certain side1 of the dimm is at least 32MB */
|
||||
if (sz.side1 >= (25 + 3)) {
|
||||
base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
|
||||
map |= (sz.side1 - (25 + 3)) << (index *4);
|
||||
}
|
||||
|
||||
/* Make certain side2 of the dimm is at least 32MB */
|
||||
if (sz.side2 >= (25 + 3)) {
|
||||
base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
|
||||
}
|
||||
|
||||
/* Set the appropriate DIMM base address register */
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (index << 2), value);
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (((index << 1)+0)<<2), base0);
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (((index << 1)+1)<<2), base1);
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x80, map);
|
||||
}
|
||||
|
||||
static void spd_set_ram_size(void)
|
||||
|
@ -1207,8 +1233,7 @@ static void spd_set_ram_size(void)
|
|||
{
|
||||
struct dimm_size sz;
|
||||
sz = spd_get_dimm_size(device);
|
||||
set_dimm_size(sz.side1, spd_to_dimm_side0(device));
|
||||
set_dimm_size(sz.side2, spd_to_dimm_side1(device));
|
||||
set_dimm_size(sz, spd_to_dimm(device));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1235,14 +1260,12 @@ static void set_top_mem(unsigned tom_k)
|
|||
static void order_dimms(void)
|
||||
{
|
||||
unsigned long tom;
|
||||
unsigned mask;
|
||||
unsigned index;
|
||||
|
||||
/* Remember which registers we have used in the high 8 bits of tom */
|
||||
tom = 0;
|
||||
for(;;) {
|
||||
/* Find the largest remaining canidate */
|
||||
unsigned canidate;
|
||||
unsigned index, canidate;
|
||||
uint32_t csbase, csmask;
|
||||
unsigned size;
|
||||
csbase = 0;
|
||||
|
@ -1292,12 +1315,17 @@ static void order_dimms(void)
|
|||
|
||||
/* Write the new base register */
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (canidate << 2), csbase);
|
||||
/* Write the new mask register */
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 2), 0x60 + (canidate << 2), csmask);
|
||||
|
||||
}
|
||||
set_top_mem((tom & ~0xff000000) << 15);
|
||||
}
|
||||
|
||||
static void spd_set_dram_timing(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#define DRAM_CONFIG_LOW 0x90
|
||||
#define DCL_DLL_Disable (1<<0)
|
||||
|
@ -1322,6 +1350,7 @@ static void spd_set_ecc_mode(void)
|
|||
static void sdram_set_spd_registers(void)
|
||||
{
|
||||
spd_set_ram_size();
|
||||
spd_set_dram_timing();
|
||||
spd_set_ecc_mode();
|
||||
order_dimms();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
VERSION:=0.28
|
||||
RELEASE_DATE:=16 June 2003
|
||||
VERSION:=0.29
|
||||
RELEASE_DATE:=19 June 2003
|
||||
PACKAGE:=romcc
|
||||
|
||||
|
||||
# Move the configuration defines to makefile.conf
|
||||
CC=gcc
|
||||
CPPFLAGS=-DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(RELEASE_DATE)"'
|
||||
CFLAGS=-O -g -Wall $(CPPFLAGS)
|
||||
CFLAGS= -g -Wall $(CPPFLAGS)
|
||||
CPROF_FLAGS=-pg -fprofile-arcs
|
||||
|
||||
all: romcc test
|
||||
|
@ -19,6 +19,7 @@ romcc_pg: romcc.c Makefile
|
|||
|
||||
TESTS=\
|
||||
hello_world.c \
|
||||
hello_world2.c \
|
||||
simple_test.c \
|
||||
simple_test2.c \
|
||||
simple_test3.c \
|
||||
|
@ -52,6 +53,10 @@ TESTS=\
|
|||
simple_test31.c \
|
||||
simple_test32.c \
|
||||
simple_test33.c \
|
||||
simple_test34.c \
|
||||
simple_test35.c \
|
||||
simple_test36.c \
|
||||
simple_test37.c \
|
||||
raminit_test.c \
|
||||
raminit_test2.c \
|
||||
raminit_test3.c \
|
||||
|
|
|
@ -215,6 +215,9 @@ struct file_state {
|
|||
char *pos;
|
||||
int line;
|
||||
char *line_start;
|
||||
int report_line;
|
||||
const char *report_name;
|
||||
const char *report_dir;
|
||||
};
|
||||
struct hash_entry;
|
||||
struct token {
|
||||
|
@ -632,6 +635,14 @@ struct triple_set {
|
|||
#define MAX_MISC 15
|
||||
#define MAX_TARG 15
|
||||
|
||||
struct occurance {
|
||||
int count;
|
||||
const char *filename;
|
||||
const char *function;
|
||||
int line;
|
||||
int col;
|
||||
struct occurance *parent;
|
||||
};
|
||||
struct triple {
|
||||
struct triple *next, *prev;
|
||||
struct triple_set *use;
|
||||
|
@ -665,9 +676,7 @@ struct triple {
|
|||
#define TRIPLE_FLAG_FLATTENED (1 << 31)
|
||||
#define TRIPLE_FLAG_PRE_SPLIT (1 << 30)
|
||||
#define TRIPLE_FLAG_POST_SPLIT (1 << 29)
|
||||
const char *filename;
|
||||
int line;
|
||||
int col;
|
||||
struct occurance *occurance;
|
||||
union {
|
||||
ulong_t cval;
|
||||
struct block *block;
|
||||
|
@ -744,6 +753,8 @@ struct compile_state {
|
|||
FILE *output;
|
||||
struct triple *vars;
|
||||
struct file_state *file;
|
||||
struct occurance *last_occurance;
|
||||
const char *function;
|
||||
struct token token[4];
|
||||
struct hash_entry *hash_table[HASH_TABLE_SIZE];
|
||||
struct hash_entry *i_continue;
|
||||
|
@ -956,7 +967,9 @@ static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
|
|||
int col;
|
||||
if (triple) {
|
||||
fprintf(fp, "%s:%d.%d: ",
|
||||
triple->filename, triple->line, triple->col);
|
||||
triple->occurance->filename,
|
||||
triple->occurance->line,
|
||||
triple->occurance->col);
|
||||
return;
|
||||
}
|
||||
if (!state->file) {
|
||||
|
@ -964,7 +977,7 @@ static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
|
|||
}
|
||||
col = get_col(state->file);
|
||||
fprintf(fp, "%s:%d.%d: ",
|
||||
state->file->basename, state->file->line, col);
|
||||
state->file->report_name, state->file->report_line, col);
|
||||
}
|
||||
|
||||
static void __internal_error(struct compile_state *state, struct triple *ptr,
|
||||
|
@ -1194,22 +1207,119 @@ static void pop_triple(struct triple *used, struct triple *unuser)
|
|||
}
|
||||
}
|
||||
|
||||
static void put_occurance(struct occurance *occurance)
|
||||
{
|
||||
occurance->count -= 1;
|
||||
if (occurance->count <= 0) {
|
||||
if (occurance->parent) {
|
||||
put_occurance(occurance->parent);
|
||||
}
|
||||
xfree(occurance);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_occurance(struct occurance *occurance)
|
||||
{
|
||||
occurance->count += 1;
|
||||
}
|
||||
|
||||
|
||||
static struct occurance *new_occurance(struct compile_state *state)
|
||||
{
|
||||
struct occurance *result, *last;
|
||||
const char *filename;
|
||||
const char *function;
|
||||
int line, col;
|
||||
|
||||
function = "";
|
||||
filename = 0;
|
||||
line = 0;
|
||||
col = 0;
|
||||
if (state->file) {
|
||||
filename = state->file->report_name;
|
||||
line = state->file->report_line;
|
||||
col = get_col(state->file);
|
||||
}
|
||||
if (state->function) {
|
||||
function = state->function;
|
||||
}
|
||||
last = state->last_occurance;
|
||||
if (last &&
|
||||
(last->col == col) &&
|
||||
(last->line == line) &&
|
||||
(last->function == function) &&
|
||||
(strcmp(last->filename, filename) == 0)) {
|
||||
get_occurance(last);
|
||||
return last;
|
||||
}
|
||||
if (last) {
|
||||
state->last_occurance = 0;
|
||||
put_occurance(last);
|
||||
}
|
||||
result = xmalloc(sizeof(*result), "occurance");
|
||||
result->count = 2;
|
||||
result->filename = filename;
|
||||
result->function = function;
|
||||
result->line = line;
|
||||
result->col = col;
|
||||
result->parent = 0;
|
||||
state->last_occurance = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct occurance *inline_occurance(struct compile_state *state,
|
||||
struct occurance *new, struct occurance *orig)
|
||||
{
|
||||
struct occurance *result, *last;
|
||||
last = state->last_occurance;
|
||||
if (last &&
|
||||
(last->parent == orig) &&
|
||||
(last->col == new->col) &&
|
||||
(last->line == new->line) &&
|
||||
(last->function == new->function) &&
|
||||
(last->filename == new->filename)) {
|
||||
get_occurance(last);
|
||||
return last;
|
||||
}
|
||||
if (last) {
|
||||
state->last_occurance = 0;
|
||||
put_occurance(last);
|
||||
}
|
||||
get_occurance(orig);
|
||||
result = xmalloc(sizeof(*result), "occurance");
|
||||
result->count = 2;
|
||||
result->filename = new->filename;
|
||||
result->function = new->function;
|
||||
result->line = new->line;
|
||||
result->col = new->col;
|
||||
result->parent = orig;
|
||||
state->last_occurance = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static struct occurance dummy_occurance = {
|
||||
.count = 2,
|
||||
.filename = __FILE__,
|
||||
.function = "",
|
||||
.line = __LINE__,
|
||||
.col = 0,
|
||||
.parent = 0,
|
||||
};
|
||||
|
||||
/* The zero triple is used as a place holder when we are removing pointers
|
||||
* from a triple. Having allows certain sanity checks to pass even
|
||||
* when the original triple that was pointed to is gone.
|
||||
*/
|
||||
static struct triple zero_triple = {
|
||||
.next = &zero_triple,
|
||||
.prev = &zero_triple,
|
||||
.use = 0,
|
||||
.op = OP_INTCONST,
|
||||
.sizes = TRIPLE_SIZES(0, 0, 0, 0),
|
||||
.id = -1, /* An invalid id */
|
||||
.next = &zero_triple,
|
||||
.prev = &zero_triple,
|
||||
.use = 0,
|
||||
.op = OP_INTCONST,
|
||||
.sizes = TRIPLE_SIZES(0, 0, 0, 0),
|
||||
.id = -1, /* An invalid id */
|
||||
.u = { .cval = 0, },
|
||||
.filename = __FILE__,
|
||||
.line = __LINE__,
|
||||
.col = 0,
|
||||
.occurance = &dummy_occurance,
|
||||
.param { [0] = 0, [1] = 0, },
|
||||
};
|
||||
|
||||
|
@ -1268,7 +1378,7 @@ static unsigned short triple_sizes(struct compile_state *state,
|
|||
|
||||
static struct triple *alloc_triple(struct compile_state *state,
|
||||
int op, struct type *type, int lhs, int rhs,
|
||||
const char *filename, int line, int col)
|
||||
struct occurance *occurance)
|
||||
{
|
||||
size_t size, sizes, extra_count, min_count;
|
||||
struct triple *ret;
|
||||
|
@ -1280,14 +1390,12 @@ static struct triple *alloc_triple(struct compile_state *state,
|
|||
|
||||
size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
|
||||
ret = xcmalloc(size, "tripple");
|
||||
ret->op = op;
|
||||
ret->sizes = sizes;
|
||||
ret->type = type;
|
||||
ret->next = ret;
|
||||
ret->prev = ret;
|
||||
ret->filename = filename;
|
||||
ret->line = line;
|
||||
ret->col = col;
|
||||
ret->op = op;
|
||||
ret->sizes = sizes;
|
||||
ret->type = type;
|
||||
ret->next = ret;
|
||||
ret->prev = ret;
|
||||
ret->occurance = occurance;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1298,8 +1406,9 @@ struct triple *dup_triple(struct compile_state *state, struct triple *src)
|
|||
src_lhs = TRIPLE_LHS(src->sizes);
|
||||
src_rhs = TRIPLE_RHS(src->sizes);
|
||||
src_size = TRIPLE_SIZE(src->sizes);
|
||||
get_occurance(src->occurance);
|
||||
dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
|
||||
src->filename, src->line, src->col);
|
||||
src->occurance);
|
||||
memcpy(dup, src, sizeof(*src));
|
||||
memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
|
||||
return dup;
|
||||
|
@ -1309,28 +1418,19 @@ static struct triple *new_triple(struct compile_state *state,
|
|||
int op, struct type *type, int lhs, int rhs)
|
||||
{
|
||||
struct triple *ret;
|
||||
const char *filename;
|
||||
int line, col;
|
||||
filename = 0;
|
||||
line = 0;
|
||||
col = 0;
|
||||
if (state->file) {
|
||||
filename = state->file->basename;
|
||||
line = state->file->line;
|
||||
col = get_col(state->file);
|
||||
}
|
||||
ret = alloc_triple(state, op, type, lhs, rhs,
|
||||
filename, line, col);
|
||||
struct occurance *occurance;
|
||||
occurance = new_occurance(state);
|
||||
ret = alloc_triple(state, op, type, lhs, rhs, occurance);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct triple *build_triple(struct compile_state *state,
|
||||
int op, struct type *type, struct triple *left, struct triple *right,
|
||||
const char *filename, int line, int col)
|
||||
struct occurance *occurance)
|
||||
{
|
||||
struct triple *ret;
|
||||
size_t count;
|
||||
ret = alloc_triple(state, op, type, -1, -1, filename, line, col);
|
||||
ret = alloc_triple(state, op, type, -1, -1, occurance);
|
||||
count = TRIPLE_SIZE(ret->sizes);
|
||||
if (count > 0) {
|
||||
ret->param[0] = left;
|
||||
|
@ -1433,8 +1533,8 @@ static struct triple *pre_triple(struct compile_state *state,
|
|||
base = MISC(base, 0);
|
||||
}
|
||||
block = block_of_triple(state, base);
|
||||
ret = build_triple(state, op, type, left, right,
|
||||
base->filename, base->line, base->col);
|
||||
get_occurance(base->occurance);
|
||||
ret = build_triple(state, op, type, left, right, base->occurance);
|
||||
if (triple_stores_block(state, ret)) {
|
||||
ret->u.block = block;
|
||||
}
|
||||
|
@ -1463,8 +1563,8 @@ static struct triple *post_triple(struct compile_state *state,
|
|||
}
|
||||
|
||||
block = block_of_triple(state, base);
|
||||
ret = build_triple(state, op, type, left, right,
|
||||
base->filename, base->line, base->col);
|
||||
get_occurance(base->occurance);
|
||||
ret = build_triple(state, op, type, left, right, base->occurance);
|
||||
if (triple_stores_block(state, ret)) {
|
||||
ret->u.block = block;
|
||||
}
|
||||
|
@ -1485,22 +1585,31 @@ static struct triple *label(struct compile_state *state)
|
|||
|
||||
static void display_triple(FILE *fp, struct triple *ins)
|
||||
{
|
||||
struct occurance *ptr;
|
||||
const char *reg;
|
||||
char pre, post;
|
||||
pre = post = ' ';
|
||||
if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
|
||||
pre = '^';
|
||||
}
|
||||
if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
|
||||
post = 'v';
|
||||
}
|
||||
reg = arch_reg_str(ID_REG(ins->id));
|
||||
if (ins->op == OP_INTCONST) {
|
||||
fprintf(fp, "(%p) %3d %-2d %-10s <0x%08lx> @ %s:%d.%d\n",
|
||||
ins, ID_REG(ins->id), ins->template_id, tops(ins->op),
|
||||
ins->u.cval,
|
||||
ins->filename, ins->line, ins->col);
|
||||
fprintf(fp, "(%p) %c%c %-7s %-2d %-10s <0x%08lx> ",
|
||||
ins, pre, post, reg, ins->template_id, tops(ins->op),
|
||||
ins->u.cval);
|
||||
}
|
||||
else if (ins->op == OP_ADDRCONST) {
|
||||
fprintf(fp, "(%p) %3d %-2d %-10s %-10p <0x%08lx> @ %s:%d.%d\n",
|
||||
ins, ID_REG(ins->id), ins->template_id, tops(ins->op),
|
||||
MISC(ins, 0), ins->u.cval,
|
||||
ins->filename, ins->line, ins->col);
|
||||
fprintf(fp, "(%p) %c%c %-7s %-2d %-10s %-10p <0x%08lx>",
|
||||
ins, pre, post, reg, ins->template_id, tops(ins->op),
|
||||
MISC(ins, 0), ins->u.cval);
|
||||
}
|
||||
else {
|
||||
int i, count;
|
||||
fprintf(fp, "(%p) %3d %-2d %-10s",
|
||||
ins, ID_REG(ins->id), ins->template_id, tops(ins->op));
|
||||
fprintf(fp, "(%p) %c%c %-7s %-2d %-10s",
|
||||
ins, pre, post, reg, ins->template_id, tops(ins->op));
|
||||
count = TRIPLE_SIZE(ins->sizes);
|
||||
for(i = 0; i < count; i++) {
|
||||
fprintf(fp, " %-10p", ins->param[i]);
|
||||
|
@ -1508,9 +1617,16 @@ static void display_triple(FILE *fp, struct triple *ins)
|
|||
for(; i < 2; i++) {
|
||||
fprintf(fp, " ");
|
||||
}
|
||||
fprintf(fp, " @ %s:%d.%d\n",
|
||||
ins->filename, ins->line, ins->col);
|
||||
}
|
||||
fprintf(fp, " @");
|
||||
for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
|
||||
fprintf(fp, " %s,%s:%d.%d",
|
||||
ptr->function,
|
||||
ptr->filename,
|
||||
ptr->line,
|
||||
ptr->col);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
|
@ -1662,6 +1778,7 @@ static void free_triple(struct compile_state *state, struct triple *ptr)
|
|||
if (ptr->use) {
|
||||
internal_error(state, ptr, "ptr->use != 0");
|
||||
}
|
||||
put_occurance(ptr->occurance);
|
||||
memset(ptr, -1, size);
|
||||
xfree(ptr);
|
||||
}
|
||||
|
@ -2383,6 +2500,7 @@ next_token:
|
|||
while ((tokp < end) && spacep(c)) {
|
||||
if (c == '\n') {
|
||||
file->line++;
|
||||
file->report_line++;
|
||||
file->line_start = tokp + 1;
|
||||
}
|
||||
c = *(++tokp);
|
||||
|
@ -2398,6 +2516,7 @@ next_token:
|
|||
c = *tokp;
|
||||
if (c == '\n') {
|
||||
file->line++;
|
||||
file->report_line++;
|
||||
file->line_start = tokp +1;
|
||||
break;
|
||||
}
|
||||
|
@ -2424,6 +2543,7 @@ next_token:
|
|||
if (tok == TOK_UNKNOWN) {
|
||||
error(state, 0, "unterminated comment");
|
||||
}
|
||||
file->report_line += line - file->line;
|
||||
file->line = line;
|
||||
file->line_start = line_start;
|
||||
}
|
||||
|
@ -2460,6 +2580,7 @@ next_token:
|
|||
if (line != file->line) {
|
||||
warning(state, 0, "multiline string constant");
|
||||
}
|
||||
file->report_line += line - file->line;
|
||||
file->line = line;
|
||||
file->line_start = line_start;
|
||||
|
||||
|
@ -2499,6 +2620,7 @@ next_token:
|
|||
if (line != file->line) {
|
||||
warning(state, 0, "multiline character constant");
|
||||
}
|
||||
file->report_line += line - file->line;
|
||||
file->line = line;
|
||||
file->line_start = line_start;
|
||||
|
||||
|
@ -2698,6 +2820,9 @@ static void compile_macro(struct compile_state *state, struct token *tk)
|
|||
file->pos = file->buf;
|
||||
file->line_start = file->pos;
|
||||
file->line = 1;
|
||||
file->report_line = 1;
|
||||
file->report_name = file->basename;
|
||||
file->report_dir = file->dirname;
|
||||
file->prev = state->file;
|
||||
state->file = file;
|
||||
}
|
||||
|
@ -2719,6 +2844,9 @@ static int mpeek(struct compile_state *state, int index)
|
|||
struct file_state *file = state->file;
|
||||
state->file = file->prev;
|
||||
/* file->basename is used keep it */
|
||||
if (file->report_dir != file->dirname) {
|
||||
xfree(file->report_dir);
|
||||
}
|
||||
xfree(file->dirname);
|
||||
xfree(file->buf);
|
||||
xfree(file);
|
||||
|
@ -3078,8 +3206,69 @@ static void preprocess(struct compile_state *state, int index)
|
|||
tk->ident->name);
|
||||
}
|
||||
switch(tk->tok) {
|
||||
case TOK_UNDEF:
|
||||
case TOK_LIT_INT:
|
||||
{
|
||||
int override_line;
|
||||
override_line = strtoul(tk->val.str, 0, 10);
|
||||
next_token(state, index);
|
||||
/* I have a cpp line marker parse it */
|
||||
if (tk->tok == TOK_LIT_STRING) {
|
||||
const char *token, *base;
|
||||
char *name, *dir;
|
||||
int name_len, dir_len;
|
||||
name = xmalloc(tk->str_len, "report_name");
|
||||
token = tk->val.str + 1;
|
||||
base = strrchr(token, '/');
|
||||
name_len = tk->str_len -2;
|
||||
if (base != 0) {
|
||||
dir_len = base - token;
|
||||
base++;
|
||||
name_len -= base - token;
|
||||
} else {
|
||||
dir_len = 0;
|
||||
base = token;
|
||||
}
|
||||
memcpy(name, base, name_len);
|
||||
name[name_len] = '\0';
|
||||
dir = xmalloc(dir_len + 1, "report_dir");
|
||||
memcpy(dir, token, dir_len);
|
||||
dir[dir_len] = '\0';
|
||||
file->report_line = override_line - 1;
|
||||
file->report_name = name;
|
||||
file->report_dir = dir;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TOK_LINE:
|
||||
meat(state, index, TOK_LINE);
|
||||
meat(state, index, TOK_LIT_INT);
|
||||
file->report_line = strtoul(tk->val.str, 0, 10) -1;
|
||||
if (mpeek(state, index) == TOK_LIT_STRING) {
|
||||
const char *token, *base;
|
||||
char *name, *dir;
|
||||
int name_len, dir_len;
|
||||
meat(state, index, TOK_LIT_STRING);
|
||||
name = xmalloc(tk->str_len, "report_name");
|
||||
token = tk->val.str + 1;
|
||||
name_len = tk->str_len - 2;
|
||||
if (base != 0) {
|
||||
dir_len = base - token;
|
||||
base++;
|
||||
name_len -= base - token;
|
||||
} else {
|
||||
dir_len = 0;
|
||||
base = token;
|
||||
}
|
||||
memcpy(name, base, name_len);
|
||||
name[name_len] = '\0';
|
||||
dir = xmalloc(dir_len + 1, "report_dir");
|
||||
memcpy(dir, token, dir_len);
|
||||
dir[dir_len] = '\0';
|
||||
file->report_name = name;
|
||||
file->report_dir = dir;
|
||||
}
|
||||
break;
|
||||
case TOK_UNDEF:
|
||||
case TOK_PRAGMA:
|
||||
if (state->if_value < 0) {
|
||||
break;
|
||||
|
@ -3476,6 +3665,10 @@ static void compile_file(struct compile_state *state, const char *filename, int
|
|||
file->line_start = file->pos;
|
||||
file->line = 1;
|
||||
|
||||
file->report_line = 1;
|
||||
file->report_name = file->basename;
|
||||
file->report_dir = file->dirname;
|
||||
|
||||
file->prev = state->file;
|
||||
state->file = file;
|
||||
|
||||
|
@ -4725,7 +4918,8 @@ static struct triple *flatten_cond(
|
|||
return read_expr(state, val);
|
||||
}
|
||||
|
||||
struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
|
||||
struct triple *copy_func(struct compile_state *state, struct triple *ofunc,
|
||||
struct occurance *base_occurance)
|
||||
{
|
||||
struct triple *nfunc;
|
||||
struct triple *nfirst, *ofirst;
|
||||
|
@ -4745,11 +4939,13 @@ struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
|
|||
ofirst = old = RHS(ofunc, 0);
|
||||
do {
|
||||
struct triple *new;
|
||||
struct occurance *occurance;
|
||||
int old_lhs, old_rhs;
|
||||
old_lhs = TRIPLE_LHS(old->sizes);
|
||||
old_rhs = TRIPLE_RHS(old->sizes);
|
||||
occurance = inline_occurance(state, base_occurance, old->occurance);
|
||||
new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
|
||||
old->filename, old->line, old->col);
|
||||
occurance);
|
||||
if (!triple_stores_block(state, new)) {
|
||||
memcpy(&new->u, &old->u, sizeof(new->u));
|
||||
}
|
||||
|
@ -4822,7 +5018,7 @@ static struct triple *flatten_call(
|
|||
if (ofunc->op != OP_LIST) {
|
||||
internal_error(state, 0, "improper function");
|
||||
}
|
||||
nfunc = copy_func(state, ofunc);
|
||||
nfunc = copy_func(state, ofunc, ptr->occurance);
|
||||
nfirst = RHS(nfunc, 0)->next;
|
||||
/* Prepend the parameter reading into the new function list */
|
||||
ptype = nfunc->type->right;
|
||||
|
@ -5410,8 +5606,9 @@ static void flatten_structures(struct compile_state *state)
|
|||
|
||||
op = ins->op;
|
||||
def = RHS(ins, 0);
|
||||
get_occurance(ins->occurance);
|
||||
next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
|
||||
ins->filename, ins->line, ins->col);
|
||||
ins->occurance);
|
||||
|
||||
vector = &RHS(next, 0);
|
||||
tptr = next->type->left;
|
||||
|
@ -5426,9 +5623,9 @@ static void flatten_structures(struct compile_state *state)
|
|||
|
||||
vector[i] = triple(
|
||||
state, op, mtype, sfield, 0);
|
||||
vector[i]->filename = next->filename;
|
||||
vector[i]->line = next->line;
|
||||
vector[i]->col = next->col;
|
||||
put_occurance(vector[i]->occurance);
|
||||
get_occurance(next->occurance);
|
||||
vector[i]->occurance = next->occurance;
|
||||
tptr = tptr->right;
|
||||
}
|
||||
propogate_use(state, ins, next);
|
||||
|
@ -5444,8 +5641,9 @@ static void flatten_structures(struct compile_state *state)
|
|||
op = ins->op;
|
||||
src = RHS(ins, 0);
|
||||
dst = LHS(ins, 0);
|
||||
get_occurance(ins->occurance);
|
||||
next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
|
||||
ins->filename, ins->line, ins->col);
|
||||
ins->occurance);
|
||||
|
||||
vector = &RHS(next, 0);
|
||||
tptr = next->type->left;
|
||||
|
@ -5460,9 +5658,9 @@ static void flatten_structures(struct compile_state *state)
|
|||
dfield = deref_field(state, dst, mtype->field_ident);
|
||||
vector[i] = triple(
|
||||
state, op, mtype, dfield, sfield);
|
||||
vector[i]->filename = next->filename;
|
||||
vector[i]->line = next->line;
|
||||
vector[i]->col = next->col;
|
||||
put_occurance(vector[i]->occurance);
|
||||
get_occurance(next->occurance);
|
||||
vector[i]->occurance = next->occurance;
|
||||
tptr = tptr->right;
|
||||
}
|
||||
propogate_use(state, ins, next);
|
||||
|
@ -6344,10 +6542,13 @@ static void register_builtin_function(struct compile_state *state,
|
|||
|
||||
/* Dummy file state to get debug handling right */
|
||||
memset(&file, 0, sizeof(file));
|
||||
file.basename = name;
|
||||
file.basename = "<built-in>";
|
||||
file.line = 1;
|
||||
file.report_line = 1;
|
||||
file.report_name = file.basename;
|
||||
file.prev = state->file;
|
||||
state->file = &file;
|
||||
state->function = name;
|
||||
|
||||
/* Find the Parameter count */
|
||||
valid_op(state, op);
|
||||
|
@ -6436,6 +6637,7 @@ static void register_builtin_function(struct compile_state *state,
|
|||
symbol(state, ident, &ident->sym_ident, def, ftype);
|
||||
|
||||
state->file = file.prev;
|
||||
state->function = 0;
|
||||
#if 0
|
||||
fprintf(stdout, "\n");
|
||||
loc(stdout, state, 0);
|
||||
|
@ -8790,8 +8992,10 @@ static void decl(struct compile_state *state, struct triple *first)
|
|||
type = declarator(state, base_type, &ident, 0);
|
||||
if (global && ident && (peek(state) == TOK_LBRACE)) {
|
||||
/* function */
|
||||
state->function = ident->name;
|
||||
def = function_definition(state, type);
|
||||
symbol(state, ident, &ident->sym_ident, def, type);
|
||||
state->function = 0;
|
||||
}
|
||||
else {
|
||||
int done;
|
||||
|
@ -9962,11 +10166,10 @@ static void insert_phi_operations(struct compile_state *state)
|
|||
/* Count how many edges flow into this block */
|
||||
in_edges = front->users;
|
||||
/* Insert a phi function for this variable */
|
||||
get_occurance(front->first->occurance);
|
||||
phi = alloc_triple(
|
||||
state, OP_PHI, var->type, -1, in_edges,
|
||||
front->first->filename,
|
||||
front->first->line,
|
||||
front->first->col);
|
||||
front->first->occurance);
|
||||
phi->u.block = front;
|
||||
MISC(phi, 0) = var;
|
||||
use_triple(var, phi);
|
||||
|
@ -10624,8 +10827,9 @@ static void insert_copies_to_phi(struct compile_state *state)
|
|||
continue;
|
||||
}
|
||||
|
||||
get_occurance(val->occurance);
|
||||
move = build_triple(state, OP_COPY, phi->type, val, 0,
|
||||
val->filename, val->line, val->col);
|
||||
val->occurance);
|
||||
move->u.block = eblock;
|
||||
move->id |= TRIPLE_FLAG_PRE_SPLIT;
|
||||
use_triple(val, move);
|
||||
|
@ -11266,6 +11470,7 @@ static void insert_mandatory_copies(struct compile_state *state)
|
|||
internal_error(state, user, "bad rhs");
|
||||
}
|
||||
tmp = pre_copy(state, user, i);
|
||||
tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
|
||||
continue;
|
||||
} else {
|
||||
do_post_copy = 1;
|
||||
|
@ -11281,6 +11486,7 @@ static void insert_mandatory_copies(struct compile_state *state)
|
|||
internal_error(state, user, "bad rhs");
|
||||
}
|
||||
tmp = pre_copy(state, user, i);
|
||||
tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
|
||||
continue;
|
||||
} else {
|
||||
do_post_copy = 1;
|
||||
|
@ -11292,6 +11498,7 @@ static void insert_mandatory_copies(struct compile_state *state)
|
|||
if (do_post_copy) {
|
||||
struct reg_info pre, post;
|
||||
tmp = post_copy(state, ins);
|
||||
tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
|
||||
pre = arch_reg_lhs(state, ins, 0);
|
||||
post = arch_reg_lhs(state, tmp, 0);
|
||||
if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
|
||||
|
@ -11457,7 +11664,10 @@ static struct lre_hash **lre_probe(struct reg_state *rstate,
|
|||
index = hash_live_edge(left, right);
|
||||
|
||||
ptr = &rstate->hash[index];
|
||||
while((*ptr) && ((*ptr)->left != left) && ((*ptr)->right != right)) {
|
||||
while(*ptr) {
|
||||
if (((*ptr)->left == left) && ((*ptr)->right == right)) {
|
||||
break;
|
||||
}
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
return ptr;
|
||||
|
@ -11495,6 +11705,10 @@ static void add_live_edge(struct reg_state *rstate,
|
|||
if (*ptr) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "new_live_edge(%p, %p)\n",
|
||||
left, right);
|
||||
#endif
|
||||
new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
|
||||
new_hash->next = *ptr;
|
||||
new_hash->left = left;
|
||||
|
@ -11533,6 +11747,7 @@ static void remove_live_edge(struct reg_state *rstate,
|
|||
*ptr = edge->next;
|
||||
memset(edge, 0, sizeof(*edge));
|
||||
xfree(edge);
|
||||
right->degree--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11542,6 +11757,7 @@ static void remove_live_edge(struct reg_state *rstate,
|
|||
*ptr = edge->next;
|
||||
memset(edge, 0, sizeof(*edge));
|
||||
xfree(edge);
|
||||
left->degree--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11671,7 +11887,7 @@ static struct live_range *coalesce_ranges(
|
|||
fprintf(stderr, "lr2 pre\n");
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
#if 1
|
||||
fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
|
||||
lr1->defs->def,
|
||||
lr1->color,
|
||||
|
@ -11894,6 +12110,85 @@ static void graph_ins(
|
|||
return;
|
||||
}
|
||||
|
||||
static struct live_range *get_verify_live_range(
|
||||
struct compile_state *state, struct reg_state *rstate, struct triple *ins)
|
||||
{
|
||||
struct live_range *lr;
|
||||
struct live_range_def *lrd;
|
||||
int ins_found;
|
||||
if ((ins->id < 0) || (ins->id > rstate->defs)) {
|
||||
internal_error(state, ins, "bad ins?");
|
||||
}
|
||||
lr = rstate->lrd[ins->id].lr;
|
||||
ins_found = 0;
|
||||
lrd = lr->defs;
|
||||
do {
|
||||
if (lrd->def == ins) {
|
||||
ins_found = 1;
|
||||
}
|
||||
lrd = lrd->next;
|
||||
} while(lrd != lr->defs);
|
||||
if (!ins_found) {
|
||||
internal_error(state, ins, "ins not in live range");
|
||||
}
|
||||
return lr;
|
||||
}
|
||||
|
||||
static void verify_graph_ins(
|
||||
struct compile_state *state,
|
||||
struct reg_block *blocks, struct triple_reg_set *live,
|
||||
struct reg_block *rb, struct triple *ins, void *arg)
|
||||
{
|
||||
struct reg_state *rstate = arg;
|
||||
struct triple_reg_set *entry1, *entry2;
|
||||
|
||||
|
||||
/* Compare live against edges and make certain the code is working */
|
||||
for(entry1 = live; entry1; entry1 = entry1->next) {
|
||||
struct live_range *lr1;
|
||||
lr1 = get_verify_live_range(state, rstate, entry1->member);
|
||||
for(entry2 = live; entry2; entry2 = entry2->next) {
|
||||
struct live_range *lr2;
|
||||
struct live_range_edge *edge2;
|
||||
int lr1_found;
|
||||
int lr2_degree;
|
||||
if (entry2 == entry1) {
|
||||
continue;
|
||||
}
|
||||
lr2 = get_verify_live_range(state, rstate, entry2->member);
|
||||
if (lr1 == lr2) {
|
||||
internal_error(state, entry2->member,
|
||||
"live range with 2 values simultaneously alive");
|
||||
}
|
||||
if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
|
||||
continue;
|
||||
}
|
||||
if (!interfere(rstate, lr1, lr2)) {
|
||||
internal_error(state, entry2->member,
|
||||
"edges don't interfere?");
|
||||
}
|
||||
|
||||
lr1_found = 0;
|
||||
lr2_degree = 0;
|
||||
for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
|
||||
lr2_degree++;
|
||||
if (edge2->node == lr1) {
|
||||
lr1_found = 1;
|
||||
}
|
||||
}
|
||||
if (lr2_degree != lr2->degree) {
|
||||
internal_error(state, entry2->member,
|
||||
"computed degree: %d does not match reported degree: %d\n",
|
||||
lr2_degree, lr2->degree);
|
||||
}
|
||||
if (!lr1_found) {
|
||||
internal_error(state, entry2->member, "missing edge");
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void print_interference_ins(
|
||||
struct compile_state *state,
|
||||
|
@ -11902,9 +12197,14 @@ static void print_interference_ins(
|
|||
{
|
||||
struct reg_state *rstate = arg;
|
||||
struct live_range *lr;
|
||||
unsigned id;
|
||||
|
||||
lr = rstate->lrd[ins->id].lr;
|
||||
id = ins->id;
|
||||
ins->id = rstate->lrd[id].orig_id;
|
||||
SET_REG(ins->id, lr->color);
|
||||
display_triple(stdout, ins);
|
||||
ins->id = id;
|
||||
|
||||
if (lr->defs) {
|
||||
struct live_range_def *lrd;
|
||||
|
@ -12033,7 +12333,7 @@ static int coalesce_live_ranges(
|
|||
if (interfere(rstate, lr1, lr2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
res = coalesce_ranges(state, rstate, lr1, lr2);
|
||||
coalesced += 1;
|
||||
if (res != lr1) {
|
||||
|
@ -13066,6 +13366,7 @@ static void print_interference_block(
|
|||
}
|
||||
}
|
||||
id = ptr->id;
|
||||
ptr->id = rstate->lrd[id].orig_id;
|
||||
SET_REG(ptr->id, lr->color);
|
||||
display_triple(stdout, ptr);
|
||||
ptr->id = id;
|
||||
|
@ -13278,6 +13579,9 @@ static void allocate_registers(struct compile_state *state)
|
|||
/* Forget previous live range edge calculations */
|
||||
cleanup_live_edges(&rstate);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "coalescing\n");
|
||||
#endif
|
||||
/* Compute the interference graph */
|
||||
walk_variable_lifetimes(
|
||||
state, rstate.blocks, graph_ins, &rstate);
|
||||
|
@ -13291,6 +13595,11 @@ static void allocate_registers(struct compile_state *state)
|
|||
state, rstate.blocks,
|
||||
print_interference_ins, &rstate);
|
||||
}
|
||||
#if DEBUG_CONSISTENCY
|
||||
/* Verify the interference graph */
|
||||
walk_variable_lifetimes(
|
||||
state, rstate.blocks, verify_graph_ins, &rstate);
|
||||
#endif
|
||||
|
||||
coalesced = coalesce_live_ranges(state, &rstate);
|
||||
} while(coalesced);
|
||||
|
@ -15745,8 +16054,8 @@ static int check_reg(struct compile_state *state,
|
|||
static const char *arch_reg_str(int reg)
|
||||
{
|
||||
static const char *regs[] = {
|
||||
"%bad_register",
|
||||
"%bad_register2",
|
||||
"%unset",
|
||||
"%unneeded",
|
||||
"%eflags",
|
||||
"%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
|
||||
"%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
|
||||
|
@ -16487,28 +16796,42 @@ static void print_instructions(struct compile_state *state)
|
|||
{
|
||||
struct triple *first, *ins;
|
||||
int print_location;
|
||||
int last_line;
|
||||
int last_col;
|
||||
const char *last_filename;
|
||||
struct occurance *last_occurance;
|
||||
FILE *fp;
|
||||
print_location = 1;
|
||||
last_line = -1;
|
||||
last_col = -1;
|
||||
last_filename = 0;
|
||||
last_occurance = 0;
|
||||
fp = state->output;
|
||||
fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
|
||||
first = RHS(state->main_function, 0);
|
||||
ins = first;
|
||||
do {
|
||||
if (print_location &&
|
||||
((last_filename != ins->filename) ||
|
||||
(last_line != ins->line) ||
|
||||
(last_col != ins->col))) {
|
||||
fprintf(fp, "\t/* %s:%d */\n",
|
||||
ins->filename, ins->line);
|
||||
last_filename = ins->filename;
|
||||
last_line = ins->line;
|
||||
last_col = ins->col;
|
||||
if (print_location &&
|
||||
last_occurance != ins->occurance) {
|
||||
if (!ins->occurance->parent) {
|
||||
fprintf(fp, "\t/* %s,%s:%d.%d */\n",
|
||||
ins->occurance->function,
|
||||
ins->occurance->filename,
|
||||
ins->occurance->line,
|
||||
ins->occurance->col);
|
||||
}
|
||||
else {
|
||||
struct occurance *ptr;
|
||||
fprintf(fp, "\t/*\n");
|
||||
for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
|
||||
fprintf(fp, "\t * %s,%s:%d.%d\n",
|
||||
ptr->function,
|
||||
ptr->filename,
|
||||
ptr->line,
|
||||
ptr->col);
|
||||
}
|
||||
fprintf(fp, "\t */\n");
|
||||
|
||||
}
|
||||
if (last_occurance) {
|
||||
put_occurance(last_occurance);
|
||||
}
|
||||
get_occurance(ins->occurance);
|
||||
last_occurance = ins->occurance;
|
||||
}
|
||||
|
||||
print_instruction(state, ins, fp);
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
typedef __builtin_msr_t msr_t;
|
||||
|
||||
static msr_t rdmsr(unsigned long index)
|
||||
{
|
||||
return __builtin_rdmsr(index);
|
||||
}
|
||||
|
||||
static void uart_tx_byte(unsigned char data)
|
||||
{
|
||||
while(!(__builtin_inb(0x3f8 + 0x05) & 0x20))
|
||||
;
|
||||
__builtin_outb(data, 0x3f8 + 0x00);
|
||||
|
||||
while(!(__builtin_inb(0x3f8 + 0x05) & 0x40))
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
static void print_nibble(unsigned nibble)
|
||||
{
|
||||
unsigned char digit;
|
||||
digit = nibble + '0';
|
||||
if (digit > '9') {
|
||||
digit += 39;
|
||||
}
|
||||
uart_tx_byte(digit);
|
||||
}
|
||||
|
||||
static void print_debug_hex32(unsigned int value)
|
||||
{
|
||||
print_nibble((value >> 28U) & 0x0fU);
|
||||
print_nibble((value >> 24U) & 0x0fU);
|
||||
print_nibble((value >> 20U) & 0x0fU);
|
||||
print_nibble((value >> 16U) & 0x0fU);
|
||||
print_nibble((value >> 12U) & 0x0fU);
|
||||
print_nibble((value >> 8U) & 0x0fU);
|
||||
print_nibble((value >> 4U) & 0x0fU);
|
||||
print_nibble(value & 0x0fU);
|
||||
}
|
||||
|
||||
static void print_debug(const char *str)
|
||||
{
|
||||
unsigned char ch;
|
||||
while((ch = *str++) != '\0') {
|
||||
uart_tx_byte(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static void main(void)
|
||||
{
|
||||
unsigned long start, stop;
|
||||
msr_t msr;
|
||||
msr = rdmsr(0xC001001A);
|
||||
print_debug("TOP_MEM: ");
|
||||
print_debug_hex32(msr.hi);
|
||||
print_debug_hex32(msr.lo);
|
||||
print_debug("\r\n");
|
||||
|
||||
start = 0;
|
||||
stop = msr.lo;
|
||||
print_debug("Testing DRAM : ");
|
||||
print_debug_hex32(start);
|
||||
print_debug("-");
|
||||
print_debug_hex32(stop);
|
||||
print_debug("\r\n");
|
||||
|
||||
print_debug("DRAM verify: ");
|
||||
print_debug_hex32(start);
|
||||
print_debug_hex32(stop);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
static void main(void)
|
||||
{
|
||||
__builtin_msr_t msr;
|
||||
msr = __builtin_rdmsr(0xC001001A);
|
||||
while(__builtin_inb(0x3fd))
|
||||
;
|
||||
__builtin_outb(msr.hi, 0x3f8);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
static void order_dimms(void)
|
||||
{
|
||||
unsigned long tom;
|
||||
|
||||
tom = 0;
|
||||
for(;;) {
|
||||
|
||||
unsigned csbase, csmask;
|
||||
unsigned size;
|
||||
unsigned index;
|
||||
csbase = 0;
|
||||
|
||||
for(index = 0; index < 1; index++) {
|
||||
csbase = __builtin_inl(0x40);
|
||||
}
|
||||
if (csbase == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
size = csbase;
|
||||
|
||||
csbase = (tom << 21);
|
||||
|
||||
tom += size;
|
||||
|
||||
|
||||
csmask = size;
|
||||
csmask |= 0xfe00;
|
||||
|
||||
|
||||
__builtin_outl(csbase, 0xCFC);
|
||||
|
||||
__builtin_outl(0xc260, 0xCF8);
|
||||
__builtin_outl(csmask, 0xCFC);
|
||||
}
|
||||
|
||||
tom &= ~0xff000000;
|
||||
|
||||
__builtin_outl(tom, 0x1234);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
static void main(void)
|
||||
{
|
||||
unsigned csbase, csmask;
|
||||
|
||||
csbase = 0x40;
|
||||
csmask = 0xfe00;
|
||||
|
||||
__builtin_outl(csbase, 0x40);
|
||||
__builtin_outl(csmask, 0x60);
|
||||
}
|
Loading…
Reference in New Issue