Add parsing support for register aliases.
This commit is contained in:
		
							parent
							
								
									e4fec71f9c
								
							
						
					
					
						commit
						d6984d60ac
					
				
					 5 changed files with 59 additions and 8 deletions
				
			
		|  | @ -25,6 +25,7 @@ extern int yylex(void); | |||
|     struct constraint* constraint; | ||||
| } | ||||
| 
 | ||||
| %term ALIASES | ||||
| %term COPY | ||||
| %term CORRUPTED | ||||
| %term COST | ||||
|  | @ -43,6 +44,7 @@ extern int yylex(void); | |||
| %token <string>     ID | ||||
| %token <string>     QFRAGMENT | ||||
| 
 | ||||
| %type  <stringlist> aliases; | ||||
| %type  <constraint> constraint | ||||
| %type  <constraint> constraints | ||||
| %type  <expr>       predicate | ||||
|  | @ -72,10 +74,16 @@ registers | |||
| 
 | ||||
| register | ||||
|     : ID QFRAGMENT                    { $$ = makereg($1, $2); } | ||||
|     | register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); } | ||||
|     | register ID                     { $$ = $1; addregattr($1, $2, false); } | ||||
|     | register ID '!'                 { $$ = $1; addregattr($1, $2, true); } | ||||
|     ; | ||||
| 
 | ||||
| aliases | ||||
|     : ID                              { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); } | ||||
|     | aliases ',' ID                  { $$ = $1; stringlist_add($$, $3); } | ||||
|     ; | ||||
| 
 | ||||
| declarations | ||||
|     : /* nothing */ | ||||
|     | declarations declaration ';' | ||||
|  |  | |||
|  | @ -279,6 +279,7 @@ struct reg* makereg(const char* id, const char* realname) | |||
| 	p->name = id; | ||||
| 	p->realname = realname; | ||||
| 	p->number = number++; | ||||
| 	array_append(&p->aliases, p); | ||||
| 	smap_put(®isters, id, p); | ||||
| 
 | ||||
| 	return p; | ||||
|  | @ -311,6 +312,34 @@ void addregattr(struct reg* reg, const char* id, bool exact) | |||
| 		reg->type |= 1<<(p->number); | ||||
| } | ||||
| 
 | ||||
| void addregalias(struct reg* r1, struct reg* r2) | ||||
| { | ||||
| 	if (!array_appendu(&r1->aliases, r2)) | ||||
| 	{ | ||||
| 		int i; | ||||
| 
 | ||||
| 		for (i=0; i<r1->aliases.count; i++) | ||||
| 			addregalias(r1->aliases.item[i], r2); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void addregaliases(struct reg* reg, struct stringlist* aliases) | ||||
| { | ||||
| 	struct stringfragment* f = aliases->first; | ||||
| 
 | ||||
| 	while (f) | ||||
| 	{ | ||||
| 		struct reg* r = smap_get(®isters, f->data); | ||||
| 		if (!r) | ||||
| 			yyerror("register '%s' is not defined here", f->data); | ||||
| 
 | ||||
| 		array_appendu(®->aliases, r); | ||||
| 		array_appendu(&r->aliases, reg); | ||||
| 
 | ||||
| 		f = f->next; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct regattr* getregattr(const char* id) | ||||
| { | ||||
| 	struct regattr* p = smap_get(®isterattrs, id); | ||||
|  | @ -588,7 +617,17 @@ static void emitregisterattrs(void) | |||
| 
 | ||||
| static void emitregisters(void) | ||||
| { | ||||
| 	int i; | ||||
| 	int i, j; | ||||
| 
 | ||||
| 	for (i=0; i<registers.count; i++) | ||||
| 	{ | ||||
| 		struct reg* r = registers.item[i].right; | ||||
| 
 | ||||
| 		print("const struct %Pregister_data* %Pregister_aliases_%d_%s[] = {\n%1", i, r->name); | ||||
| 		for (j=0; j<r->aliases.count; j++) | ||||
| 			print("&%Pregister_data[%d], ", r->aliases.item[j]->number); | ||||
| 		print("NULL\n};\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	print("const struct %Pregister_data %Pregister_data[] = {\n"); | ||||
| 	for (i=0; i<registers.count; i++) | ||||
|  | @ -596,8 +635,8 @@ static void emitregisters(void) | |||
| 		struct reg* r = registers.item[i].right; | ||||
| 		assert(r->number == i); | ||||
| 
 | ||||
| 		print("%1{ \"%s\", \"%s\", 0x%x, 0x%x },\n", | ||||
| 			r->name, r->realname, r->type, r->attrs); | ||||
| 		print("%1{ \"%s\", \"%s\", 0x%x, 0x%x, %Pregister_aliases_%d_%s },\n", | ||||
| 			r->name, r->realname, r->type, r->attrs, i, r->name); | ||||
| 	} | ||||
| 	print("%1{ NULL }\n"); | ||||
| 	print("};\n\n"); | ||||
|  |  | |||
|  | @ -58,11 +58,12 @@ struct terminfo | |||
| 
 | ||||
| struct reg | ||||
| { | ||||
| 	const char* name;      /* friendly register name */ | ||||
| 	const char* realname;  /* name used in assembly output */ | ||||
| 	int number;            /* identifying number */ | ||||
| 	uint32_t attrs;        /* bitfield of register attributes */ | ||||
| 	uint32_t type;         /* register type */ | ||||
| 	const char* name;          /* friendly register name */ | ||||
| 	const char* realname;      /* name used in assembly output */ | ||||
| 	int number;                /* identifying number */ | ||||
| 	uint32_t attrs;            /* bitfield of register attributes */ | ||||
| 	uint32_t type;             /* register type */ | ||||
| 	ARRAYOF(struct reg) aliases; /* registers that this one aliases */ | ||||
| }; | ||||
| 
 | ||||
| struct regattr | ||||
|  | @ -73,6 +74,7 @@ struct regattr | |||
| 
 | ||||
| extern struct reg* makereg(const char* name, const char* realname); | ||||
| extern void addregattr(struct reg* reg, const char* regattr, bool exact); | ||||
| extern void addregaliases(struct reg* reg, struct stringlist* aliases); | ||||
| extern struct regattr* getregattr(const char* name); | ||||
| 
 | ||||
| struct term | ||||
|  |  | |||
|  | @ -67,6 +67,7 @@ struct burm_register_data | |||
|     const char* realname; | ||||
|     uint32_t type; | ||||
|     uint32_t attrs; | ||||
|     const struct burm_register_data** aliases; | ||||
| }; | ||||
| 
 | ||||
| extern const struct burm_register_data burm_register_data[]; | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ static int braces = 0; | |||
| "DECLARATIONS"              return DECLARATIONS; | ||||
| "PATTERNS"                  return PATTERNS; | ||||
| "REGISTERS"                 return REGISTERS; | ||||
| "aliases"                   return ALIASES; | ||||
| "corrupted"                 return CORRUPTED; | ||||
| "cost"                      return COST; | ||||
| "emit"                      return EMIT; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue