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; |     struct constraint* constraint; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | %term ALIASES | ||||||
| %term COPY | %term COPY | ||||||
| %term CORRUPTED | %term CORRUPTED | ||||||
| %term COST | %term COST | ||||||
|  | @ -43,6 +44,7 @@ extern int yylex(void); | ||||||
| %token <string>     ID | %token <string>     ID | ||||||
| %token <string>     QFRAGMENT | %token <string>     QFRAGMENT | ||||||
| 
 | 
 | ||||||
|  | %type  <stringlist> aliases; | ||||||
| %type  <constraint> constraint | %type  <constraint> constraint | ||||||
| %type  <constraint> constraints | %type  <constraint> constraints | ||||||
| %type  <expr>       predicate | %type  <expr>       predicate | ||||||
|  | @ -72,10 +74,16 @@ registers | ||||||
| 
 | 
 | ||||||
| register | register | ||||||
|     : ID QFRAGMENT                    { $$ = makereg($1, $2); } |     : ID QFRAGMENT                    { $$ = makereg($1, $2); } | ||||||
|  |     | register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); } | ||||||
|     | register ID                     { $$ = $1; addregattr($1, $2, false); } |     | register ID                     { $$ = $1; addregattr($1, $2, false); } | ||||||
|     | register ID '!'                 { $$ = $1; addregattr($1, $2, true); } |     | register ID '!'                 { $$ = $1; addregattr($1, $2, true); } | ||||||
|     ; |     ; | ||||||
| 
 | 
 | ||||||
|  | aliases | ||||||
|  |     : ID                              { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); } | ||||||
|  |     | aliases ',' ID                  { $$ = $1; stringlist_add($$, $3); } | ||||||
|  |     ; | ||||||
|  | 
 | ||||||
| declarations | declarations | ||||||
|     : /* nothing */ |     : /* nothing */ | ||||||
|     | declarations declaration ';' |     | declarations declaration ';' | ||||||
|  |  | ||||||
|  | @ -279,6 +279,7 @@ struct reg* makereg(const char* id, const char* realname) | ||||||
| 	p->name = id; | 	p->name = id; | ||||||
| 	p->realname = realname; | 	p->realname = realname; | ||||||
| 	p->number = number++; | 	p->number = number++; | ||||||
|  | 	array_append(&p->aliases, p); | ||||||
| 	smap_put(®isters, id, p); | 	smap_put(®isters, id, p); | ||||||
| 
 | 
 | ||||||
| 	return p; | 	return p; | ||||||
|  | @ -311,6 +312,34 @@ void addregattr(struct reg* reg, const char* id, bool exact) | ||||||
| 		reg->type |= 1<<(p->number); | 		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* getregattr(const char* id) | ||||||
| { | { | ||||||
| 	struct regattr* p = smap_get(®isterattrs, id); | 	struct regattr* p = smap_get(®isterattrs, id); | ||||||
|  | @ -588,7 +617,17 @@ static void emitregisterattrs(void) | ||||||
| 
 | 
 | ||||||
| static void emitregisters(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"); | 	print("const struct %Pregister_data %Pregister_data[] = {\n"); | ||||||
| 	for (i=0; i<registers.count; i++) | 	for (i=0; i<registers.count; i++) | ||||||
|  | @ -596,8 +635,8 @@ static void emitregisters(void) | ||||||
| 		struct reg* r = registers.item[i].right; | 		struct reg* r = registers.item[i].right; | ||||||
| 		assert(r->number == i); | 		assert(r->number == i); | ||||||
| 
 | 
 | ||||||
| 		print("%1{ \"%s\", \"%s\", 0x%x, 0x%x },\n", | 		print("%1{ \"%s\", \"%s\", 0x%x, 0x%x, %Pregister_aliases_%d_%s },\n", | ||||||
| 			r->name, r->realname, r->type, r->attrs); | 			r->name, r->realname, r->type, r->attrs, i, r->name); | ||||||
| 	} | 	} | ||||||
| 	print("%1{ NULL }\n"); | 	print("%1{ NULL }\n"); | ||||||
| 	print("};\n\n"); | 	print("};\n\n"); | ||||||
|  |  | ||||||
|  | @ -63,6 +63,7 @@ struct reg | ||||||
| 	int number;                /* identifying number */ | 	int number;                /* identifying number */ | ||||||
| 	uint32_t attrs;            /* bitfield of register attributes */ | 	uint32_t attrs;            /* bitfield of register attributes */ | ||||||
| 	uint32_t type;             /* register type */ | 	uint32_t type;             /* register type */ | ||||||
|  | 	ARRAYOF(struct reg) aliases; /* registers that this one aliases */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct regattr | struct regattr | ||||||
|  | @ -73,6 +74,7 @@ struct regattr | ||||||
| 
 | 
 | ||||||
| extern struct reg* makereg(const char* name, const char* realname); | extern struct reg* makereg(const char* name, const char* realname); | ||||||
| extern void addregattr(struct reg* reg, const char* regattr, bool exact); | 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); | extern struct regattr* getregattr(const char* name); | ||||||
| 
 | 
 | ||||||
| struct term | struct term | ||||||
|  |  | ||||||
|  | @ -67,6 +67,7 @@ struct burm_register_data | ||||||
|     const char* realname; |     const char* realname; | ||||||
|     uint32_t type; |     uint32_t type; | ||||||
|     uint32_t attrs; |     uint32_t attrs; | ||||||
|  |     const struct burm_register_data** aliases; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern const struct burm_register_data burm_register_data[]; | extern const struct burm_register_data burm_register_data[]; | ||||||
|  |  | ||||||
|  | @ -39,6 +39,7 @@ static int braces = 0; | ||||||
| "DECLARATIONS"              return DECLARATIONS; | "DECLARATIONS"              return DECLARATIONS; | ||||||
| "PATTERNS"                  return PATTERNS; | "PATTERNS"                  return PATTERNS; | ||||||
| "REGISTERS"                 return REGISTERS; | "REGISTERS"                 return REGISTERS; | ||||||
|  | "aliases"                   return ALIASES; | ||||||
| "corrupted"                 return CORRUPTED; | "corrupted"                 return CORRUPTED; | ||||||
| "cost"                      return COST; | "cost"                      return COST; | ||||||
| "emit"                      return EMIT; | "emit"                      return EMIT; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue