Abstract out the EM reader; skeleton of the tree builder.
This commit is contained in:
		
							parent
							
								
									2eee391aef
								
							
						
					
					
						commit
						24380e2a93
					
				
					 7 changed files with 446 additions and 232 deletions
				
			
		|  | @ -1,19 +1,7 @@ | ||||||
| #include <stdlib.h> | #include "mcg.h" | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdarg.h> |  | ||||||
| #include <assert.h> |  | ||||||
| #include "em.h" |  | ||||||
| #include "em_comp.h" | #include "em_comp.h" | ||||||
| #include "em_pseu.h" |  | ||||||
| #include "em_mnem.h" |  | ||||||
| #include "em_flag.h" |  | ||||||
| #include "em_ptyp.h" |  | ||||||
| 
 | 
 | ||||||
| extern char em_pseu[][4]; | void fatal(const char* msg, ...) | ||||||
| extern char em_mnem[][4]; |  | ||||||
| extern char em_flag[]; |  | ||||||
| 
 |  | ||||||
| static void fatal(const char* msg, ...) |  | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 	va_start(ap, msg); | 	va_start(ap, msg); | ||||||
|  | @ -22,226 +10,15 @@ static void fatal(const char* msg, ...) | ||||||
| 	fprintf(stderr, "\n"); | 	fprintf(stderr, "\n"); | ||||||
| 
 | 
 | ||||||
| 	va_end(ap); | 	va_end(ap); | ||||||
| 	exit(1); | 	abort(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char* type_to_str(int type) | int main(int argc, char* argv[]) | ||||||
| { | { | ||||||
| 	switch (type) |  | ||||||
| 	{ |  | ||||||
| 		case EM_MNEM:       return "EM_MNEM"; |  | ||||||
| 		case EM_PSEU:	    return "EM_PSEU"; |  | ||||||
| 		case EM_STARTMES:   return "EM_STARTMES"; |  | ||||||
| 		case EM_MESARG:     return "EM_MESARG"; |  | ||||||
| 		case EM_ENDMES:     return "EM_ENDMES"; |  | ||||||
| 		case EM_DEFILB:     return "EM_DEFILB"; |  | ||||||
| 		case EM_DEFDLB:     return "EM_DEFDLB"; |  | ||||||
| 		case EM_DEFDNAM:    return "EM_DEFDNAM"; |  | ||||||
| 		case EM_ERROR:      return "EM_ERROR"; |  | ||||||
| 		case EM_FATAL:      return "EM_FATAL"; |  | ||||||
| 		case EM_EOF:        return "EM_EOF"; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     assert(0 && "invalid EM type"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static const char* argtype_to_str(int type) |  | ||||||
| { |  | ||||||
|     if (type == 0)        return "..."; |  | ||||||
|     if (type == ilb_ptyp) return "ilb"; |  | ||||||
|     if (type == nof_ptyp) return "nof"; |  | ||||||
|     if (type == sof_ptyp) return "sof"; |  | ||||||
|     if (type == cst_ptyp) return "cst"; |  | ||||||
|     if (type == pro_ptyp) return "pro"; |  | ||||||
|     if (type == str_ptyp) return "str"; |  | ||||||
|     if (type == ico_ptyp) return "ico"; |  | ||||||
|     if (type == uco_ptyp) return "uco"; |  | ||||||
|     if (type == fco_ptyp) return "fco"; |  | ||||||
|     return "???"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int main(int argc, const char* argv[]) |  | ||||||
| { |  | ||||||
|     struct e_instr insn; |  | ||||||
| 
 |  | ||||||
| 	if (!EM_open(argv[1])) | 	if (!EM_open(argv[1])) | ||||||
| 		fatal("Couldn't open input file: %s", EM_error); | 		fatal("Couldn't open input file: %s", EM_error); | ||||||
| 	 | 	 | ||||||
|     EM_getinstr(&insn); |     parse_em(); | ||||||
|     printf("; word size = %d\n", EM_wordsize); |  | ||||||
|     printf("; pointer size = %d\n", EM_pointersize); |  | ||||||
| 
 |  | ||||||
| 	while (insn.em_type != EM_EOF) |  | ||||||
| 	{ |  | ||||||
|         printf("%s %s ", |  | ||||||
|             type_to_str(insn.em_type), |  | ||||||
|             argtype_to_str(insn.em_arg.ema_argtype)); |  | ||||||
| 
 |  | ||||||
|         switch (insn.em_type) |  | ||||||
|         { |  | ||||||
|             case EM_PSEU: |  | ||||||
|                 printf("%s ", em_pseu[insn.em_opcode - sp_fpseu]); |  | ||||||
|                 switch (insn.em_opcode) |  | ||||||
|                 { |  | ||||||
|                     case ps_exp: /* external proc */ |  | ||||||
|                     case ps_exa: /* external array */ |  | ||||||
|                     case ps_inp: /* internal proc */ |  | ||||||
|                     case ps_ina: /* internal array */ |  | ||||||
|                         switch (insn.em_arg.ema_argtype) |  | ||||||
|                         { |  | ||||||
|                             case pro_ptyp: |  | ||||||
|                                 printf("name=%s\n", insn.em_pnam); |  | ||||||
|                                 break; |  | ||||||
| 
 |  | ||||||
|                             case sof_ptyp: |  | ||||||
|                                 printf("name=%s offset=0x%x\n", |  | ||||||
|                                     insn.em_dnam, |  | ||||||
|                                     insn.em_off); |  | ||||||
|                                 break; |  | ||||||
| 
 |  | ||||||
|                             default: |  | ||||||
|                                 printf("name=?\n"); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case ps_con: /* .data */ |  | ||||||
|                     case ps_rom: /* .rom */ |  | ||||||
|                         printf("size=%d ", |  | ||||||
|                             insn.em_size); |  | ||||||
| 
 |  | ||||||
|                         switch (insn.em_arg.ema_argtype) |  | ||||||
|                         { |  | ||||||
|                             case ico_ptyp: |  | ||||||
|                             case uco_ptyp: |  | ||||||
|                             case fco_ptyp: |  | ||||||
|                             case str_ptyp: |  | ||||||
|                                 printf("val=%s\n", insn.em_string); |  | ||||||
|                                 break; |  | ||||||
| 
 |  | ||||||
|                             default: |  | ||||||
|                                 printf("val=?\n"); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case ps_pro: /* procedure start */ |  | ||||||
|                         printf("\n\n%s %d\n", |  | ||||||
|                             insn.em_arg.ema_pnam, |  | ||||||
|                             insn.em_arg.ema_szoroff); |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case ps_end: /* procedure end */ |  | ||||||
|                         printf("%d\n\n\n", |  | ||||||
|                             insn.em_arg.ema_szoroff); |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     default: |  | ||||||
|                         printf("???\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case EM_DEFILB: |  | ||||||
|                 printf("code label %d\n", insn.em_ilb); |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case EM_DEFDLB: |  | ||||||
|                 printf("data label %d\n", insn.em_dlb); |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case EM_DEFDNAM: |  | ||||||
|                 printf("data label %s\n", insn.em_dnam); |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case EM_STARTMES: |  | ||||||
|                 for (;;) |  | ||||||
|                 { |  | ||||||
|                     switch (insn.em_arg.ema_argtype) |  | ||||||
|                     { |  | ||||||
|                         case cst_ptyp: |  | ||||||
|                             printf("%d ", insn.em_cst); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case str_ptyp: |  | ||||||
|                             printf("%s ", insn.em_string); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         default: |  | ||||||
|                             printf("(unknown %s) ", |  | ||||||
|                                 argtype_to_str(insn.em_arg.ema_argtype)); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     EM_getinstr(&insn); |  | ||||||
|                     if (insn.em_type == EM_ENDMES) |  | ||||||
|                         break; |  | ||||||
|                     assert(insn.em_type == EM_MESARG); |  | ||||||
|                  } |  | ||||||
|                  printf("\n"); |  | ||||||
|                  break; |  | ||||||
| 
 |  | ||||||
|             case EM_MNEM: |  | ||||||
|             { |  | ||||||
|                 int flag = em_flag[insn.em_opcode - sp_fmnem]; |  | ||||||
|                 printf("%s %c%c%c%c ", |  | ||||||
|                     em_mnem[insn.em_opcode - sp_fmnem], |  | ||||||
|                     "/CDNFLGWSZOPBR"[flag & EM_PAR], |  | ||||||
|                     (flag & FLO_C) ? 'c' : '.', |  | ||||||
|                     (flag & FLO_P) ? 'p' : '.', |  | ||||||
|                     (flag & FLO_T) ? 't' : '.'); |  | ||||||
| 
 |  | ||||||
|                 if (flag & EM_PAR) |  | ||||||
|                 { |  | ||||||
|                     switch (insn.em_argtype) |  | ||||||
|                     { |  | ||||||
|                         case ilb_ptyp: |  | ||||||
|                             printf("ilb "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case nof_ptyp: |  | ||||||
|                             printf("nof "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case sof_ptyp: |  | ||||||
|                             printf("sof "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case cst_ptyp: |  | ||||||
|                             printf("cst 0x%08x ", insn.em_cst); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case pro_ptyp: |  | ||||||
|                             printf("pro "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case str_ptyp: |  | ||||||
|                             printf("str "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case ico_ptyp: |  | ||||||
|                             printf("ico "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case uco_ptyp: |  | ||||||
|                             printf("uco "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         case fco_ptyp: |  | ||||||
|                             printf("fco "); |  | ||||||
|                             break; |  | ||||||
| 
 |  | ||||||
|                         default: |  | ||||||
|                             printf("???"); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 printf("\n"); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             default: |  | ||||||
|                 printf("%d\n", insn.em_opcode); |  | ||||||
|                 break; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
| 		EM_getinstr(&insn); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	EM_close(); | 	EM_close(); | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								mach/proto/mcg/mcg.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								mach/proto/mcg/mcg.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | #ifndef MCG_H | ||||||
|  | #define MCG_H | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <assert.h> | ||||||
|  | #include "em_arith.h" | ||||||
|  | #include "em_label.h" | ||||||
|  | #include "em.h" | ||||||
|  | #include "em_comp.h" | ||||||
|  | #include "em_pseu.h" | ||||||
|  | #include "em_mnem.h" | ||||||
|  | #include "em_flag.h" | ||||||
|  | #include "em_ptyp.h" | ||||||
|  | 
 | ||||||
|  | extern char em_pseu[][4]; | ||||||
|  | extern char em_mnem[][4]; | ||||||
|  | extern char em_flag[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern void fatal(const char* s, ...); | ||||||
|  | 
 | ||||||
|  | extern void parse_em(void); | ||||||
|  | 
 | ||||||
|  | extern void tb_filestart(void); | ||||||
|  | extern void tb_fileend(void); | ||||||
|  | extern void tb_symbol(const char* name, bool is_exported, bool is_proc); | ||||||
|  | extern void tb_dlabel(const char* label); | ||||||
|  | extern void tb_ilabel(const char* label); | ||||||
|  | extern void tb_data(const uint8_t* data, size_t size, bool is_ro); | ||||||
|  | extern void tb_data_offset(const char* label, arith offset, bool is_ro); | ||||||
|  | extern void tb_bss(size_t size, uint8_t init); | ||||||
|  | extern void tb_procstart(const char* label, size_t nlocals); | ||||||
|  | extern void tb_procend(void); | ||||||
|  | extern void tb_regvar(arith offset, int size, int type, int priority); | ||||||
|  | 
 | ||||||
|  | extern void tb_insn_simple(int opcode, int flags); | ||||||
|  | extern void tb_insn_label(int opcode, int flags, const char* label, arith offset); | ||||||
|  | extern void tb_insn_value(int opcode, int flags, arith value); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* vim: set sw=4 ts=4 expandtab : */ | ||||||
							
								
								
									
										295
									
								
								mach/proto/mcg/parse_em.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								mach/proto/mcg/parse_em.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,295 @@ | ||||||
|  | #include "mcg.h" | ||||||
|  | 
 | ||||||
|  | static struct e_instr insn; | ||||||
|  | 
 | ||||||
|  | static const char* type_to_str(int type) | ||||||
|  | { | ||||||
|  | 	switch (type) | ||||||
|  | 	{ | ||||||
|  | 		case EM_MNEM:       return "EM_MNEM"; | ||||||
|  | 		case EM_PSEU:	    return "EM_PSEU"; | ||||||
|  | 		case EM_STARTMES:   return "EM_STARTMES"; | ||||||
|  | 		case EM_MESARG:     return "EM_MESARG"; | ||||||
|  | 		case EM_ENDMES:     return "EM_ENDMES"; | ||||||
|  | 		case EM_DEFILB:     return "EM_DEFILB"; | ||||||
|  | 		case EM_DEFDLB:     return "EM_DEFDLB"; | ||||||
|  | 		case EM_DEFDNAM:    return "EM_DEFDNAM"; | ||||||
|  | 		case EM_ERROR:      return "EM_ERROR"; | ||||||
|  | 		case EM_FATAL:      return "EM_FATAL"; | ||||||
|  | 		case EM_EOF:        return "EM_EOF"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  |     assert(0 && "invalid EM type"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char* argtype_to_str(int type) | ||||||
|  | { | ||||||
|  |     if (type == 0)        return "..."; | ||||||
|  |     if (type == ilb_ptyp) return "ilb"; | ||||||
|  |     if (type == nof_ptyp) return "nof"; | ||||||
|  |     if (type == sof_ptyp) return "sof"; | ||||||
|  |     if (type == cst_ptyp) return "cst"; | ||||||
|  |     if (type == pro_ptyp) return "pro"; | ||||||
|  |     if (type == str_ptyp) return "str"; | ||||||
|  |     if (type == ico_ptyp) return "ico"; | ||||||
|  |     if (type == uco_ptyp) return "uco"; | ||||||
|  |     if (type == fco_ptyp) return "fco"; | ||||||
|  |     return "???"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void unknown_type(const char* s) | ||||||
|  | { | ||||||
|  |     fatal("%s with unknown type '%s'", | ||||||
|  |         s, | ||||||
|  |         argtype_to_str(insn.em_arg.ema_argtype)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const uint8_t* arith_to_bytes(arith a, size_t sz) | ||||||
|  | { | ||||||
|  |     uint8_t* p = malloc(8); | ||||||
|  | 
 | ||||||
|  |     switch (sz) | ||||||
|  |     { | ||||||
|  |         case 1: *(uint8_t*)p = a; break; | ||||||
|  |         case 2: *(uint16_t*)p = a; break; | ||||||
|  |         case 4: *(uint32_t*)p = a; break; | ||||||
|  |         case 8: *(uint64_t*)p = a; break; | ||||||
|  |         default: | ||||||
|  |             fatal("bad constant size '%d'", sz); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char* ilabel_to_str(label l) | ||||||
|  | { | ||||||
|  |     char s[16]; | ||||||
|  |     sprintf(s, "__I%d", l); | ||||||
|  |     return strdup(s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char* dlabel_to_str(label l) | ||||||
|  | { | ||||||
|  |     char s[16]; | ||||||
|  |     sprintf(s, ".%d", l); | ||||||
|  |     return strdup(s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void parse_pseu(void) | ||||||
|  | { | ||||||
|  | 	switch (insn.em_opcode) | ||||||
|  | 	{ | ||||||
|  | 		case ps_exp: /* external proc */ | ||||||
|  | 		case ps_exa: /* external array */ | ||||||
|  | 		case ps_inp: /* internal proc */ | ||||||
|  | 		case ps_ina: /* internal array */ | ||||||
|  | 		{ | ||||||
|  | 			bool export = (insn.em_opcode == ps_exp) || (insn.em_opcode == ps_exa); | ||||||
|  | 			bool proc = (insn.em_opcode == ps_exp) || (insn.em_opcode == ps_inp); | ||||||
|  | 
 | ||||||
|  | 			switch (insn.em_arg.ema_argtype) | ||||||
|  | 			{ | ||||||
|  | 				case pro_ptyp: | ||||||
|  | 					tb_symbol(strdup(insn.em_pnam), export, proc); | ||||||
|  | 					break; | ||||||
|  | 
 | ||||||
|  | 				case sof_ptyp: | ||||||
|  |                     assert(insn.em_off == 0); | ||||||
|  | 					tb_symbol(strdup(insn.em_dnam), export, proc); | ||||||
|  | 					break; | ||||||
|  | 
 | ||||||
|  |                 case nof_ptyp: | ||||||
|  |                     assert(insn.em_off == 0); | ||||||
|  |                     tb_symbol(dlabel_to_str(insn.em_dlb), export, proc); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  | 				default: | ||||||
|  |                     unknown_type("exp, exa, inp, ina"); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case ps_con: /* .data */ | ||||||
|  | 		case ps_rom: /* .rom */ | ||||||
|  |         { | ||||||
|  |             bool ro = (insn.em_opcode == ps_rom); | ||||||
|  | 
 | ||||||
|  | 			switch (insn.em_arg.ema_argtype) | ||||||
|  | 			{ | ||||||
|  | 				case ico_ptyp: | ||||||
|  | 				case uco_ptyp: | ||||||
|  |                 { | ||||||
|  |                     arith val = atol(insn.em_string); | ||||||
|  |                     tb_data(arith_to_bytes(val, insn.em_size), insn.em_size, ro); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 				case str_ptyp: | ||||||
|  |                     tb_data(strdup(insn.em_string), insn.em_size, ro); | ||||||
|  | 					break; | ||||||
|  | 
 | ||||||
|  |                 case cst_ptyp: | ||||||
|  |                     tb_data(arith_to_bytes(insn.em_cst, EM_wordsize), EM_wordsize, ro); | ||||||
|  |                     break; | ||||||
|  |                      | ||||||
|  |                 case nof_ptyp: | ||||||
|  |                     tb_data_offset(dlabel_to_str(insn.em_dlb), insn.em_off, ro); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case ilb_ptyp: | ||||||
|  |                     tb_data_offset(ilabel_to_str(insn.em_ilb), 0, ro); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  | 				default: | ||||||
|  |                     unknown_type("con, rom"); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         case ps_bss: | ||||||
|  |         { | ||||||
|  |             switch (insn.em_arg.ema_argtype) | ||||||
|  |             { | ||||||
|  |                 case cst_ptyp: | ||||||
|  |                     tb_bss(EM_bsssize, EM_bssinit); | ||||||
|  |                     break; | ||||||
|  |                      | ||||||
|  |                 default: | ||||||
|  |                     unknown_type("bss"); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 		case ps_pro: /* procedure start */ | ||||||
|  |             if (insn.em_nlocals == -1) | ||||||
|  |                 fatal("procedures with unspecified number of locals are not supported yet"); | ||||||
|  | 
 | ||||||
|  |             tb_procstart(strdup(insn.em_pnam), insn.em_nlocals); | ||||||
|  |             break; | ||||||
|  | 
 | ||||||
|  | 		case ps_end: /* procedure end */ | ||||||
|  |             tb_procend(); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		default: | ||||||
|  |             fatal("unknown pseudo with opcode %d\n", insn.em_opcode); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static arith mes_get_cst(void) | ||||||
|  | { | ||||||
|  |     EM_getinstr(&insn); | ||||||
|  |     if (insn.em_type != EM_MESARG) | ||||||
|  |         fatal("malformed MES"); | ||||||
|  |     return insn.em_cst; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void parse_mes(void) | ||||||
|  | { | ||||||
|  |     assert(insn.em_arg.ema_argtype == cst_ptyp); | ||||||
|  |     switch (insn.em_cst) | ||||||
|  |     { | ||||||
|  |         case 0: /* error */ | ||||||
|  |             fatal("MES 0 received (explicit halt)"); | ||||||
|  | 
 | ||||||
|  |         case 3: /* register variable */ | ||||||
|  |         { | ||||||
|  |             arith offset = mes_get_cst(); | ||||||
|  |             int size = mes_get_cst(); | ||||||
|  |             int type = mes_get_cst(); | ||||||
|  |             int priority = mes_get_cst(); | ||||||
|  |             tb_regvar(offset, size, type, priority); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     while ((insn.em_type == EM_STARTMES) || (insn.em_type == EM_MESARG)) | ||||||
|  |         EM_getinstr(&insn); | ||||||
|  | 
 | ||||||
|  |     if (insn.em_type != EM_ENDMES) | ||||||
|  |         fatal("malformed MES"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void parse_em(void) | ||||||
|  | { | ||||||
|  |     EM_getinstr(&insn); | ||||||
|  | 	tb_filestart(); | ||||||
|  | 
 | ||||||
|  | 	while (insn.em_type != EM_EOF) | ||||||
|  | 	{ | ||||||
|  |         switch (insn.em_type) | ||||||
|  |         { | ||||||
|  |             case EM_PSEU: | ||||||
|  | 				parse_pseu(); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case EM_DEFILB: | ||||||
|  |                 tb_ilabel(ilabel_to_str(insn.em_ilb)); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case EM_DEFDLB: | ||||||
|  |                 tb_dlabel(dlabel_to_str(insn.em_dlb)); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case EM_DEFDNAM: | ||||||
|  |                 tb_dlabel(strdup(insn.em_dnam)); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case EM_STARTMES: | ||||||
|  |                 parse_mes(); | ||||||
|  |                  break; | ||||||
|  | 
 | ||||||
|  |             case EM_MNEM: | ||||||
|  |             { | ||||||
|  |                 int flags = em_flag[insn.em_opcode - sp_fmnem]; | ||||||
|  | 
 | ||||||
|  |                 if (flags & EM_PAR) | ||||||
|  |                 { | ||||||
|  |                     switch (insn.em_argtype) | ||||||
|  |                     { | ||||||
|  |                         case ilb_ptyp: | ||||||
|  |                             tb_insn_label(insn.em_opcode, flags, | ||||||
|  |                                 ilabel_to_str(insn.em_ilb), 0); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case nof_ptyp: | ||||||
|  |                             tb_insn_label(insn.em_opcode, flags, | ||||||
|  |                                 dlabel_to_str(insn.em_dlb), insn.em_off); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case sof_ptyp: | ||||||
|  |                             tb_insn_label(insn.em_opcode, flags, | ||||||
|  |                                 strdup(insn.em_dnam), insn.em_off); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case pro_ptyp: | ||||||
|  |                             tb_insn_label(insn.em_opcode, flags, | ||||||
|  |                                 strdup(insn.em_pnam), 0); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case cst_ptyp: | ||||||
|  |                             tb_insn_value(insn.em_opcode, flags, | ||||||
|  |                                 insn.em_cst); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         default: | ||||||
|  |                             unknown_type("instruction"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                     tb_insn_simple(insn.em_opcode, flags); | ||||||
|  | 
 | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             default: | ||||||
|  |                 fatal("unrecognised instruction type '%d'", insn.em_type); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 		EM_getinstr(&insn); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tb_fileend(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* vim: set sw=4 ts=4 expandtab : */ | ||||||
|  | @ -44,9 +44,9 @@ END { | ||||||
| 		print ""; | 		print ""; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	print "const struct stackop* stackops[] = {"; | 	print "const struct stackop* const stackops[] = {"; | ||||||
| 	for (i=0; i<count; i++) | 	for (i=0; i<count; i++) | ||||||
| 		print "\t&so_" opcode[i] "," | 		print "\tso_" opcode[i] "," | ||||||
| 	print "};" | 	print "};" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ struct stackop { | ||||||
| 	char type : 7; | 	char type : 7; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern const struct stackop* stackops[]; | extern const struct stackop* const stackops[]; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										94
									
								
								mach/proto/mcg/treebuilder.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								mach/proto/mcg/treebuilder.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | ||||||
|  | #include "mcg.h" | ||||||
|  | 
 | ||||||
|  | void tb_filestart(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_fileend(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_symbol(const char* name, bool is_exported, bool is_proc) | ||||||
|  | { | ||||||
|  | 	printf("; symbol name=%s, exported=%s, is_proc=%s\n", | ||||||
|  | 		name, | ||||||
|  | 		is_exported ? "yes" : "no", | ||||||
|  | 		is_proc ? "yes" : "no"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_dlabel(const char* label) | ||||||
|  | { | ||||||
|  | 	printf("; dlabel name=%s\n", label); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_ilabel(const char* label) | ||||||
|  | { | ||||||
|  | 	printf("; ilabel name=%s\n", label); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_data(const uint8_t* data, size_t size, bool is_ro) | ||||||
|  | { | ||||||
|  | 	printf("; data size=%d ro=%s\n", | ||||||
|  | 		size, | ||||||
|  | 		is_ro ? "yes" : "no"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_data_offset(const char* label, arith offset, bool is_ro) | ||||||
|  | { | ||||||
|  | 	printf("; data label=%s offset=%d ro=%s\n", | ||||||
|  | 		label, offset, | ||||||
|  | 		is_ro ? "yes" : "no"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_bss(size_t size, uint8_t init) | ||||||
|  | { | ||||||
|  | 	printf("; bss size=%d init=0x%x\n", | ||||||
|  | 		size, init); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_procstart(const char* label, size_t nlocals) | ||||||
|  | { | ||||||
|  | 	printf("; proc name=%s nlocals=%d\n", label, nlocals); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_procend(void) | ||||||
|  | { | ||||||
|  | 	printf("; endproc\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_regvar(arith offset, int size, int type, int priority) | ||||||
|  | { | ||||||
|  | 	printf("; regvar offset=%d size=%d type=%d priority=%d\n", | ||||||
|  | 		offset, size, type, priority); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void printinsn(int opcode, int flags) | ||||||
|  | { | ||||||
|  | 	printf("; insn %s %c%c%c%c ", | ||||||
|  | 		em_mnem[opcode - sp_fmnem], | ||||||
|  | 		"/CDNFLGWSZOPBR"[flags & EM_PAR], | ||||||
|  | 		(flags & FLO_C) ? 'c' : '.', | ||||||
|  | 		(flags & FLO_P) ? 'p' : '.', | ||||||
|  | 		(flags & FLO_T) ? 't' : '.'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_insn_simple(int opcode, int flags) | ||||||
|  | { | ||||||
|  | 	printinsn(opcode, flags); | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_insn_label(int opcode, int flags, const char* label, arith offset) | ||||||
|  | { | ||||||
|  | 	printinsn(opcode, flags); | ||||||
|  | 	printf("label=%s offset=%d\n", label, offset); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void tb_insn_value(int opcode, int flags, arith value) | ||||||
|  | { | ||||||
|  | 	printinsn(opcode, flags); | ||||||
|  | 	printf("value=%d\n", value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* vim: set sw=4 ts=4 expandtab : */ | ||||||
|  | 
 | ||||||
|  | @ -4,4 +4,5 @@ | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| 
 | 
 | ||||||
| #define label unsigned int | typedef unsigned int label; | ||||||
|  | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue