It doesn't really make a lot of sense to have BURG nonterminal names different
to register classes, so combine them. Refactor the map code.
This commit is contained in:
parent
3a973a19f3
commit
4a3a9a98dc
|
@ -17,7 +17,7 @@
|
|||
#include "em_flag.h"
|
||||
#include "em_ptyp.h"
|
||||
#include "array.h"
|
||||
#include "map.h"
|
||||
#include "pmap.h"
|
||||
#include "diagnostics.h"
|
||||
#include "astring.h"
|
||||
#include "ir.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "mcg.h"
|
||||
|
||||
static MAPOF(struct basicblock, struct basicblock) graph;
|
||||
static PMAPOF(struct basicblock, struct basicblock) graph;
|
||||
static ARRAYOF(struct ir) pops;
|
||||
static ARRAYOF(struct ir) pushes;
|
||||
|
||||
|
@ -46,7 +46,7 @@ static bool collect_outputs_cb(struct ir* ir, void* user)
|
|||
struct basicblock* caller = user;
|
||||
|
||||
if (ir->opcode == IR_BLOCK)
|
||||
map_addp(&graph, caller, ir->u.bvalue);
|
||||
pmap_add(&graph, caller, ir->u.bvalue);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,96 +1,102 @@
|
|||
REGISTERS
|
||||
|
||||
r0 reg4 i ret0;
|
||||
r1 reg4 i;
|
||||
r2 reg4 i;
|
||||
r3 reg4 i;
|
||||
r4 reg4 i;
|
||||
r5 reg4 i;
|
||||
r6 reg4 i;
|
||||
r7 reg4 i;
|
||||
r8 reg4 i;
|
||||
r9 reg4 i;
|
||||
r10 reg4 i;
|
||||
r11 reg4 i;
|
||||
r0 any int ret;
|
||||
r1 any int;
|
||||
r2 any int;
|
||||
r3 any int;
|
||||
r4 any int;
|
||||
r5 any int;
|
||||
r6 any int;
|
||||
r7 any int;
|
||||
r8 any int;
|
||||
r9 any int;
|
||||
r10 any int;
|
||||
r11 any int;
|
||||
|
||||
s0 reg4 f;
|
||||
s1 reg4 f;
|
||||
s2 reg4 f;
|
||||
s3 reg4 f;
|
||||
s4 reg4 f;
|
||||
s5 reg4 f;
|
||||
s6 reg4 f;
|
||||
s7 reg4 f;
|
||||
s8 reg4 f;
|
||||
s9 reg4 f;
|
||||
s0 any float;
|
||||
s1 any float;
|
||||
s2 any float;
|
||||
s3 any float;
|
||||
s4 any float;
|
||||
s5 any float;
|
||||
s6 any float;
|
||||
s7 any float;
|
||||
s8 any float;
|
||||
s9 any float;
|
||||
|
||||
cc cc;
|
||||
|
||||
cc conditioncode;
|
||||
|
||||
DECLARATIONS
|
||||
|
||||
address fragment;
|
||||
aluparam fragment;
|
||||
reg allocates(reg4);
|
||||
tristate allocates(conditioncode);
|
||||
bistate allocates(conditioncode);
|
||||
|
||||
|
||||
PATTERNS
|
||||
|
||||
/* Special */
|
||||
|
||||
reg;
|
||||
|
||||
reg = REG4;
|
||||
int;
|
||||
float;
|
||||
|
||||
PAIR(BLOCK4, BLOCK4);
|
||||
|
||||
|
||||
/* Miscellaneous special things */
|
||||
|
||||
PUSH4(in:reg)
|
||||
PUSH4(in:int)
|
||||
emit "push %in"
|
||||
cost 4;
|
||||
|
||||
reg = POP4
|
||||
emit "pop %reg"
|
||||
int = POP4
|
||||
emit "pop %int"
|
||||
cost 4;
|
||||
|
||||
RET
|
||||
emit "ret"
|
||||
cost 4;
|
||||
|
||||
SETRET4(in:reg)
|
||||
SETRET4(in:ret)
|
||||
emit "mov r0, %in"
|
||||
cost 4;
|
||||
|
||||
int = REG4 cost 1;
|
||||
float = REG4 cost 1;
|
||||
|
||||
any = int cost 1;
|
||||
int = any cost 1;
|
||||
any = float cost 1;
|
||||
float = any cost 1;
|
||||
|
||||
|
||||
/* Memory operations */
|
||||
|
||||
STORE4(addr:address, value:reg)
|
||||
STORE4(addr:address, value:int)
|
||||
emit "str %value, %addr"
|
||||
cost 4;
|
||||
|
||||
reg = LOAD4(addr:address)
|
||||
emit "ldr %reg, %addr"
|
||||
int = LOAD4(addr:address)
|
||||
emit "ldr %int, %addr"
|
||||
cost 4;
|
||||
|
||||
reg = LOAD1(addr:address)
|
||||
emit "ldrb %reg, %addr"
|
||||
int = LOAD1(addr:address)
|
||||
emit "ldrb %int, %addr"
|
||||
cost 4;
|
||||
|
||||
reg = CIU14(LOAD1(addr:address))
|
||||
emit "ldrb %reg, %addr"
|
||||
int = CIU14(LOAD1(addr:address))
|
||||
emit "ldrb %int, %addr"
|
||||
cost 4;
|
||||
|
||||
reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
|
||||
emit "ldrsb %reg, %addr"
|
||||
int = CII14(CIU41(CIU14(LOAD1(addr:address))))
|
||||
emit "ldrsb %int, %addr"
|
||||
cost 4;
|
||||
|
||||
|
||||
/* Locals */
|
||||
|
||||
reg = in:LOCAL4
|
||||
emit "add %reg, fp, #$in"
|
||||
int = in:LOCAL4
|
||||
emit "add %int, fp, #$in"
|
||||
cost 4;
|
||||
|
||||
address = in:LOCAL4
|
||||
|
@ -99,10 +105,10 @@ PATTERNS
|
|||
|
||||
/* Memory addressing modes */
|
||||
|
||||
address = ADD4(addr:reg, offset:CONST4)
|
||||
address = ADD4(addr:int, offset:CONST4)
|
||||
emit "[%addr, #$offset]";
|
||||
|
||||
address = addr:reg
|
||||
address = addr:int
|
||||
emit "[%addr]";
|
||||
|
||||
|
||||
|
@ -112,12 +118,7 @@ PATTERNS
|
|||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
|
||||
emit "beq $true"
|
||||
emit "b $false"
|
||||
cost 8;
|
||||
|
||||
CJUMPEQ(value:bistate, PAIR(true:BLOCK4, false:BLOCK4))
|
||||
CJUMPEQ(value:cc, PAIR(true:BLOCK4, false:BLOCK4))
|
||||
emit "beq $true"
|
||||
emit "b $false"
|
||||
cost 8;
|
||||
|
@ -125,72 +126,67 @@ PATTERNS
|
|||
|
||||
/* Comparisons */
|
||||
|
||||
tristate = COMPARES4(left:reg, right:aluparam)
|
||||
cc = COMPARES4(left:int, right:aluparam)
|
||||
emit "cmp %left, %right"
|
||||
cost 4;
|
||||
|
||||
bistate = COMPARES4(COMPARES4(left:reg, right:aluparam), CONST4)
|
||||
cc = COMPARES4(COMPARES4(left:int, right:aluparam), CONST4)
|
||||
emit "cmp %left, %right"
|
||||
cost 4;
|
||||
|
||||
reg = tristate
|
||||
emit "mov %reg, #0"
|
||||
emit "movlt %reg, #-1"
|
||||
emit "movgt %reg, #1"
|
||||
int = cc
|
||||
emit "mov %int, #0"
|
||||
emit "movlt %int, #-1"
|
||||
emit "movgt %int, #1"
|
||||
cost 12;
|
||||
|
||||
reg = bistate
|
||||
emit "moveq %reg, #1"
|
||||
emit "movne %reg, #0"
|
||||
cost 8;
|
||||
|
||||
|
||||
/* Conversions */
|
||||
|
||||
reg = CII14(CIU41(value:reg))
|
||||
emit "sxtb %reg, %value"
|
||||
int = CII14(CIU41(value:int))
|
||||
emit "sxtb %int, %value"
|
||||
cost 4;
|
||||
|
||||
reg = CIU41(in:reg)
|
||||
emit "and %reg, %in, #0xff"
|
||||
int = CIU41(in:int)
|
||||
emit "and %int, %in, #0xff"
|
||||
cost 4;
|
||||
|
||||
|
||||
/* ALU operations */
|
||||
|
||||
reg = ADD4(left:reg, right:aluparam)
|
||||
emit "add %reg, %left, %right"
|
||||
int = ADD4(left:int, right:aluparam)
|
||||
emit "add %int, %left, %right"
|
||||
cost 4;
|
||||
|
||||
reg = ADD4(left:aluparam, right:reg)
|
||||
emit "add %reg, %right, %left"
|
||||
int = ADD4(left:aluparam, right:int)
|
||||
emit "add %int, %right, %left"
|
||||
cost 4;
|
||||
|
||||
aluparam = value:CONST4
|
||||
emit "#$value";
|
||||
|
||||
aluparam = value:reg
|
||||
aluparam = value:int
|
||||
emit "%value";
|
||||
|
||||
reg = value:aluparam
|
||||
emit "mov %reg, %value"
|
||||
int = value:aluparam
|
||||
emit "mov %int, %value"
|
||||
cost 4;
|
||||
|
||||
reg = value:LABEL4
|
||||
emit "adr %reg, $value"
|
||||
int = value:LABEL4
|
||||
emit "adr %int, $value"
|
||||
cost 4;
|
||||
|
||||
reg = value:BLOCK4
|
||||
emit "adr %reg, $value"
|
||||
int = value:BLOCK4
|
||||
emit "adr %int, $value"
|
||||
cost 4;
|
||||
|
||||
reg = value:CONST4
|
||||
emit "ldr %reg, #$value"
|
||||
any = value:CONST4
|
||||
emit "ldr %any, address-containing-$value"
|
||||
cost 8;
|
||||
|
||||
/* FPU operations */
|
||||
|
||||
reg = ADDF4(left:reg, right:reg)
|
||||
emit "fadds %reg, %left, %right"
|
||||
float = ADDF4(left:float, right:float)
|
||||
emit "fadds %float, %left, %right"
|
||||
cost 4;
|
||||
|
||||
|
|
|
@ -56,3 +56,19 @@ void imap_add(void* mapp, int left, void* right)
|
|||
append(map, left, right);
|
||||
}
|
||||
|
||||
void* imap_get(void* mapp, int left)
|
||||
{
|
||||
struct imap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct imap_node* node = &map->item[i];
|
||||
if (node->left == left)
|
||||
return node->right;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ struct imap
|
|||
|
||||
extern void imap_put(void* map, int left, void* right);
|
||||
extern void imap_add(void* map, int left, void* right);
|
||||
extern void* imap_get(void* map, int left);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
|
||||
struct map_node
|
||||
{
|
||||
void* left;
|
||||
void* right;
|
||||
};
|
||||
|
||||
/* Danger, Will Robinson! The type and the macro must be compatible. */
|
||||
|
||||
struct map
|
||||
{
|
||||
struct map_node* item;
|
||||
int count;
|
||||
int max;
|
||||
};
|
||||
|
||||
#define MAPOF(LEFT, RIGHT) \
|
||||
struct { \
|
||||
struct { LEFT* left; RIGHT* right; }* item; \
|
||||
int count; \
|
||||
int max; \
|
||||
}
|
||||
|
||||
extern void map_putp(void* map, void* left, void* right);
|
||||
extern void map_addp(void* map, void* left, void* right);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "map.h"
|
||||
#include "pmap.h"
|
||||
|
||||
static void append(void* mapp, void* left, void* right)
|
||||
{
|
||||
struct map* map = mapp;
|
||||
struct map_node* node;
|
||||
struct pmap* map = mapp;
|
||||
struct pmap_node* node;
|
||||
|
||||
if (map->count == map->max)
|
||||
{
|
||||
int newmax = (map->max == 0) ? 8 : (map->max * 2);
|
||||
struct map_node* newarray = realloc(map->item, newmax * sizeof(*newarray));
|
||||
struct pmap_node* newarray = realloc(map->item, newmax * sizeof(*newarray));
|
||||
|
||||
map->max = newmax;
|
||||
map->item = newarray;
|
||||
|
@ -23,14 +23,14 @@ static void append(void* mapp, void* left, void* right)
|
|||
node->right = right;
|
||||
}
|
||||
|
||||
void map_putp(void* mapp, void* left, void* right)
|
||||
void pmap_put(void* mapp, void* left, void* right)
|
||||
{
|
||||
struct map* map = mapp;
|
||||
struct pmap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct map_node* node = &map->item[i];
|
||||
struct pmap_node* node = &map->item[i];
|
||||
if (node->left == left)
|
||||
{
|
||||
node->right = right;
|
||||
|
@ -41,14 +41,14 @@ void map_putp(void* mapp, void* left, void* right)
|
|||
append(map, left, right);
|
||||
}
|
||||
|
||||
void map_addp(void* mapp, void* left, void* right)
|
||||
void pmap_add(void* mapp, void* left, void* right)
|
||||
{
|
||||
struct map* map = mapp;
|
||||
struct pmap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct map_node* node = &map->item[i];
|
||||
struct pmap_node* node = &map->item[i];
|
||||
if ((node->left == left) && (node->right == right))
|
||||
return;
|
||||
}
|
||||
|
@ -56,3 +56,19 @@ void map_addp(void* mapp, void* left, void* right)
|
|||
append(map, left, right);
|
||||
}
|
||||
|
||||
void* pmap_get(void* mapp, void* left)
|
||||
{
|
||||
struct pmap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct pmap_node* node = &map->item[i];
|
||||
if (node->left == left)
|
||||
return node->right;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
31
modules/src/data/pmap.h
Normal file
31
modules/src/data/pmap.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef PMAP_H
|
||||
#define PMAP_H
|
||||
|
||||
struct pmap_node
|
||||
{
|
||||
void* left;
|
||||
void* right;
|
||||
};
|
||||
|
||||
/* Danger, Will Robinson! The type and the macro must be compatible. */
|
||||
|
||||
struct pmap
|
||||
{
|
||||
struct pmap_node* item;
|
||||
int count;
|
||||
int max;
|
||||
};
|
||||
|
||||
#define PMAPOF(LEFT, RIGHT) \
|
||||
struct { \
|
||||
struct { LEFT* left; RIGHT* right; }* item; \
|
||||
int count; \
|
||||
int max; \
|
||||
}
|
||||
|
||||
extern void pmap_put(void* map, void* left, void* right);
|
||||
extern void pmap_add(void* map, void* left, void* right);
|
||||
extern void* pmap_get(void* map, void* left);
|
||||
|
||||
#endif
|
||||
|
74
modules/src/data/smap.c
Normal file
74
modules/src/data/smap.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "smap.h"
|
||||
|
||||
static void append(void* mapp, const char* left, void* right)
|
||||
{
|
||||
struct smap* map = mapp;
|
||||
struct smap_node* node;
|
||||
|
||||
if (map->count == map->max)
|
||||
{
|
||||
int newmax = (map->max == 0) ? 8 : (map->max * 2);
|
||||
struct smap_node* newarray = realloc(map->item, newmax * sizeof(*newarray));
|
||||
|
||||
map->max = newmax;
|
||||
map->item = newarray;
|
||||
}
|
||||
|
||||
node = &map->item[map->count];
|
||||
map->count++;
|
||||
|
||||
node->left = left;
|
||||
node->right = right;
|
||||
}
|
||||
|
||||
void smap_put(void* mapp, const char* left, void* right)
|
||||
{
|
||||
struct smap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct smap_node* node = &map->item[i];
|
||||
if (strcmp(node->left, left) == 0)
|
||||
{
|
||||
node->right = right;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
append(map, left, right);
|
||||
}
|
||||
|
||||
void smap_add(void* mapp, const char* left, void* right)
|
||||
{
|
||||
struct smap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct smap_node* node = &map->item[i];
|
||||
if ((strcmp(node->left, left) == 0) && (node->right == right))
|
||||
return;
|
||||
}
|
||||
|
||||
append(map, left, right);
|
||||
}
|
||||
|
||||
void* smap_get(void* mapp, const char* left)
|
||||
{
|
||||
struct smap* map = mapp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map->count; i++)
|
||||
{
|
||||
struct smap_node* node = &map->item[i];
|
||||
if (strcmp(node->left, left) == 0)
|
||||
return node->right;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
31
modules/src/data/smap.h
Normal file
31
modules/src/data/smap.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef SMAP_H
|
||||
#define SMAP_H
|
||||
|
||||
struct smap_node
|
||||
{
|
||||
const char* left;
|
||||
void* right;
|
||||
};
|
||||
|
||||
/* Danger, Will Robinson! The type and the macro must be compatible. */
|
||||
|
||||
struct smap
|
||||
{
|
||||
struct smap_node* item;
|
||||
int count;
|
||||
int max;
|
||||
};
|
||||
|
||||
#define SMAPOF(RIGHT) \
|
||||
struct { \
|
||||
struct { const char* left; RIGHT* right; }* item; \
|
||||
int count; \
|
||||
int max; \
|
||||
}
|
||||
|
||||
extern void smap_put(void* map, const char* left, void* right);
|
||||
extern void smap_add(void* map, const char* left, void* right);
|
||||
extern void* smap_get(void* map, const char* left);
|
||||
|
||||
#endif
|
||||
|
|
@ -22,7 +22,7 @@ static int nextern = 1;
|
|||
Rule rule;
|
||||
struct reg* reg;
|
||||
struct stringlist* stringlist;
|
||||
char* stringpair[2];
|
||||
struct terminfo terminfo;
|
||||
}
|
||||
|
||||
%term ALLOCATES
|
||||
|
@ -48,7 +48,7 @@ static int nextern = 1;
|
|||
%type <rule> pattern
|
||||
%type <stringlist> cfragments
|
||||
%type <stringlist> qfragments
|
||||
%type <stringpair> labelledid
|
||||
%type <terminfo> terminfo
|
||||
%type <tree> rhs
|
||||
%%
|
||||
|
||||
|
@ -106,14 +106,16 @@ pattern
|
|||
;
|
||||
|
||||
rhs
|
||||
: labelledid { $$ = tree($1[1], $1[0], NULL, NULL); }
|
||||
| labelledid '(' rhs ')' { $$ = tree($1[1], $1[0], $3, NULL); }
|
||||
| labelledid '(' rhs ',' rhs ')' { $$ = tree($1[1], $1[0], $3, $5); }
|
||||
: terminfo { $$ = tree(&$1, NULL, NULL); }
|
||||
| terminfo '(' rhs ')' { $$ = tree(&$1, $3, NULL); }
|
||||
| terminfo '(' rhs ',' rhs ')' { $$ = tree(&$1, $3, $5); }
|
||||
;
|
||||
|
||||
labelledid
|
||||
: ID { $$[0] = NULL; $$[1] = $1; }
|
||||
| ID ':' ID { $$[0] = $1; $$[1] = $3; }
|
||||
terminfo
|
||||
: ID { $$.name = $1; }
|
||||
| ID '.' ID { $$.name = $1; $$.regattr = $3; }
|
||||
| ID ':' ID { $$.label = $1; $$.name = $3; }
|
||||
| ID ':' ID '.' ID { $$.label = $1; $$.name = $3; $$.regattr = $5; }
|
||||
;
|
||||
|
||||
cfragments
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include "iburg.h"
|
||||
#include "ircodes.h"
|
||||
#include "astring.h"
|
||||
#include "smap.h"
|
||||
|
||||
static char rcsid[] = "$Id$";
|
||||
|
||||
|
@ -21,13 +23,14 @@ static char* prefix = "burm";
|
|||
static int Tflag = 1; /* tracing */
|
||||
static int ntnumber = 0;
|
||||
static Nonterm start = 0;
|
||||
static struct reg* regs = NULL;
|
||||
static struct regclass* regclasses = NULL;
|
||||
static Term terms;
|
||||
static Nonterm nts;
|
||||
static Rule rules;
|
||||
static int nrules;
|
||||
|
||||
static SMAPOF(struct reg) registers;
|
||||
static SMAPOF(struct regclass) registerclasses;
|
||||
|
||||
static void print(char* fmt, ...);
|
||||
static void ckreach(Nonterm p);
|
||||
static void registerterminals(void);
|
||||
|
@ -44,8 +47,8 @@ static void emitleaf(Term p, int ntnumber);
|
|||
static void emitnts(Rule rules, int nrules);
|
||||
static void emitpredicatedefinitions(Rule rules);
|
||||
static void emitrecord(char* pre, Rule r, int cost);
|
||||
static void emitregisterclasses(struct regclass* rc);
|
||||
static void emitregisters(struct reg* regs);
|
||||
static void emitregisterclasses();
|
||||
static void emitregisters();
|
||||
static void emitrule(Nonterm nts);
|
||||
static void emitstate(Term terms, Nonterm start, int ntnumber);
|
||||
static void emitstring(Rule rules);
|
||||
|
@ -128,12 +131,14 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (start)
|
||||
ckreach(start);
|
||||
#if 0
|
||||
for (p = nts; p; p = p->link)
|
||||
if (!p->reached)
|
||||
yyerror("can't reach non-terminal `%s'\n", p->name);
|
||||
#endif
|
||||
|
||||
emitregisterclasses(regclasses);
|
||||
emitregisters(regs);
|
||||
emitregisterclasses();
|
||||
emitregisters();
|
||||
emitdefs(nts, ntnumber);
|
||||
emitstruct(nts, ntnumber);
|
||||
emitnts(rules, nrules);
|
||||
|
@ -230,52 +235,40 @@ static void* install(const char* name)
|
|||
|
||||
struct reg* makereg(const char* id)
|
||||
{
|
||||
struct reg* p = lookup(id);
|
||||
struct reg** q = ®s;
|
||||
struct reg* p = smap_get(®isters, id);
|
||||
static int number = 1;
|
||||
|
||||
if (p)
|
||||
yyerror("redefinition of '%s'", id);
|
||||
p = install(id);
|
||||
p->kind = REG;
|
||||
p = calloc(1, sizeof(*p));
|
||||
p->name = id;
|
||||
p->number = number++;
|
||||
smap_put(®isters, id, p);
|
||||
|
||||
while (*q && (*q)->number < p->number)
|
||||
q = &(*q)->link;
|
||||
assert(*q == 0 || (*q)->number != p->number);
|
||||
p->link = *q;
|
||||
*q = p;
|
||||
return p;
|
||||
}
|
||||
|
||||
void addregclass(struct reg* reg, const char* id)
|
||||
{
|
||||
struct regclass* p = lookup(id);
|
||||
struct regclass** q = ®classes;
|
||||
struct regclass* p = smap_get(®isterclasses, id);
|
||||
static int number = 1;
|
||||
|
||||
if (p && (p->kind != REGCLASS))
|
||||
yyerror("redefinition of '%s' as something else\n", id);
|
||||
if (!p)
|
||||
{
|
||||
p = install(id);
|
||||
p->kind = REGCLASS;
|
||||
p = calloc(1, sizeof(*p));
|
||||
p->name = id;
|
||||
p->number = number++;
|
||||
|
||||
while (*q && (*q)->number < p->number)
|
||||
q = &(*q)->link;
|
||||
assert(*q == 0 || (*q)->number != p->number);
|
||||
p->link = *q;
|
||||
*q = p;
|
||||
smap_put(®isterclasses, id, p);
|
||||
}
|
||||
|
||||
reg->classes |= 1<<(p->number);
|
||||
nonterm(id, true);
|
||||
}
|
||||
|
||||
struct regclass* getregclass(const char* id)
|
||||
{
|
||||
struct regclass* p = lookup(id);
|
||||
if (!p || (p->kind != REGCLASS))
|
||||
struct regclass* p = smap_get(®isterclasses, id);
|
||||
if (!p)
|
||||
yyerror("'%s' is not the name of a register class", id);
|
||||
return p;
|
||||
}
|
||||
|
@ -333,10 +326,10 @@ Term term(const char* id, int esn)
|
|||
}
|
||||
|
||||
/* tree - create & initialize a tree node with the given fields */
|
||||
Tree tree(const char* id, const char* label, Tree left, Tree right)
|
||||
Tree tree(struct terminfo* ti, Tree left, Tree right)
|
||||
{
|
||||
Tree t = calloc(1, sizeof *t);
|
||||
Term p = lookup(id);
|
||||
Term p = lookup(ti->name);
|
||||
int arity = 0;
|
||||
|
||||
if (left && right)
|
||||
|
@ -345,22 +338,22 @@ Tree tree(const char* id, const char* label, Tree left, Tree right)
|
|||
arity = 1;
|
||||
if (p == NULL && arity > 0)
|
||||
{
|
||||
yyerror("undefined terminal `%s'\n", id);
|
||||
p = term(id, -1);
|
||||
yyerror("undefined terminal `%s'\n", ti->name);
|
||||
p = term(ti->name, -1);
|
||||
}
|
||||
else if (p == NULL && arity == 0)
|
||||
p = (Term)nonterm(id, false);
|
||||
p = (Term)nonterm(ti->name, false);
|
||||
else if (p && p->kind == NONTERM && arity > 0)
|
||||
{
|
||||
yyerror("`%s' is a non-terminal\n", id);
|
||||
p = term(id, -1);
|
||||
yyerror("`%s' is a non-terminal\n", ti->name);
|
||||
p = term(ti->name, -1);
|
||||
}
|
||||
if (p->kind == TERM && p->arity == -1)
|
||||
p->arity = arity;
|
||||
if (p->kind == TERM && arity != p->arity)
|
||||
yyerror("inconsistent arity for terminal `%s'\n", id);
|
||||
yyerror("inconsistent arity for terminal `%s'\n", ti->name);
|
||||
t->op = p;
|
||||
t->label = label;
|
||||
t->label = ti->label;
|
||||
t->nterms = p->kind == TERM;
|
||||
if (t->left = left)
|
||||
t->nterms += left->nterms;
|
||||
|
@ -423,6 +416,10 @@ static void print(char* fmt, ...)
|
|||
fprintf(outfp, "%x", va_arg(ap, uint32_t));
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
fprintf(outfp, "0x%" PRIx64 "ULL", va_arg(ap, uint64_t));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
fputs(va_arg(ap, char*), outfp);
|
||||
break;
|
||||
|
@ -503,34 +500,34 @@ static void ckreach(Nonterm p)
|
|||
reach(r->pattern);
|
||||
}
|
||||
|
||||
static void emitregisterclasses(struct regclass* rc)
|
||||
static void emitregisterclasses(void)
|
||||
{
|
||||
int k = 0;
|
||||
int i;
|
||||
|
||||
print("const char* %Pregister_class_names[] = {\n");
|
||||
while (rc)
|
||||
print("%1NULL,\n"); /* register class id 0 is invalid */
|
||||
for (i=0; i<registerclasses.count; i++)
|
||||
{
|
||||
for (; k < rc->number; k++)
|
||||
print("%1NULL,\n");
|
||||
k++;
|
||||
struct regclass* rc = registerclasses.item[i].right;
|
||||
assert(rc->number == (i+1));
|
||||
|
||||
print("%1\"%s\",\n", rc->name);
|
||||
rc = rc->link;
|
||||
}
|
||||
print("};\n\n");
|
||||
}
|
||||
|
||||
static void emitregisters(struct reg* r)
|
||||
static void emitregisters(void)
|
||||
{
|
||||
int k = 0;
|
||||
print("const struct %Pregister_data %Pregister_data[] = {\n");
|
||||
while (r)
|
||||
{
|
||||
for (; k < r->number; k++)
|
||||
print("%1{ 0 },\n");
|
||||
k++;
|
||||
int i;
|
||||
|
||||
print("%1{ \"%s\", %d },\n", r->name, r->classes);
|
||||
r = r->link;
|
||||
print("const struct %Pregister_data %Pregister_data[] = {\n");
|
||||
print("%1{ 0 },\n"); /* register id 0 is invalid */
|
||||
for (i=0; i<registers.count; i++)
|
||||
{
|
||||
struct reg* r = registers.item[i].right;
|
||||
assert(r->number == (i+1));
|
||||
|
||||
print("%1{ \"%s\", %X },\n", r->name, r->classes);
|
||||
}
|
||||
print("};\n\n");
|
||||
}
|
||||
|
|
|
@ -15,21 +15,24 @@ typedef enum
|
|||
typedef struct rule* Rule;
|
||||
typedef struct term* Term;
|
||||
|
||||
struct terminfo
|
||||
{
|
||||
const char* name;
|
||||
const char* label;
|
||||
const char* regattr;
|
||||
};
|
||||
|
||||
struct reg
|
||||
{
|
||||
const char* name; /* register name */
|
||||
Kind kind; /* REG */
|
||||
int number; /* identifying number */
|
||||
uint32_t classes; // bitfield of classes */
|
||||
struct reg* link; /* next in list */
|
||||
uint64_t classes; // bitfield of classes */
|
||||
};
|
||||
|
||||
struct regclass
|
||||
{
|
||||
const char* name; /* class name */
|
||||
Kind kind; /* REGCLASS */
|
||||
int number; /* identifying number */
|
||||
struct regclass* link; /* next in list */
|
||||
};
|
||||
|
||||
extern struct reg* makereg(const char* name);
|
||||
|
@ -72,7 +75,7 @@ struct tree
|
|||
Tree left, right; /* operands */
|
||||
int nterms; /* number of terminal nodes in this tree */
|
||||
};
|
||||
extern Tree tree(const char* op, const char* label, Tree left, Tree right);
|
||||
extern Tree tree(struct terminfo* ti, Tree left, Tree right);
|
||||
|
||||
struct rule
|
||||
{ /* rules: */
|
||||
|
|
Loading…
Reference in a new issue