parse.y (78945B)
1 %define parse.error verbose 2 3 %{ 4 #include "lex.h" 5 int line = 1; 6 char *fname; 7 int yywrap(void){ return 1; } 8 int yylex(void); 9 void yyerror(const char *s) 10 { 11 fprintf(stderr, "%s:%i:%s\n", fname, line, s); 12 exit(1); 13 } 14 15 #define IDENTIFIER_TYPES( f ) \ 16 f(undefined) \ 17 f(variable) \ 18 f(func) \ 19 f(parameter) 20 21 enum id_type { 22 #define f(n) n, 23 IDENTIFIER_TYPES(f) 24 #undef f 25 }; 26 27 #define EXPRESSION_TYPES( f ) \ 28 f(nop) f(string) f(number) f(idnt) \ 29 f(neg) f(add) f(mul) f(divide) f(mod)\ 30 f(comma) \ 31 f(ref) f(deref) \ 32 f(l_eq) f(l_lt) \ 33 f(l_and) f(l_or) f(l_not) \ 34 f(b_and) f(b_or) f(b_not) f(b_xor) \ 35 f(shift_l) f(shift_r) \ 36 f(set) f(decl) \ 37 f(ifnz) f(loop) \ 38 f(printchar) f(writestring) f(readstring)\ 39 f(brk_sys) f(_syscall) \ 40 f(function) f(fcall) f(ret) f(exit_p) 41 42 enum e_type { 43 #define f(n) n, 44 EXPRESSION_TYPES(f) 45 #undef f 46 }; 47 48 struct expression { 49 enum e_type type; 50 enum id_type id_type; 51 int constant; 52 int declares; 53 char *str; 54 char flags; 55 int64_t i; 56 size_t args_count; 57 struct expression *args; 58 }; 59 60 struct identifiers{ 61 size_t count; 62 struct expression *identifiers; 63 }; 64 struct identifiers *ids = NULL; 65 struct expression *defid(char *name) 66 { 67 int i; 68 if (!ids) 69 ids = calloc(sizeof(struct identifiers), 1); 70 for (i = 0; i < ids->count; i++) { 71 if (!strcmp(ids->identifiers[i].str, name)) return &ids->identifiers[i]; 72 } 73 ids->count++; 74 ids->identifiers = realloc(ids->identifiers, sizeof(struct expression) * ids->count); 75 76 ids->identifiers[ids->count-1].type = idnt; 77 ids->identifiers[ids->count-1].id_type = undefined; 78 ids->identifiers[ids->count-1].constant = 1; 79 ids->identifiers[ids->count-1].str = malloc(strlen(name) + 1); 80 81 strcpy(ids->identifiers[ids->count-1].str, name); 82 free(name); 83 84 return &ids->identifiers[ids->count-1]; 85 } 86 87 struct expression *find_idnt(char *name) 88 { 89 struct expression *r = NULL; 90 size_t i; 91 for (i = 0; i < ids->count; i++) { 92 if (!strcmp(ids->identifiers[i].str, name)) { 93 r = &ids->identifiers[i]; 94 break; 95 } 96 } 97 if (!r) yyerror("undefined symbol"); 98 return r; 99 } 100 101 struct expression *ZERO = &(struct expression){ .type = number, .constant = 1 }; 102 struct expression *ONE = &(struct expression){ .type = number, .constant = 1, .i = 1 }; 103 struct expression *final; 104 105 struct expression *e(enum e_type type, struct expression *arg1, struct expression *arg2, int nofree) 106 { 107 struct expression *r = calloc(sizeof(struct expression), 1); 108 r->type = type; 109 if (r->type == comma && (arg1 && arg1->type == comma || arg2 && arg2->type == comma)) { 110 if (arg1 && arg1->type == comma && arg2 && arg2->type == comma) { 111 r->args_count = arg1->args_count + arg2->args_count; 112 r->args = calloc(sizeof(struct expression), r->args_count); 113 memmove(r->args, arg1->args, sizeof(struct expression) * arg1->args_count); 114 memmove(&r->args[arg1->args_count], arg2->args, sizeof(struct expression) * arg2->args_count); 115 } else if (arg1 && arg1->type == comma) { 116 r->args_count = arg1->args_count + 1; 117 r->args = calloc(sizeof(struct expression), r->args_count); 118 memmove(r->args, arg1->args, sizeof(struct expression) * arg1->args_count); 119 if (arg2) memmove(&r->args[arg1->args_count], arg2, sizeof(struct expression)); 120 } else if (arg2 && arg2->type == comma) { 121 r->args_count = arg2->args_count + 1; 122 r->args = calloc(sizeof(struct expression), r->args_count); 123 if (arg1) memmove(r->args, arg1, sizeof(struct expression)); 124 memmove(&r->args[arg1 ? 1 : 0], arg2->args, sizeof(struct expression) * arg2->args_count); 125 } 126 } else if (r->type == number) { 127 r->i = (int64_t) arg1; 128 } else if (r->type == string && arg1) { 129 r->str = calloc(strlen((char *)arg1) + 1, 1); 130 strcpy(r->str, (char *)arg1); 131 } else { 132 r->args_count = (arg1 ? 1 : 0) + (arg2 ? 1 : 0); 133 r->args = calloc(sizeof(struct expression), r->args_count); 134 if (arg1) memmove(r->args, arg1, sizeof(struct expression)); 135 if (arg2) memmove(&r->args[arg1 ? 1 : 0], arg2, sizeof(struct expression)); 136 } 137 //if (!nofree && arg1 && !arg1->constant) free(arg1); 138 if (!nofree && arg2 && !arg2->constant) free(arg2); 139 return r; 140 } 141 int curr_decl = 0; 142 struct expression *defun(struct expression *identifier, struct expression *params, struct expression *body) 143 { 144 struct expression *r = calloc(sizeof(struct expression), 1); 145 r->type = function; 146 r->declares = curr_decl; 147 curr_decl = 0; 148 r->args_count = params ? 3 : 2; 149 r->args = calloc(sizeof(struct expression), r->args_count); 150 memmove(r->args, identifier, sizeof(struct expression)); 151 if (params) memmove(&r->args[1], params, sizeof(struct expression)); 152 memmove(&r->args[r->args_count-1], body, sizeof(struct expression)); 153 if (params) free(params); 154 if (body) free(body); 155 return r; 156 } 157 158 void append(struct expression *base, struct expression *arg) 159 { 160 base->args = realloc(base->args, sizeof(struct expression) * (++base->args_count)); 161 memmove(&base->args[base->args_count-1], arg, sizeof(struct expression)); 162 free(arg); 163 } 164 165 struct expression *move(struct expression *e) 166 { 167 struct expression *r = calloc(sizeof(struct expression), 1); 168 memmove(r, e, sizeof(struct expression)); 169 free(e); 170 return r; 171 } 172 struct expression *copy(struct expression *e) 173 { 174 struct expression *r = calloc(sizeof(struct expression), 1); 175 memcpy(r, e, sizeof(struct expression)); 176 return r; 177 } 178 179 char *expand_str(char *str) { 180 int i, j = 0, l = strlen(str); 181 for (i = 0; i < l; i++) { 182 if (str[i] == '\\') { 183 switch (str[i+1]) { 184 case 'n': 185 j = 1; 186 str[i+j] = '\n'; 187 break; 188 case 'r': 189 j = 1; 190 str[i+j] = '\r'; 191 break; 192 case 't': 193 j = 1; 194 str[i+j] = '\t'; 195 break; 196 case '\\': 197 i++; 198 default: 199 j = 0; 200 break; 201 } 202 l -= j; 203 if (j) memmove(&str[i], &str[i+j], l - i + 1); 204 } 205 } 206 return str; 207 } 208 209 char *escape_str(char *str) { 210 int i, j, l = strlen(str); 211 char *r; 212 for (i = 0, j = 1; i < l; i++) 213 if (str[i] == '\\' || str[i] == '\n' || str[i] == '\r' || str[i] == '\t') 214 j++; 215 r = calloc(l + j, 1); 216 for (i = 0, j = 0; i < l; i++, j++) { 217 switch (str[i]) { 218 case '\n': 219 r[j++] = '\\'; 220 r[j] = 'n'; 221 break; 222 case '\r': 223 r[j++] = '\\'; 224 r[j] = 'r'; 225 break; 226 case '\t': 227 r[j++] = '\\'; 228 r[j] = 't'; 229 break; 230 case '\\': 231 r[j++] = '\\'; 232 r[j] = '\\'; 233 break; 234 default: 235 r[j] = str[i]; 236 break; 237 } 238 } 239 return r; 240 } 241 %} 242 243 %union {struct expression *expr; char *str; int64_t i;} 244 245 %token END 0 246 %token <str> IDENTIFIER STRING 247 %token <i> NUMBER 248 %token INC "++" DEC "--" 249 %token EQ "==" LTEQ "<=" GTEQ ">=" AND "&&" OR "||" NOT_EQ "!=" 250 %token SHIFT_L "<<" SHIFT_R ">>" 251 %token ADD_EQ "+=" SUB_EQ "-=" MUL_EQ "*=" DIV_EQ "/=" MOD_EQ "%=" 252 %token OR_EQ "|=" AND_EQ "&=" XOR_EQ "^=" SHL_EQ "<<=" SHR_EQ ">>=" 253 %token RETURN "return" IF "if" ELSE "else" WHILE "while" DECL "decl" 254 %token EXIT "exit" PUTC "putc" WRITE "write" READ "read" BRK "brk" 255 %token SYSCALL1 "_syscall1" SYSCALL2 "_syscall2" SYSCALL3 "_syscall3" 256 %token SYSCALL4 "_syscall4" SYSCALL5 "_syscall5" SYSCALL6 "_syscall6" 257 258 %nonassoc "if" 259 %nonassoc "else" 260 261 %left ',' 262 %right '?' ':' '=' "+=" "-=" "*=" "/=" "%=" "&=" "|=" "^=" "<<=" ">>=" 263 %left "||" 264 %left "&&" 265 %left '|' 266 %left '^' 267 %left '&' 268 %left "==" "!=" 269 %left '<' '>' "<=" ">=" 270 %left "<<" ">>" 271 %left '+' '-' 272 %left '*' '/' '%' 273 %right REF NEG "++" "--" '!' '~' 274 %left '(' '[' 275 276 %type <expr> expression exprs c_expr var_def var_defs statement comp_stmt if_stmt 277 %type <expr> parameters parameter identifier program function ifelse 278 %type <str> str 279 280 %% 281 282 program: program function {$$ = move($1); append($$, $2); final = $$;} 283 | function {$$ = e(comma, $1, NULL, 0); final = $$;} 284 ; 285 286 function: identifier '(' parameters ')' statement {$1->id_type = function; $$ = defun(copy($1), $3, $5);} 287 ; 288 289 parameters: parameter {$$ = move($1);} 290 | %empty {$$ = NULL;} 291 ; 292 293 parameter: parameter ',' parameter {$$ = e(comma, $1, $3, 0);} 294 | identifier {$1->id_type = parameter; $$ = copy($1);} 295 ; 296 297 statement: "return" exprs ';' {$$ = e(ret, $2, NULL, 0);} 298 | "while" '(' expression ')' statement {$$ = e(loop, $3, $5, 0);} 299 | ifelse {$$ = move($1);} 300 | exprs ';' {$$ = move($1);} 301 | "exit" ';' {$$ = e(exit_p, ZERO, NULL, 0);} 302 | "exit" expression ';' {$$ = e(exit_p, $2, NULL, 0);} 303 | comp_stmt '}' {$$ = move($1);} 304 | ';' {$$ = e(nop, NULL, NULL, 1);} 305 ; 306 307 ; 308 309 ifelse: if_stmt "else" statement %prec "else" {$$ = move($1); append($$, $3);} 310 | if_stmt %prec "if" {$$ = move($1);} 311 ; 312 313 if_stmt: "if" '(' expression ')' statement {$$ = e(ifnz, $3, $5, 0);} 314 ; 315 316 comp_stmt: '{' {$$ = e(comma, NULL, NULL, 1);} 317 | comp_stmt statement {$$ = move($1); append($$, $2);} 318 ; 319 320 var_defs: "decl" var_def {$$ = move($2);} 321 | var_defs ',' var_def {$$ = e(comma, $1, $3, 0);} 322 ; 323 324 var_def: identifier {curr_decl++; $1->id_type = variable; $$ = e(decl, $1, NULL, 0);} 325 | identifier '=' expression {curr_decl++; $1->id_type = variable; $$ = e(comma, e(decl, $1, NULL, 0), e(set, $1, $3, 0), 0);} 326 ; 327 328 identifier: IDENTIFIER {$$ = copy(defid($1));} 329 ; 330 331 exprs: c_expr {$$ = move($1);} 332 | var_defs {$$ = move($1);} 333 ; 334 335 c_expr: expression {$$ = move($1);} 336 | c_expr ',' expression {$$ = e(comma, $1, $3, 0);} 337 ; 338 339 expression: IDENTIFIER {$$ = copy(defid($1)); /*$$ = copy(find_idnt($1));*/} 340 | NUMBER {$$ = e(number, (void *)$1, NULL, 1);} 341 | str {$$ = e(string, (void *)expand_str($1), NULL, 0);} 342 | expression '[' expression ']' {$$ = e(deref, e(add, $1, $3, 0), NULL, 0);} 343 | '(' exprs ')' {$$ = move($2);} 344 | expression '(' ')' {$$ = e(fcall, $1, NULL, 0);} 345 | expression '(' c_expr ')' {$$ = e(fcall, $1, $3, 0);} 346 | "putc" '(' expression ')' {$$ = e(printchar, $3, NULL, 0);} 347 | "write" '(' expression ',' expression ',' expression ')' {$$ = e(writestring, e(comma, e(comma, $3, $5, 0), $7, 0), NULL, 0);} 348 | "read" '(' expression ',' expression ',' expression ')' {$$ = e(readstring, e(comma, e(comma, $3, $5, 0), $7, 0), NULL, 0);} 349 | "brk" '(' expression ')' {$$ = e(brk_sys, $3, NULL, 0);} 350 | "_syscall1" '(' expression ',' 351 expression ')' {$$ = e(_syscall, $3, $5, 0);} 352 353 | "_syscall2" '(' expression ',' 354 expression ',' 355 expression ')' {$$ = e(_syscall, $3, e(comma, $5, $7, 0), 0);} 356 357 | "_syscall3" '(' expression ',' 358 expression ',' 359 expression ',' 360 expression ')' {$$ = e(_syscall, $3, e(comma, e(comma, $5, $7, 0), $9, 0), 0);} 361 362 | "_syscall4" '(' expression ',' 363 expression ',' 364 expression ',' 365 expression ',' 366 expression ')' {$$ = e(_syscall, $3, e(comma, e(comma, e(comma, $5, $7, 0), $9, 0), $11, 0), 0);} 367 368 | "_syscall5" '(' expression ',' 369 expression ',' 370 expression ',' 371 expression ',' 372 expression ',' 373 expression ')' {$$ = e(_syscall, $3, e(comma, e(comma, e(comma, e(comma, $5, $7, 0), $9, 0), $11, 0), $13, 0), 0);} 374 375 | "_syscall6" '(' expression ',' 376 expression ',' 377 expression ',' 378 expression ',' 379 expression ',' 380 expression ',' 381 expression ')' {$$ = e(_syscall, $3, e(comma, e(comma, e(comma, e(comma, e(comma, $5, $7, 0), $9, 0), $11, 0), $13, 0), $15, 0), 0);} 382 383 | expression '+' expression {$$ = e(add, $1, $3, 0);} 384 | expression '-' expression {if ($3->type == number) { 385 $$ = e(add, $1, $3, 0); 386 $$->args[1].i = -$$->args[1].i; 387 } else { 388 $$ = e(add, $1, e(neg, $3, NULL, 0), 0); 389 }} 390 | expression '*' expression {$$ = e(mul, $1, $3, 0);} 391 | expression '/' expression {$$ = e(divide, $1, $3, 0);} 392 | expression '%' expression {$$ = e(mod, $1, $3, 0);} 393 | expression '&' expression {$$ = e(b_and, $1, $3, 0);} 394 | expression '|' expression {$$ = e(b_or, $1, $3, 0);} 395 | expression '^' expression {$$ = e(b_xor, $1, $3, 0);} 396 | expression "<<" expression {$$ = e(shift_l, $1, $3, 0);} 397 | expression ">>" expression {$$ = e(shift_r, $1, $3, 0);} 398 | expression '=' expression {$$ = e(set, $1, $3, 0);} 399 | expression "+=" expression {$$ = e(set, $1, e(add, $1, $3, 0), 0);} 400 | expression "-=" expression {if ($3->type == number) { 401 $$ = e(add, $1, $3, 0); 402 $$->args[1].i = -$$->args[1].i; 403 $$ = e(set, $1, $$, 0); 404 } else { 405 $$ = e(set, $1, e(add, $1, e(neg, $3, NULL, 0), 0), 0); 406 }} 407 | expression "*=" expression {$$ = e(set, $1, e(mul, $1, $3, 0), 0);} 408 | expression "/=" expression {$$ = e(set, $1, e(divide, $1, $3, 0), 0);} 409 | expression "%=" expression {$$ = e(set, $1, e(mod, $1, $3, 0), 0);} 410 | expression "&=" expression {$$ = e(set, $1, e(b_and, $1, $3, 0), 0);} 411 | expression "|=" expression {$$ = e(set, $1, e(b_or, $1, $3, 0), 0);} 412 | expression "^=" expression {$$ = e(set, $1, e(b_xor, $1, $3, 0), 0);} 413 | expression "<<=" expression {$$ = e(set, $1, e(shift_l, $1, $3, 0), 0);} 414 | expression ">>=" expression {$$ = e(set, $1, e(shift_r, $1, $3, 0), 0);} 415 | expression "==" expression {$$ = e(l_eq, $1, $3, 0);} 416 | expression "!=" expression {$$ = e(l_not, e(l_eq, $1, $3, 0), NULL, 0);} 417 | expression '<' expression {$$ = e(l_lt, $1, $3, 0);} 418 | expression '>' expression {$$ = e(l_lt, $3, $1, 0);} 419 | expression "<=" expression {$$ = e(l_not, e(l_lt, $1, $3, 0), NULL, 0);} 420 | expression ">=" expression {$$ = e(l_not, e(l_lt, $3, $1, 0), NULL, 0);} 421 | expression "&&" expression {$$ = e(l_and, $1, $3, 0);} 422 | expression "||" expression {$$ = e(l_or, $1, $3, 0);} 423 | '!' expression {$$ = e(l_not, $2, NULL, 0);} 424 | '~' expression {printf("uh-oh\n");$$ = NULL;} 425 | '*' expression %prec REF {$$ = e(deref, $2, NULL, 0);} 426 | '&' expression %prec REF {$$ = e(ref, $2, NULL, 0);} 427 | '-' expression %prec NEG {if ($2->type == number) { 428 $$ = $2; 429 $$->i = -$$->i; 430 } else { 431 $$ = e(neg, $2, NULL, 0); 432 }} 433 | '+' expression %prec NEG {printf("uh-oh\n");$$ = NULL;} 434 | "++" expression {$$ = e(set, $2, e(add, $2, ONE, 0), 0);} 435 | "--" expression {$$ = e(set, $2, e(add, $2, e(neg, ONE, NULL, 0), 0), 0);} 436 | expression "++" {printf("uh-oh ++\n");$$ = NULL;} 437 | expression "--" {printf("uh-oh --\n");$$ = NULL;} 438 ; 439 440 str: str STRING {$$ = calloc(strlen($1) + strlen($2) + 1, 1); strcpy($$, $1); strcpy(&$$[strlen($$)], $2); free($1); free($2);} 441 | STRING {$$ = $1;} 442 ; 443 444 %% 445 #include <stdio.h> 446 #include <fcntl.h> 447 448 char *exp_str[] = { 449 #define f(e) #e, 450 EXPRESSION_TYPES(f) 451 #undef f 452 }; 453 454 int has_sideeffect(struct expression *n) 455 { 456 int i, r = 0; 457 switch (n->type) { 458 case nop: case number: case idnt: case string: 459 return 0; 460 case set: case decl: case ret: 461 return 1; 462 case brk_sys: case printchar: case writestring: 463 case readstring: case _syscall: case exit_p: 464 return 2; 465 case neg: case l_not: case b_not: case ref: case deref: 466 return has_sideeffect(n->args); 467 case add: case mul: case divide: case mod: case b_and: case b_or: case b_xor: 468 case l_and: case l_or: case l_lt: case l_eq: case shift_l: case shift_r: 469 case loop: case comma: case ifnz: 470 for (i = 0; i < n->args_count; i++) 471 r |= has_sideeffect(&n->args[i]); 472 return r; 473 default: 474 return 1; 475 } 476 } 477 478 void stringify(struct expression *e, int p_indent, int last, char *name, uint64_t idmap) 479 { 480 int i, indent = p_indent + 3; 481 char *str; 482 if (last) idmap |= (1 << p_indent/3); 483 for (i = 0; i < p_indent; i+=3) fprintf(stderr, "%s ", (idmap & (1 << (i/3))) ? " " : "│"); 484 if (p_indent >= 0) fprintf(stderr, "%s- ", last ? "-": "+"); 485 switch(e->type) { 486 case function: 487 fprintf(stderr, "%s (", e->args->str); 488 if (e->args_count == 3) { 489 if (e->args[1].type == comma) { 490 for (i = 0; i < e->args[1].args_count; i++) 491 fprintf(stderr, "%s%s", e->args[1].args[i].str, i+1 == e->args[1].args_count ? "" : ", "); 492 } else { 493 fprintf(stderr, "%s", e->args[1].str); 494 } 495 } 496 fprintf(stderr, "):\n"); 497 stringify(&e->args[e->args_count-1], indent, 1, NULL, idmap); 498 break; 499 case string: 500 str = escape_str(e->str); 501 fprintf(stderr, "%s: \"%s\"\n", name ? name : "string", str); 502 free(str); 503 break; 504 case idnt: 505 fprintf(stderr, "%s: %s\n", name ? name : "ident", e->str); 506 break; 507 case number: 508 fprintf(stderr, "%s: %li\n", name ? name : "number", e->i); 509 break; 510 default: 511 fprintf(stderr, "%s: (pure: %i)\n", exp_str[e->type], !has_sideeffect(e)); 512 for (i = 0; i < e->args_count;) { 513 stringify(&e->args[i++], indent, i+1 == e->args_count, NULL, idmap); 514 } 515 break; 516 } 517 } 518 519 void breakpoint(void) {} 520 521 struct storage { 522 int type; 523 char *var; 524 char rbp; 525 int rev; 526 }; 527 struct reg_history { 528 /* 0 - undefined 529 * 1 - variable 530 * 2 - constant */ 531 int type; 532 int reg; 533 int val; 534 int rev; 535 }; 536 537 struct storage regs[1024]; 538 struct reg_history reg_hist[16]; 539 const int registers = 16; 540 int next_reg; 541 uint16_t used_regs; 542 int next_rbp; 543 544 char machine_code[16384] = { 0 }; 545 int mc_ptr = 0; 546 char rodata[8192] = { 0 }; 547 int rd_ptr = 0; 548 int entry_addr = -1; 549 long start_addr, rodata_addr; 550 int func_declares; 551 552 int arg_order[16] = {7, 6, 2, 1, 8, 9, 1, 0, 11, 12, 13, 14, 15, 3, 5}; 553 int syscall_arg[16] = {7, 6, 2, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1}; 554 //int caller_save = 0b0000111111001111; 555 int caller_save = 0b1111111111001111; 556 557 int get_free_reg(int mark_used) 558 { 559 int i; 560 for (i = 0; i < registers; i++) { 561 if (!(used_regs & (1 << i))) { 562 if (mark_used) used_regs |= (1 << i); 563 return i; 564 break; 565 } 566 } 567 fprintf(stderr, "Out of registers?!? fix me\n"); 568 exit(1); 569 } 570 571 void push(int reg, int *pushed, char *order, char *from) { 572 int i; 573 if (used_regs & (1 << reg)) { 574 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 575 machine_code[mc_ptr++] = 0x50 + (reg % 8); 576 for (i = 0; i < registers; i++) { 577 if (order[i] == -1) { 578 order[i] = reg; 579 used_regs &= ~(1 << reg); 580 *pushed |= (1 << reg); 581 next_rbp += 8; 582 return; 583 } 584 } 585 fprintf(stderr, "Unable to push any more registers\n"); 586 exit(1); 587 } 588 } 589 590 void pop(int reg, int *pushed) { 591 if (!(*pushed & (1 << reg))) { 592 fprintf(stderr, "Trying to pop a register which hasn't been pushed\n"); 593 exit(1); 594 } 595 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 596 machine_code[mc_ptr++] = 0x58 + (reg % 8); 597 *pushed &= ~(1 << reg); 598 used_regs |= (1 << reg); 599 next_rbp -= 8; 600 reg_hist[reg].type = 0; 601 } 602 603 struct func_template { 604 char *fname; 605 int fptr; 606 }; 607 608 struct func_template *ftemp; 609 int ftemp_len = 0; 610 611 void func_append(char *fname, int ptr) 612 { 613 int i, j; 614 for (i = 0; i < ftemp_len; i++) 615 if (!strcmp(ftemp[i].fname, fname)) break; 616 if (i == ftemp_len) { 617 ftemp = realloc(ftemp, sizeof(struct func_template) * ++ftemp_len); 618 ftemp[i].fname = malloc(strlen(fname) + 1); 619 strcpy(ftemp[i].fname, fname); 620 ftemp[i].fptr = 0; 621 } 622 if (!ftemp[i].fptr) { 623 ftemp[i].fptr = ptr; 624 } else { 625 for (j = ftemp[i].fptr; *((int *) &machine_code[j]); j = *((int *) &machine_code[j])); 626 *((int *) &machine_code[j]) = ptr; 627 } 628 } 629 630 void func_retrofit(char *fname, int ptr) 631 { 632 int i, j, k; 633 for (i = 0; i < ftemp_len; i++) 634 if (!strcmp(ftemp[i].fname, fname)) break; 635 if (i == ftemp_len) return; 636 637 for (j = ftemp[i].fptr, k = 1; k; j = k) { 638 k = *((int *) &machine_code[j]); 639 *((int *) &machine_code[j]) = ptr - j - 4; 640 } 641 ftemp[i].fptr = 0; 642 } 643 644 int compile_tree(FILE *output, struct expression *tree, int discard_result, int out_reg) 645 { 646 int i, j, k, l, reg = -1; 647 char push_order[16] = { -1, -1, -1, -1, 648 -1, -1, -1, -1, 649 -1, -1, -1, -1, 650 -1, -1, -1, -1 }; 651 int pushed = 0; 652 struct expression *tmp; 653 switch (tree->type) { 654 case function: 655 next_reg = registers; 656 used_regs = (1 << 5) | (1 << 4); 657 next_rbp = 8; 658 tree->i = mc_ptr; 659 find_idnt(tree->args->str)->i = mc_ptr + start_addr; 660 find_idnt(tree->args->str)->flags |= 1; 661 func_retrofit(tree->args->str, mc_ptr); 662 memset(reg_hist, 0, sizeof(reg_hist)); 663 if (!strcmp(tree->args->str, "_start")) { 664 entry_addr = mc_ptr; 665 machine_code[mc_ptr++] = 0x55; 666 machine_code[mc_ptr++] = 0x48; 667 machine_code[mc_ptr++] = 0x89; 668 machine_code[mc_ptr++] = 0xE5; 669 670 if (tree->declares) { 671 machine_code[mc_ptr++] = 0x48; 672 machine_code[mc_ptr++] = 0x81; 673 machine_code[mc_ptr++] = 0xEC; 674 *(int *) &machine_code[mc_ptr] = tree->declares*8; 675 mc_ptr += 4; 676 } 677 } else { 678 if (tree->args[1].type == idnt && tree->args[1].id_type == parameter) { 679 tree->declares++; 680 regs[next_reg].type = 1; 681 regs[next_reg].var = tree->args[1].str; 682 regs[next_reg].rbp = next_rbp; 683 next_rbp += 8; 684 next_reg++; 685 } else if (tree->args[1].type == comma && tree->args[1].args->type == idnt && tree->args[1].args->id_type == parameter) { 686 for (i = 0; i < tree->args[1].args_count; i++) { 687 tree->declares++; 688 regs[next_reg].type = 1; 689 regs[next_reg].var = tree->args[1].args[i].str; 690 regs[next_reg].rbp = next_rbp; 691 next_rbp += 8; 692 next_reg++; 693 } 694 } 695 func_declares = tree->declares; 696 machine_code[mc_ptr++] = 0x55; 697 machine_code[mc_ptr++] = 0x48; 698 machine_code[mc_ptr++] = 0x89; 699 machine_code[mc_ptr++] = 0xE5; 700 701 if (tree->declares) { 702 machine_code[mc_ptr++] = 0x48; 703 machine_code[mc_ptr++] = 0x81; 704 machine_code[mc_ptr++] = 0xEC; 705 *(int *) &machine_code[mc_ptr] = tree->declares*8; 706 mc_ptr += 4; 707 } 708 709 if (tree->args[1].type == idnt && tree->args[1].id_type == parameter) { 710 machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 4 : 0); 711 machine_code[mc_ptr++] = 0x89; 712 machine_code[mc_ptr++] = 0x45 + (arg_order[0] % 8) * 8; 713 machine_code[mc_ptr++] = -regs[registers].rbp; 714 reg_hist[arg_order[0]].type = 1; 715 reg_hist[arg_order[0]].reg = registers; 716 reg_hist[arg_order[0]].rev = ++regs[registers].rev; 717 } else if (tree->args[1].type == comma && tree->args[1].args->type == idnt && tree->args[1].args->id_type == parameter) { 718 for (i = 0; i < tree->args[1].args_count; i++) { 719 machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 4 : 0); 720 machine_code[mc_ptr++] = 0x89; 721 machine_code[mc_ptr++] = 0x45 + (arg_order[i] % 8) * 8; 722 machine_code[mc_ptr++] = -regs[registers + i].rbp; 723 reg_hist[arg_order[i]].type = 1; 724 reg_hist[arg_order[i]].reg = registers + i; 725 reg_hist[arg_order[i]].rev = ++regs[registers + i].rev; 726 } 727 } 728 } 729 j = compile_tree(output, &tree->args[tree->args_count-1], 1, 0); 730 if (strcmp(tree->args->str, "_start") && j != -3 && j != -2) { 731 machine_code[mc_ptr++] = 0xc9; 732 machine_code[mc_ptr++] = 0xc3; 733 } 734 break; 735 case comma: 736 for (i = 0; i < tree->args_count; i++) { 737 j = compile_tree(output, &tree->args[i], (i+1 == tree->args_count ? discard_result : 1), (i+1 == tree->args_count ? out_reg : -1)); 738 if (j == -2 || j == -3) return j; 739 } 740 if (!discard_result) reg = j; 741 break; 742 case fcall: 743 for (i = 0; i < registers; i++) { 744 if (caller_save & (1 << i)) { 745 push(i, &pushed, push_order, "fcall (caller_save)"); 746 } 747 } 748 if (tree->args_count == 2) { 749 if (tree->args[1].type == comma) { 750 for (i = 0; i < tree->args[1].args_count; i++) { 751 j = compile_tree(output, &tree->args[1].args[i], 0, arg_order[i]); 752 } 753 } else { 754 j = compile_tree(output, &tree->args[1], 0, arg_order[0]); 755 } 756 } 757 machine_code[mc_ptr++] = 0xe8; 758 if (find_idnt(tree->args->str)->flags & 1) { 759 j = find_idnt(tree->args->str)->i - start_addr - mc_ptr - 4; 760 } else { 761 func_append(tree->args->str, mc_ptr); 762 j = 0; 763 } 764 *(int32_t *) &machine_code[mc_ptr] = j; 765 mc_ptr += 4; 766 767 if (tree->args[1].type == comma) 768 for (i = 0; i < tree->args[1].args_count; i++) 769 used_regs &= ~(1 << arg_order[i]); 770 else 771 used_regs &= ~(1 << arg_order[0]); 772 773 memset(reg_hist, 0, sizeof(reg_hist)); 774 if (!discard_result) { 775 reg = 0; 776 used_regs |= !(pushed & 1); 777 } 778 break; 779 case add: 780 if (!discard_result && 781 (tree->args->type == idnt || tree->args[1].type == idnt)) { 782 if (tree->args->type == idnt) { 783 j = compile_tree(output, tree->args, discard_result, -1); 784 tmp = &tree->args[1]; 785 } else { 786 j = compile_tree(output, &tree->args[1], discard_result, -1); 787 tmp = tree->args; 788 } 789 if (j == out_reg && tmp->type == number && 790 tmp->i < (long) 0x80000000 && tmp->i >= (long) -0x80000000) { 791 reg = j; 792 k = (int) tmp->i; 793 machine_code[mc_ptr++] = 0x48; 794 machine_code[mc_ptr++] = 0x81; 795 machine_code[mc_ptr++] = 0x45; 796 *(int32_t *) &machine_code[mc_ptr] = k; 797 mc_ptr += 4; 798 break; 799 } 800 } else { 801 j = compile_tree(output, tree->args, discard_result, -1); 802 } 803 k = compile_tree(output, &tree->args[1], discard_result, -1); 804 if (discard_result) { 805 if (j >= 0 && j < registers) used_regs &= ~(1 << j); 806 if (k >= 0 && k < registers) used_regs &= ~(1 << k); 807 break; 808 } 809 if (out_reg < 0 || out_reg != j && out_reg != k) { 810 if (k >= registers) { 811 if (j >= registers) { 812 reg = out_reg; 813 if (out_reg < 0 || out_reg >= registers) 814 reg = get_free_reg(1); 815 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 816 machine_code[mc_ptr++] = 0x8b; 817 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 818 machine_code[mc_ptr++] = -regs[j].rbp; 819 j = reg; 820 } 821 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 822 machine_code[mc_ptr++] = 0x03; 823 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 824 machine_code[mc_ptr++] = -regs[k].rbp; 825 reg = j, l = k; 826 } else if (j >= registers) { 827 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 828 machine_code[mc_ptr++] = 0x03; 829 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 830 machine_code[mc_ptr++] = -regs[j].rbp; 831 reg = k, l = j; 832 } else { 833 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0); 834 machine_code[mc_ptr++] = 0x03; 835 machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + (k % 8); 836 reg = j, l = k; 837 } 838 } else { 839 if (out_reg == k) { 840 l = j; 841 j = k; 842 k = l; 843 } 844 if (j >= registers) { 845 if (k >= registers) { 846 reg = get_free_reg(1); 847 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 848 machine_code[mc_ptr++] = 0x8b; 849 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 850 machine_code[mc_ptr++] = -regs[k].rbp; 851 k = reg; 852 } 853 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 854 machine_code[mc_ptr++] = 0x01; 855 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 856 machine_code[mc_ptr++] = -regs[j].rbp; 857 } else if (k >= registers) { 858 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 859 machine_code[mc_ptr++] = 0x03; 860 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 861 machine_code[mc_ptr++] = -regs[k].rbp; 862 } else { 863 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0); 864 machine_code[mc_ptr++] = 0x03; 865 machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + (k % 8); 866 if (reg_hist[j].type & 2 && reg_hist[k].type & 2) { 867 reg_hist[j].type = 2; 868 reg_hist[j].val += reg_hist[k].val; 869 } else if (reg_hist[j].type & 2) { 870 reg_hist[j].type = 0; 871 } 872 } 873 reg = j, l = k; 874 } 875 if (l < registers) used_regs &= ~(1 << l); 876 break; 877 case neg: 878 j = compile_tree(output, tree->args, discard_result, (out_reg >= 0 ? out_reg : get_free_reg(1))); 879 if (discard_result) { 880 if (j < registers) used_regs &= ~(1 << j); 881 break; 882 } 883 reg = j; 884 if (reg >= registers) { 885 machine_code[mc_ptr++] = 0x48; 886 machine_code[mc_ptr++] = 0xf7; 887 machine_code[mc_ptr++] = 0x5d; 888 machine_code[mc_ptr++] = -regs[reg].rbp; 889 } else { 890 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 891 machine_code[mc_ptr++] = 0xf7; 892 machine_code[mc_ptr++] = 0xd8 + (reg % 8); 893 } 894 break; 895 case mul: 896 j = compile_tree(output, tree->args, discard_result, -1); 897 k = compile_tree(output, &tree->args[1], discard_result, -1); 898 if (discard_result) { 899 if (j < registers) used_regs &= ~(1 << j); 900 if (k < registers) used_regs &= ~(1 << k); 901 break; 902 } 903 if (out_reg < 0 || out_reg != j && out_reg != k) { 904 if (k >= registers) { 905 if (j >= registers) { 906 reg = out_reg; 907 if (out_reg < 0 || out_reg >= registers) 908 reg = get_free_reg(1); 909 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 910 machine_code[mc_ptr++] = 0x8b; 911 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 912 machine_code[mc_ptr++] = -regs[j].rbp; 913 j = reg; 914 } 915 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 916 machine_code[mc_ptr++] = 0x0F; 917 machine_code[mc_ptr++] = 0xAF; 918 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 919 machine_code[mc_ptr++] = -regs[k].rbp; 920 reg = j, l = k; 921 } else if (j >= registers) { 922 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 923 machine_code[mc_ptr++] = 0x0F; 924 machine_code[mc_ptr++] = 0xAF; 925 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 926 machine_code[mc_ptr++] = -regs[j].rbp; 927 reg = k, l = j; 928 } else { 929 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0); 930 machine_code[mc_ptr++] = 0x0F; 931 machine_code[mc_ptr++] = 0xAF; 932 machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + (k % 8); 933 reg = j, l = k; 934 } 935 } else { 936 if (out_reg == k) { 937 l = j; 938 j = k; 939 k = l; 940 } 941 if (j >= registers) { 942 reg = get_free_reg(1); 943 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 944 machine_code[mc_ptr++] = 0x8b; 945 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 946 machine_code[mc_ptr++] = -regs[j].rbp; 947 j = reg; 948 if (k >= registers) { 949 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 950 machine_code[mc_ptr++] = 0x0F; 951 machine_code[mc_ptr++] = 0xAF; 952 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 953 machine_code[mc_ptr++] = -regs[k].rbp; 954 } else { 955 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0); 956 machine_code[mc_ptr++] = 0x0F; 957 machine_code[mc_ptr++] = 0xAF; 958 machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + (k % 8); 959 //machine_code[mc_ptr++] = -regs[j].rbp; 960 } 961 } else if (k >= registers) { 962 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 963 machine_code[mc_ptr++] = 0x0F; 964 machine_code[mc_ptr++] = 0xAF; 965 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 966 machine_code[mc_ptr++] = -regs[k].rbp; 967 } else { 968 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0); 969 machine_code[mc_ptr++] = 0x0F; 970 machine_code[mc_ptr++] = 0xAF; 971 machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + (k % 8); 972 if (reg_hist[j].type & 2 && reg_hist[k].type & 2) { 973 reg_hist[j].type = 2; 974 reg_hist[j].val += reg_hist[k].val; 975 } else if (reg_hist[j].type & 2) { 976 reg_hist[j].type = 0; 977 } 978 } 979 reg = j, l = k; 980 } 981 if (l < registers) used_regs &= ~(1 << l); 982 break; 983 /* 984 j = compile_tree(output, tree->args, discard_result, -1); 985 k = compile_tree(output, &tree->args[1], discard_result, -1); 986 if (discard_result) { 987 if (j < registers) used_regs &= ~(1 << j); 988 if (k < registers) used_regs &= ~(1 << k); 989 break; 990 } 991 reg = j; 992 if ((out_reg == -1 || out_reg >= registers) && j >= registers) { 993 reg = get_free_reg(1); 994 if (j >= registers) { 995 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 996 machine_code[mc_ptr++] = 0x8b; 997 machine_code[mc_ptr++] = 0x45 + reg*8; 998 machine_code[mc_ptr++] = -regs[j].rbp; 999 } else { 1000 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1001 machine_code[mc_ptr++] = 0x8b; 1002 machine_code[mc_ptr++] = 0x45 + reg*8; 1003 } 1004 } 1005 1006 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1007 machine_code[mc_ptr++] = 0x0F; 1008 machine_code[mc_ptr++] = 0xAF; 1009 if (k >= registers) { 1010 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1011 machine_code[mc_ptr++] = -regs[k].rbp; 1012 } else { 1013 machine_code[mc_ptr-3] |= (k > 7 ? 1 : 0); 1014 machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + (k % 8); 1015 used_regs &= ~(1 << k); 1016 } 1017 break; 1018 */ 1019 case divide: 1020 if (discard_result) { 1021 j = compile_tree(output, tree->args, 1, -1); 1022 k = compile_tree(output, &tree->args[1], 1, -1); 1023 if (j < registers) used_regs &= ~(1 << j); 1024 break; 1025 } 1026 push(0, &pushed, push_order, "divide (rax)"); 1027 push(2, &pushed, push_order, "divide (rdx)"); 1028 j = compile_tree(output, tree->args, 0, 0); 1029 machine_code[mc_ptr++] = 0x48; 1030 machine_code[mc_ptr++] = 0x99; 1031 used_regs |= (1 << 0) | (1 << 2); 1032 1033 k = compile_tree(output, &tree->args[1], 0, -1); 1034 machine_code[mc_ptr++] = 0x48; 1035 machine_code[mc_ptr++] = 0xF7; 1036 if (k >= registers) { 1037 machine_code[mc_ptr++] = 0x7d; 1038 machine_code[mc_ptr++] = -regs[k].rbp; 1039 } else { 1040 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1041 machine_code[mc_ptr++] = 0xf8 + (k % 8); 1042 used_regs &= ~(1 << k); 1043 } 1044 reg = 0; 1045 break; 1046 case mod: 1047 if (discard_result) { 1048 j = compile_tree(output, tree->args, 1, -1); 1049 k = compile_tree(output, &tree->args[1], 1, -1); 1050 if (j < registers) used_regs &= ~(1 << j); 1051 break; 1052 } 1053 push(0, &pushed, push_order, "mod (rax)"); 1054 push(2, &pushed, push_order, "mod (rdx)"); 1055 j = compile_tree(output, tree->args, 0, 0); 1056 machine_code[mc_ptr++] = 0x48; 1057 machine_code[mc_ptr++] = 0x99; 1058 used_regs |= (1 << 0) | (1 << 2); 1059 1060 k = compile_tree(output, &tree->args[1], 0, -1); 1061 machine_code[mc_ptr++] = 0x48; 1062 machine_code[mc_ptr++] = 0xF7; 1063 if (k >= registers) { 1064 machine_code[mc_ptr++] = 0x7d; 1065 machine_code[mc_ptr++] = -regs[k].rbp; 1066 } else { 1067 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1068 machine_code[mc_ptr++] = 0xf8 + (k % 8); 1069 used_regs &= ~(1 << k); 1070 } 1071 reg = 2; 1072 break; 1073 case shift_l: 1074 j = compile_tree(output, tree->args, discard_result, out_reg); 1075 k = compile_tree(output, &tree->args[1], discard_result, 1); 1076 if (discard_result) { 1077 if (j < registers) used_regs &= ~(1 << j); 1078 if (k < registers) used_regs &= ~(1 << k); 1079 break; 1080 } 1081 if (k != 1) { 1082 if (used_regs & (1 << 1)) { 1083 fprintf(stderr, "Not implemented yet! (rcx)\n"); 1084 exit(1); 1085 } 1086 used_regs |= (1 << 1); 1087 if (k >= registers) { 1088 machine_code[mc_ptr++] = 0x48; 1089 machine_code[mc_ptr++] = 0x8b; 1090 machine_code[mc_ptr++] = 0x4d; 1091 machine_code[mc_ptr++] = -regs[k].rbp; 1092 } else { 1093 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 1 : 0); 1094 machine_code[mc_ptr++] = 0x8b; 1095 machine_code[mc_ptr++] = 0xc8 + (k % 8); 1096 used_regs &= ~(1 << k); 1097 } 1098 k = 1; 1099 } 1100 reg = j; 1101 if (reg >= registers) { 1102 reg = get_free_reg(1); 1103 machine_code[mc_ptr++] = 0x48; 1104 machine_code[mc_ptr++] = 0x8b; 1105 machine_code[mc_ptr++] = 0x45 + reg*8; 1106 machine_code[mc_ptr++] = -regs[j].rbp; 1107 } 1108 machine_code[mc_ptr++] = 0x48; 1109 machine_code[mc_ptr++] = 0xd3; 1110 machine_code[mc_ptr++] = 0xe0 + reg; 1111 1112 if (k < registers) used_regs &= ~(1 << k); 1113 break; 1114 case shift_r: 1115 j = compile_tree(output, tree->args, discard_result, out_reg); 1116 k = compile_tree(output, &tree->args[1], discard_result, 1); 1117 if (discard_result) { 1118 if (j < registers) used_regs &= ~(1 << j); 1119 if (k < registers) used_regs &= ~(1 << k); 1120 break; 1121 } 1122 if (k != 1) { 1123 if (used_regs & (1 << 1)) { 1124 fprintf(stderr, "Not implemented yet! (rcx)\n"); 1125 exit(1); 1126 } 1127 used_regs |= (1 << 1); 1128 if (k >= registers) { 1129 machine_code[mc_ptr++] = 0x48; 1130 machine_code[mc_ptr++] = 0x8b; 1131 machine_code[mc_ptr++] = 0x4d; 1132 machine_code[mc_ptr++] = -regs[k].rbp; 1133 } else { 1134 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 1 : 0); 1135 machine_code[mc_ptr++] = 0x8b; 1136 machine_code[mc_ptr++] = 0xc8 + (k % 8); 1137 used_regs &= ~(1 << k); 1138 } 1139 k = 1; 1140 } 1141 reg = j; 1142 if (reg >= registers) { 1143 reg = get_free_reg(1); 1144 machine_code[mc_ptr++] = 0x48; 1145 machine_code[mc_ptr++] = 0x8b; 1146 machine_code[mc_ptr++] = 0x45 + reg*8; 1147 machine_code[mc_ptr++] = -regs[j].rbp; 1148 } 1149 machine_code[mc_ptr++] = 0x48; 1150 machine_code[mc_ptr++] = 0xd3; 1151 machine_code[mc_ptr++] = 0xe8 + reg; 1152 1153 if (k < registers) used_regs &= ~(1 << k); 1154 break; 1155 case b_and: 1156 j = compile_tree(output, tree->args, discard_result, out_reg); 1157 k = compile_tree(output, &tree->args[1], discard_result, -1); 1158 if (discard_result) { 1159 if (j < registers) used_regs &= ~(1 << j); 1160 if (k < registers) used_regs &= ~(1 << k); 1161 break; 1162 } 1163 reg = j; 1164 if (reg >= registers) { 1165 reg = get_free_reg(1); 1166 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1167 machine_code[mc_ptr++] = 0x8b; 1168 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1169 machine_code[mc_ptr++] = -regs[j].rbp; 1170 } 1171 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1172 machine_code[mc_ptr++] = 0x23; 1173 if (tree->args[1].type == idnt) { 1174 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1175 machine_code[mc_ptr++] = -regs[k].rbp; 1176 } else { 1177 machine_code[mc_ptr-2] |= k > 7 ? 1 : 0; 1178 machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + (k % 8); 1179 } 1180 if (k < registers) used_regs &= ~(1 << k); 1181 break; 1182 case b_or: 1183 j = compile_tree(output, tree->args, discard_result, out_reg); 1184 k = compile_tree(output, &tree->args[1], discard_result, -1); 1185 if (discard_result) { 1186 if (j < registers) used_regs &= ~(1 << j); 1187 if (k < registers) used_regs &= ~(1 << k); 1188 break; 1189 } 1190 reg = j; 1191 if (reg >= registers) { 1192 reg = get_free_reg(1); 1193 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1194 machine_code[mc_ptr++] = 0x8b; 1195 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1196 machine_code[mc_ptr++] = -regs[j].rbp; 1197 } 1198 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1199 machine_code[mc_ptr++] = 0x0b; 1200 if (tree->args[1].type == idnt) { 1201 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1202 machine_code[mc_ptr++] = -regs[k].rbp; 1203 } else { 1204 machine_code[mc_ptr-2] |= k > 7 ? 1 : 0; 1205 machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + (k % 8); 1206 } 1207 if (k < registers) used_regs &= ~(1 << k); 1208 break; 1209 case b_xor: 1210 j = compile_tree(output, tree->args, discard_result, out_reg); 1211 k = compile_tree(output, &tree->args[1], discard_result, -1); 1212 if (discard_result) { 1213 if (j < registers) used_regs &= ~(1 << j); 1214 if (k < registers) used_regs &= ~(1 << k); 1215 break; 1216 } 1217 reg = j; 1218 if (reg >= registers) { 1219 reg = get_free_reg(1); 1220 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1221 machine_code[mc_ptr++] = 0x8b; 1222 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1223 machine_code[mc_ptr++] = -regs[j].rbp; 1224 } 1225 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1226 machine_code[mc_ptr++] = 0x33; 1227 if (tree->args[1].type == idnt) { 1228 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1229 machine_code[mc_ptr++] = -regs[k].rbp; 1230 } else { 1231 machine_code[mc_ptr-2] |= k > 7 ? 1 : 0; 1232 machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + (k % 8); 1233 } 1234 if (k < registers) used_regs &= ~(1 << k); 1235 break; 1236 case decl: 1237 reg = next_reg++; 1238 regs[reg].type = 1; 1239 regs[reg].rbp = next_rbp; 1240 next_rbp += 8; 1241 regs[reg].var = tree->args->str; 1242 break; 1243 case set: 1244 /* 1245 reg = compile_tree(output, tree->args, 0, -1); 1246 j = compile_tree(output, &tree->args[1], 0, reg); 1247 break; 1248 case set: 1249 */ 1250 if (tree->args->type == deref) 1251 reg = compile_tree(output, tree->args->args, 0, -1); 1252 else 1253 reg = compile_tree(output, tree->args, 0, -1); 1254 if (reg >= registers && tree->args->type != deref) { 1255 j = compile_tree(output, &tree->args[1], 0, reg); 1256 break; 1257 } 1258 j = compile_tree(output, &tree->args[1], 0, -1); 1259 if (j < 0) { 1260 fprintf(stderr, "No rvalue for assignment\n"); 1261 exit(1); 1262 } 1263 if (j >= registers) { 1264 k = get_free_reg(1); 1265 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1266 machine_code[mc_ptr++] = 0x8b; 1267 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1268 machine_code[mc_ptr++] = -regs[j].rbp; 1269 } else { 1270 k = j; 1271 } 1272 if (tree->args->type == deref) { 1273 if (reg >= registers) { 1274 j = get_free_reg(1); 1275 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1276 machine_code[mc_ptr++] = 0x8b; 1277 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1278 machine_code[mc_ptr++] = -regs[reg].rbp; 1279 reg = j; 1280 } 1281 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0) | (k > 7 ? 4 : 0); 1282 machine_code[mc_ptr++] = 0x89; 1283 machine_code[mc_ptr++] = 0x00 + (reg % 8) + (k % 8) * 8; 1284 } else if (reg >= registers) { 1285 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1286 machine_code[mc_ptr++] = 0x89; 1287 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1288 machine_code[mc_ptr++] = -regs[reg].rbp; 1289 } 1290 if (discard_result) { 1291 used_regs &= ~(1 << k); 1292 used_regs &= ~(1 << reg); 1293 reg = -1; 1294 break; 1295 } 1296 reg = k; 1297 break; 1298 case ref: 1299 if (tree->args->type != idnt) { 1300 fprintf(stderr, "Unable to reference non-identifier\n"); 1301 exit(1); 1302 } 1303 if (discard_result) break; 1304 j = compile_tree(output, tree->args, 0, -1); 1305 reg = out_reg; 1306 if (out_reg < 0 || out_reg >= registers) 1307 reg = get_free_reg(1); 1308 used_regs |= (1 << reg); 1309 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1310 machine_code[mc_ptr++] = 0x8d; 1311 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1312 machine_code[mc_ptr++] = -regs[j].rbp; 1313 break; 1314 case deref: 1315 j = compile_tree(output, tree->args, discard_result, out_reg); 1316 if (discard_result) { 1317 if (used_regs & (1 << j)) used_regs &= ~(1 << j); 1318 break; 1319 } 1320 reg = j; 1321 if (j >= registers) { 1322 reg = get_free_reg(1); 1323 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1324 machine_code[mc_ptr++] = 0x8b; 1325 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1326 machine_code[mc_ptr++] = -regs[j].rbp; 1327 } 1328 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0); 1329 machine_code[mc_ptr++] = 0x8b; 1330 machine_code[mc_ptr++] = 0x00 + (reg % 8) + (reg % 8) * 8; 1331 break; 1332 case idnt: 1333 if (discard_result) break; 1334 for (reg = registers; reg < 1024; reg++) { 1335 if (regs[reg].type != 1) continue; 1336 if (!strcmp(regs[reg].var, tree->str)) break; 1337 } 1338 if (reg == 1024) { 1339 fprintf(stderr, "Unable to locate identifier <%s>\n", tree->str); 1340 exit(1); 1341 } 1342 /* 1343 for (i = 0; i < registers; i++) { 1344 if (reg_hist[i].type & 1 && reg_hist[i].reg == reg && reg_hist[i].rev == regs[reg].rev) { 1345 reg = i; 1346 used_regs |= (1 << reg); 1347 break; 1348 } 1349 } 1350 */ 1351 break; 1352 case number: 1353 if (discard_result) break; 1354 /* 1355 for (i = 0; i < registers; i++) { 1356 if (reg_hist[i].type & 2 && reg_hist[i].val == tree->i) { 1357 reg = i; 1358 break; 1359 } 1360 } 1361 */ 1362 if (out_reg < 0 || out_reg >= registers) 1363 reg = get_free_reg(1); 1364 else 1365 reg = out_reg; 1366 if (tree->i) { 1367 if (tree->i == 1) { 1368 if (reg > 7) 1369 machine_code[mc_ptr++] = 0x41; 1370 machine_code[mc_ptr++] = 0x33; 1371 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1372 if (reg > 7) 1373 machine_code[mc_ptr++] = 0x41; 1374 machine_code[mc_ptr++] = 0xff; 1375 machine_code[mc_ptr++] = 0xc0 + (reg % 8); 1376 } else if (tree->i == -1) { 1377 if (reg > 7) 1378 machine_code[mc_ptr++] = 0x41; 1379 machine_code[mc_ptr++] = 0x33; 1380 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1381 1382 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1383 machine_code[mc_ptr++] = 0xff; 1384 machine_code[mc_ptr++] = 0xc8 + (reg % 8); 1385 } else if (tree->i <= 0x7FFFFFFF && tree->i > 0) { 1386 if (reg > 7) 1387 machine_code[mc_ptr++] = 0x41; 1388 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1389 *(int32_t *) &machine_code[mc_ptr] = (int) tree->i; 1390 mc_ptr += 4; 1391 } else if (tree->i < 0 && -tree->i <= 0x7FFFFFFF) { 1392 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1393 machine_code[mc_ptr++] = 0xc7; 1394 machine_code[mc_ptr++] = 0xc0 + (reg % 8); 1395 *(int32_t *) &machine_code[mc_ptr] = (int) tree->i; 1396 mc_ptr += 4; 1397 } else { 1398 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1399 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1400 *(int64_t *) &machine_code[mc_ptr] = tree->i; 1401 mc_ptr += 8; 1402 } 1403 } else { 1404 if (reg > 7) 1405 machine_code[mc_ptr++] = 0x45; 1406 machine_code[mc_ptr++] = 0x33; 1407 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1408 } 1409 reg_hist[reg].type = 2; 1410 reg_hist[reg].val = tree->i; 1411 break; 1412 case string: 1413 if (discard_result) break; 1414 reg = out_reg; 1415 if (reg == -1 || reg >= registers) 1416 reg = get_free_reg(1); 1417 if (!tree->i) { 1418 strcpy(&rodata[rd_ptr], tree->str); 1419 tree->i = rodata_addr + rd_ptr; 1420 rd_ptr += strlen(tree->str) + 1; 1421 } 1422 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1423 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1424 *(int64_t *) &machine_code[mc_ptr] = tree->i; 1425 mc_ptr += 8; 1426 break; 1427 case loop: 1428 memset(reg_hist, 0, sizeof(reg_hist)); 1429 machine_code[mc_ptr++] = 0xe9; 1430 l = mc_ptr; 1431 mc_ptr += 4; 1432 compile_tree(output, &tree->args[1], 1, -1); 1433 *(int32_t *) &machine_code[l] = mc_ptr - l - 4; 1434 switch (tree->args->type) { 1435 case l_not: 1436 j = compile_tree(output, tree->args->args, 0, -1); 1437 if (j >= registers) { 1438 machine_code[mc_ptr++] = 0x48; 1439 machine_code[mc_ptr++] = 0x83; 1440 machine_code[mc_ptr++] = 0x7d; 1441 machine_code[mc_ptr++] = -regs[j].rbp; 1442 } else { 1443 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0); 1444 machine_code[mc_ptr++] = 0x83; 1445 machine_code[mc_ptr++] = 0xf8 + (j % 8); 1446 } 1447 machine_code[mc_ptr++] = 0x00; 1448 machine_code[mc_ptr++] = 0x0f; 1449 machine_code[mc_ptr++] = 0x84; 1450 *(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1451 mc_ptr += 4; 1452 break; 1453 case l_eq: 1454 j = compile_tree(output, tree->args->args, 0, -1); 1455 k = compile_tree(output, &tree->args->args[1], 0, -1); 1456 if (j >= registers) { 1457 if (k >= registers) { 1458 k = compile_tree(output, &tree->args->args[1], 0, get_free_reg(0)); 1459 } 1460 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1461 machine_code[mc_ptr++] = 0x39; 1462 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1463 machine_code[mc_ptr++] = -regs[j].rbp; 1464 } else { 1465 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1466 machine_code[mc_ptr++] = 0x3b; 1467 if (k >= registers) { 1468 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1469 machine_code[mc_ptr++] = -regs[k].rbp; 1470 } else { 1471 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1472 machine_code[mc_ptr++] = 0xc0 + (k % 8) + (j % 8) * 8; 1473 } 1474 } 1475 machine_code[mc_ptr++] = 0x0f; 1476 machine_code[mc_ptr++] = 0x84; 1477 *(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1478 mc_ptr += 4; 1479 break; 1480 case l_lt: 1481 j = compile_tree(output, tree->args->args, 0, -1); 1482 k = compile_tree(output, &tree->args->args[1], 0, -1); 1483 if (j >= registers) { 1484 if (k >= registers) { 1485 k = compile_tree(output, &tree->args->args[1], 0, get_free_reg(0)); 1486 } 1487 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1488 machine_code[mc_ptr++] = 0x39; 1489 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1490 machine_code[mc_ptr++] = -regs[j].rbp; 1491 } else { 1492 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1493 machine_code[mc_ptr++] = 0x3b; 1494 if (k >= registers) { 1495 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1496 machine_code[mc_ptr++] = -regs[k].rbp; 1497 } else { 1498 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1499 machine_code[mc_ptr++] = 0xc0 + (k % 8) + (j % 8) * 8; 1500 } 1501 } 1502 machine_code[mc_ptr++] = 0x0f; 1503 machine_code[mc_ptr++] = 0x8c; 1504 *(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1505 mc_ptr += 4; 1506 break; 1507 default: 1508 j = compile_tree(output, tree->args, 0, -1); 1509 if (j >= registers) { 1510 machine_code[mc_ptr++] = 0x48; 1511 machine_code[mc_ptr++] = 0x83; 1512 machine_code[mc_ptr++] = 0x7d; 1513 machine_code[mc_ptr++] = -regs[j].rbp; 1514 } else { 1515 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0); 1516 machine_code[mc_ptr++] = 0x83; 1517 machine_code[mc_ptr++] = 0xf8 + (j % 8); 1518 } 1519 machine_code[mc_ptr++] = 0x00; 1520 machine_code[mc_ptr++] = 0x0f; 1521 machine_code[mc_ptr++] = 0x85; 1522 *(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1523 mc_ptr += 4; 1524 break; 1525 } 1526 used_regs = (1 << 5) | (1 << 4); 1527 for (i = 0; i < registers; i++) 1528 reg_hist[i].type = 0; 1529 break; 1530 case ifnz: 1531 /* 1532 j = compile_tree(output, tree->args, 0, -1); 1533 if (j >= registers) { 1534 machine_code[mc_ptr++] = 0x48; 1535 machine_code[mc_ptr++] = 0x83; 1536 machine_code[mc_ptr++] = 0x7d; 1537 machine_code[mc_ptr++] = -regs[j].rbp; 1538 machine_code[mc_ptr++] = 0x00; 1539 } else { 1540 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0); 1541 machine_code[mc_ptr++] = 0x83; 1542 machine_code[mc_ptr++] = 0xf8 + (j % 8); 1543 machine_code[mc_ptr++] = 0x00; 1544 } 1545 //machine_code[mc_ptr++] = 0x00; 1546 machine_code[mc_ptr++] = 0x0f; 1547 machine_code[mc_ptr++] = 0x84; 1548 k = mc_ptr; 1549 mc_ptr += 4; 1550 */ 1551 switch (tree->args->type) { 1552 case l_not: 1553 j = compile_tree(output, tree->args->args, 0, -1); 1554 if (j >= registers) { 1555 machine_code[mc_ptr++] = 0x48; 1556 machine_code[mc_ptr++] = 0x83; 1557 machine_code[mc_ptr++] = 0x7d; 1558 machine_code[mc_ptr++] = -regs[j].rbp; 1559 } else { 1560 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0); 1561 machine_code[mc_ptr++] = 0x83; 1562 machine_code[mc_ptr++] = 0xf8 + (j % 8); 1563 } 1564 machine_code[mc_ptr++] = 0x00; 1565 machine_code[mc_ptr++] = 0x0f; 1566 machine_code[mc_ptr++] = 0x85; 1567 //*(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1568 k = mc_ptr; 1569 mc_ptr += 4; 1570 break; 1571 case l_eq: 1572 j = compile_tree(output, tree->args->args, 0, -1); 1573 k = compile_tree(output, &tree->args->args[1], 0, -1); 1574 if (j >= registers) { 1575 if (k >= registers) { 1576 k = compile_tree(output, &tree->args->args[1], 0, get_free_reg(0)); 1577 } 1578 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1579 machine_code[mc_ptr++] = 0x39; 1580 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1581 machine_code[mc_ptr++] = -regs[j].rbp; 1582 } else { 1583 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1584 machine_code[mc_ptr++] = 0x3b; 1585 if (k >= registers) { 1586 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1587 machine_code[mc_ptr++] = -regs[k].rbp; 1588 } else { 1589 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1590 machine_code[mc_ptr++] = 0xc0 + (k % 8) + (j % 8) * 8; 1591 } 1592 } 1593 machine_code[mc_ptr++] = 0x0f; 1594 machine_code[mc_ptr++] = 0x85; 1595 //*(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1596 k = mc_ptr; 1597 mc_ptr += 4; 1598 break; 1599 case l_lt: 1600 j = compile_tree(output, tree->args->args, 0, -1); 1601 k = compile_tree(output, &tree->args->args[1], 0, -1); 1602 if (j >= registers) { 1603 if (k >= registers) { 1604 k = compile_tree(output, &tree->args->args[1], 0, get_free_reg(0)); 1605 } 1606 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1607 machine_code[mc_ptr++] = 0x39; 1608 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1609 machine_code[mc_ptr++] = -regs[j].rbp; 1610 } else { 1611 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1612 machine_code[mc_ptr++] = 0x3b; 1613 if (k >= registers) { 1614 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1615 machine_code[mc_ptr++] = -regs[k].rbp; 1616 } else { 1617 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1618 machine_code[mc_ptr++] = 0xc0 + (k % 8) + (j % 8) * 8; 1619 } 1620 } 1621 machine_code[mc_ptr++] = 0x0f; 1622 machine_code[mc_ptr++] = 0x8d; 1623 //*(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1624 k = mc_ptr; 1625 mc_ptr += 4; 1626 break; 1627 case b_and: 1628 j = compile_tree(output, tree->args->args, 0, -1); 1629 k = compile_tree(output, &tree->args->args[1], 0, -1); 1630 if (j >= registers) { 1631 if (k >= registers) { 1632 k = compile_tree(output, &tree->args->args[1], 0, get_free_reg(0)); 1633 } 1634 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1635 machine_code[mc_ptr++] = 0x85; 1636 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1637 machine_code[mc_ptr++] = -regs[j].rbp; 1638 } else { 1639 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1640 machine_code[mc_ptr++] = 0x85; 1641 if (k >= registers) { 1642 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1643 machine_code[mc_ptr++] = -regs[k].rbp; 1644 } else { 1645 machine_code[mc_ptr-2] |= (k > 7 ? 1 : 0); 1646 machine_code[mc_ptr++] = 0xc0 + (k % 8) + (j % 8) * 8; 1647 } 1648 } 1649 machine_code[mc_ptr++] = 0x0f; 1650 machine_code[mc_ptr++] = 0x84; 1651 //*(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1652 k = mc_ptr; 1653 mc_ptr += 4; 1654 break; 1655 default: 1656 j = compile_tree(output, tree->args, 0, -1); 1657 if (j >= registers) { 1658 machine_code[mc_ptr++] = 0x48; 1659 machine_code[mc_ptr++] = 0x83; 1660 machine_code[mc_ptr++] = 0x7d; 1661 machine_code[mc_ptr++] = -regs[j].rbp; 1662 } else { 1663 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0); 1664 machine_code[mc_ptr++] = 0x83; 1665 machine_code[mc_ptr++] = 0xf8 + (j % 8); 1666 } 1667 machine_code[mc_ptr++] = 0x00; 1668 machine_code[mc_ptr++] = 0x0f; 1669 machine_code[mc_ptr++] = 0x84; 1670 //*(int32_t *) &machine_code[mc_ptr] = -(mc_ptr - l); 1671 k = mc_ptr; 1672 mc_ptr += 4; 1673 break; 1674 } 1675 // True 1676 used_regs = (1 << 5) | (1 << 4); 1677 compile_tree(output, &tree->args[1], 1, -1); 1678 if (tree->args_count == 3) { 1679 machine_code[mc_ptr++] = 0xe9; 1680 l = mc_ptr; 1681 *(int32_t *) &machine_code[mc_ptr] = 0x00; 1682 mc_ptr += 4; 1683 // Else 1684 *(int32_t *) &machine_code[k] = mc_ptr - k - 4; 1685 compile_tree(output, &tree->args[2], 1, -1); 1686 *(int32_t *) &machine_code[l] = mc_ptr - l - 4; 1687 } else { 1688 *(int32_t *) &machine_code[k] = mc_ptr - k - 4; 1689 } 1690 used_regs = (1 << 5) | (1 << 4); 1691 for (i = 0; i < registers; i++) 1692 reg_hist[i].type = 0; 1693 break; 1694 case l_not: 1695 j = compile_tree(output, tree->args, discard_result, out_reg); 1696 if (discard_result) { 1697 if (j < registers) used_regs &= ~(1 << j); 1698 break; 1699 } 1700 reg = j; 1701 if (j >= registers) { 1702 reg = get_free_reg(1); 1703 machine_code[mc_ptr++] = 0x48; 1704 machine_code[mc_ptr++] = 0x83; 1705 machine_code[mc_ptr++] = 0x7d; 1706 machine_code[mc_ptr++] = -regs[j].rbp; 1707 } else { 1708 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1709 machine_code[mc_ptr++] = 0x83; 1710 machine_code[mc_ptr++] = 0xf8 + (reg % 8); 1711 } 1712 machine_code[mc_ptr++] = 0x00; 1713 machine_code[mc_ptr++] = 0x74; 1714 machine_code[mc_ptr++] = 0x05; 1715 // Not zero 1716 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0); 1717 machine_code[mc_ptr++] = 0x33; 1718 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1719 machine_code[mc_ptr++] = 0xeb; 1720 machine_code[mc_ptr++] = 0x0a; 1721 // Zero 1722 machine_code[mc_ptr++] = 0x48 + (reg > 7 ? 1 : 0); 1723 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1724 *(int64_t *) &machine_code[mc_ptr] = 1; 1725 mc_ptr += 8; 1726 break; 1727 case l_and: 1728 if (tree->args->type == number) 1729 k = tree->args->i, l = 1; 1730 else 1731 l = 0; 1732 if (l) { 1733 if (k) 1734 reg = compile_tree(output, &tree->args[1], discard_result, out_reg); 1735 else 1736 reg = compile_tree(output, tree->args, discard_result, out_reg); 1737 break; 1738 } 1739 j = compile_tree(output, tree->args, discard_result, out_reg); 1740 reg = j; 1741 if (j >= registers) { 1742 reg = get_free_reg(1); 1743 machine_code[mc_ptr++] = 0x48; 1744 machine_code[mc_ptr++] = 0x83; 1745 machine_code[mc_ptr++] = 0x7d; 1746 machine_code[mc_ptr++] = -regs[j].rbp; 1747 } else { 1748 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1749 machine_code[mc_ptr++] = 0x83; 1750 machine_code[mc_ptr++] = 0xf8 + (reg % 8); 1751 } 1752 machine_code[mc_ptr++] = 0x00; 1753 1754 machine_code[mc_ptr++] = 0x0f; 1755 machine_code[mc_ptr++] = 0x84; 1756 //machine_code[mc_ptr++] = 0x05; 1757 l = mc_ptr; 1758 mc_ptr += 4; 1759 // Not zero 1760 compile_tree(output, &tree->args[1], discard_result, reg); 1761 if (discard_result) { 1762 *(int32_t *) &machine_code[l] = mc_ptr - l; 1763 if (reg < registers) used_regs &= ~(1 << reg); 1764 break; 1765 } 1766 machine_code[mc_ptr++] = 0xeb; 1767 machine_code[mc_ptr++] = 0x03; 1768 *(int32_t *) &machine_code[l] = mc_ptr - l - 4; 1769 // Zero 1770 machine_code[mc_ptr++] = 0x48 + (reg > 7 ? 5 : 0); 1771 machine_code[mc_ptr++] = 0x33; 1772 machine_code[mc_ptr++] = 0xc0 + (reg % 8) * 8 + (reg % 8); 1773 break; 1774 case l_or: 1775 if (has_sideeffect(tree->args) || has_sideeffect(&tree->args[1]) || 1776 !discard_result) { 1777 if (tree->args->type == number) 1778 k = tree->args->i, l = 1; 1779 else 1780 l = 0; 1781 if (l) { 1782 if (k) 1783 reg = compile_tree(output, tree->args, discard_result, out_reg); 1784 else 1785 reg = compile_tree(output, &tree->args[1], discard_result, out_reg); 1786 break; 1787 } 1788 j = compile_tree(output, tree->args, 0, out_reg); 1789 reg = j; 1790 if (j >= registers) { 1791 reg = get_free_reg(1); 1792 machine_code[mc_ptr++] = 0x48; 1793 machine_code[mc_ptr++] = 0x83; 1794 machine_code[mc_ptr++] = 0x7d; 1795 machine_code[mc_ptr++] = -regs[j].rbp; 1796 } else { 1797 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0); 1798 machine_code[mc_ptr++] = 0x83; 1799 machine_code[mc_ptr++] = 0xf8 + (reg % 8); 1800 } 1801 machine_code[mc_ptr++] = 0x00; 1802 } 1803 1804 if (has_sideeffect(&tree->args[1]) || !discard_result) { 1805 machine_code[mc_ptr++] = 0x0f; 1806 machine_code[mc_ptr++] = 0x85; 1807 l = mc_ptr; 1808 mc_ptr += 4; 1809 compile_tree(output, &tree->args[1], discard_result, reg); 1810 *(int32_t *) &machine_code[l] = mc_ptr - l - 4; 1811 } 1812 if (discard_result) { 1813 if (reg >= 0 && reg < registers) used_regs &= ~(1 << reg); 1814 break; 1815 } 1816 break; 1817 case l_eq: 1818 j = compile_tree(output, tree->args, discard_result, -1); 1819 k = compile_tree(output, &tree->args[1], discard_result, -1); 1820 if (discard_result) { 1821 if (j < registers) used_regs &= ~(1 << j); 1822 if (k < registers) used_regs &= ~(1 << k); 1823 break; 1824 } 1825 reg = k; 1826 1827 if (j >= registers) { 1828 if (k >= registers) { 1829 reg = get_free_reg(1); 1830 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1831 machine_code[mc_ptr++] = 0x8b; 1832 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1833 machine_code[mc_ptr++] = -regs[k].rbp; 1834 k = reg; 1835 } 1836 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1837 machine_code[mc_ptr++] = 0x39; 1838 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1839 machine_code[mc_ptr++] = -regs[j].rbp; 1840 } else if (k >= registers) { 1841 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1842 machine_code[mc_ptr++] = 0x3b; 1843 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1844 machine_code[mc_ptr++] = -regs[k].rbp; 1845 } else { 1846 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0); 1847 machine_code[mc_ptr++] = 0x39; 1848 machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8; 1849 used_regs &= ~(1 << k); 1850 } 1851 if (j < registers && k >= registers) used_regs &= ~(1 << reg), reg = j; 1852 machine_code[mc_ptr++] = 0x74; 1853 machine_code[mc_ptr++] = 0x05; //Offset 1854 // Not less than: 1855 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0); 1856 machine_code[mc_ptr++] = 0x33; 1857 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1858 machine_code[mc_ptr++] = 0xeb; 1859 machine_code[mc_ptr++] = 0x0a; 1860 // Less than: 1861 machine_code[mc_ptr++] = 0x48 + (reg > 7 ? 1 : 0); 1862 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1863 *(int64_t *) &machine_code[mc_ptr] = 1; 1864 mc_ptr += 8; 1865 break; 1866 case l_lt: 1867 j = compile_tree(output, tree->args, discard_result, -1); 1868 k = compile_tree(output, &tree->args[1], discard_result, -1); 1869 if (discard_result) { 1870 if (j < registers) used_regs &= ~(1 << j); 1871 if (k < registers) used_regs &= ~(1 << k); 1872 break; 1873 } 1874 1875 reg = j; 1876 if (j >= registers) { 1877 reg = k; 1878 if (k >= registers) { 1879 reg = get_free_reg(1); 1880 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 1881 machine_code[mc_ptr++] = 0x8b; 1882 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 1883 machine_code[mc_ptr++] = -regs[k].rbp; 1884 k = reg; 1885 } 1886 machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0); 1887 machine_code[mc_ptr++] = 0x39; 1888 machine_code[mc_ptr++] = 0x45 + (k % 8) * 8; 1889 machine_code[mc_ptr++] = -regs[j].rbp; 1890 } else if (k >= registers) { 1891 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 1892 machine_code[mc_ptr++] = 0x3b; 1893 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 1894 machine_code[mc_ptr++] = -regs[k].rbp; 1895 } else { 1896 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0); 1897 machine_code[mc_ptr++] = 0x39; 1898 machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8; 1899 used_regs &= ~(1 << k); 1900 } 1901 if (reg != out_reg && out_reg >= 0) { 1902 used_regs &= ~(1 << reg); 1903 reg = out_reg; 1904 } 1905 machine_code[mc_ptr++] = 0x7c; 1906 machine_code[mc_ptr++] = 0x05; //Offset 1907 // Not less than: 1908 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0); 1909 machine_code[mc_ptr++] = 0x33; 1910 machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8; 1911 machine_code[mc_ptr++] = 0xeb; 1912 machine_code[mc_ptr++] = 0x0a; 1913 // Less than: 1914 machine_code[mc_ptr++] = 0x48 + (reg > 7 ? 1 : 0); 1915 machine_code[mc_ptr++] = 0xb8 + (reg % 8); 1916 *(int64_t *) &machine_code[mc_ptr] = 1; 1917 mc_ptr += 8; 1918 break; 1919 case ret: 1920 compile_tree(output, tree->args, 0, 0); 1921 machine_code[mc_ptr++] = 0xc9; 1922 machine_code[mc_ptr++] = 0xc3; 1923 return -3; 1924 case _syscall: 1925 push(0, &pushed, push_order, "readstring (rax)"); 1926 if (tree->args[1].type != comma) { 1927 push(syscall_arg[0], &pushed, push_order, "readstring (syscall_arg 0)"); 1928 compile_tree(output, &tree->args->args[0], 0, syscall_arg[0]); 1929 i = 1; 1930 } else { 1931 for (i = 0; i < tree->args[1].args_count; i++) { 1932 push(syscall_arg[i], &pushed, push_order, "readstring (syscall_arg loop)"); 1933 compile_tree(output, &tree->args[1].args[i], 0, syscall_arg[i]); 1934 } 1935 } 1936 1937 compile_tree(output, tree->args, 0, 0); 1938 1939 machine_code[mc_ptr++] = 0x0f; 1940 machine_code[mc_ptr++] = 0x05; 1941 for (j = 0; j < i; j++) 1942 used_regs &= ~(1 << syscall_arg[j]); 1943 reg = 0; 1944 break; 1945 case readstring: 1946 push(0, &pushed, push_order, "readstring (rax)"); 1947 push(syscall_arg[0], &pushed, push_order, "readstring (syscall_arg 0)"); 1948 push(syscall_arg[1], &pushed, push_order, "readstring (syscall_arg 1)"); 1949 push(syscall_arg[2], &pushed, push_order, "readstring (syscall_arg 2)"); 1950 compile_tree(output, &tree->args->args[0], 0, syscall_arg[0]); 1951 compile_tree(output, &tree->args->args[1], 0, syscall_arg[1]); 1952 compile_tree(output, &tree->args->args[2], 0, syscall_arg[2]); 1953 1954 compile_tree(output, ZERO, 0, 0); 1955 /* 1956 machine_code[mc_ptr++] = 0x48; 1957 machine_code[mc_ptr++] = 0xb8; 1958 *(int64_t *) &machine_code[mc_ptr] = 0x00; 1959 mc_ptr += 8; 1960 */ 1961 1962 machine_code[mc_ptr++] = 0x0f; 1963 machine_code[mc_ptr++] = 0x05; 1964 used_regs &= ~(1 << syscall_arg[0]); 1965 used_regs &= ~(1 << syscall_arg[1]); 1966 used_regs &= ~(1 << syscall_arg[2]); 1967 reg = 0; 1968 break; 1969 case writestring: 1970 push(0, &pushed, push_order, "writestring (rax)"); 1971 push(syscall_arg[0], &pushed, push_order, "writestring (syscall_arg 0)"); 1972 push(syscall_arg[1], &pushed, push_order, "writestring (syscall_arg 1)"); 1973 push(syscall_arg[2], &pushed, push_order, "writestring (syscall_arg 2)"); 1974 compile_tree(output, &tree->args->args[0], 0, syscall_arg[0]); 1975 used_regs |= (1 << syscall_arg[0]); 1976 compile_tree(output, &tree->args->args[1], 0, syscall_arg[1]); 1977 used_regs |= (1 << syscall_arg[1]); 1978 compile_tree(output, &tree->args->args[2], 0, syscall_arg[2]); 1979 used_regs |= (1 << syscall_arg[2]); 1980 1981 compile_tree(output, ONE, 0, 0); 1982 /* 1983 machine_code[mc_ptr++] = 0x48; 1984 machine_code[mc_ptr++] = 0xb8; 1985 *(int64_t *) &machine_code[mc_ptr] = 0x01; 1986 mc_ptr += 8; 1987 */ 1988 1989 machine_code[mc_ptr++] = 0x0f; 1990 machine_code[mc_ptr++] = 0x05; 1991 used_regs &= ~(1 << syscall_arg[0]); 1992 used_regs &= ~(1 << syscall_arg[1]); 1993 used_regs &= ~(1 << syscall_arg[2]); 1994 reg = 0; 1995 break; 1996 case printchar: 1997 push(0, &pushed, push_order, "printchar (rax)"); 1998 push(syscall_arg[0], &pushed, push_order, "printchar (syscall_arg 0)"); 1999 push(syscall_arg[1], &pushed, push_order, "printchar (syscall_arg 1)"); 2000 push(syscall_arg[2], &pushed, push_order, "printchar (syscall_arg 2)"); 2001 2002 j = compile_tree(output, tree->args, 0, syscall_arg[1]); 2003 2004 // Allocate extra space on the stack for the character 2005 // Because of scratch space, this might be unnecessary 2006 machine_code[mc_ptr++] = 0x48; 2007 machine_code[mc_ptr++] = 0x83; 2008 machine_code[mc_ptr++] = 0xec; 2009 machine_code[mc_ptr++] = 0x08; 2010 2011 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 2012 machine_code[mc_ptr++] = 0x89; 2013 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 2014 machine_code[mc_ptr++] = -next_rbp; 2015 2016 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 2017 machine_code[mc_ptr++] = 0x8d; 2018 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 2019 machine_code[mc_ptr++] = -next_rbp; 2020 2021 2022 compile_tree(output, ONE, 0, 0); 2023 /* 2024 machine_code[mc_ptr++] = 0x48; 2025 machine_code[mc_ptr++] = 0xb8; 2026 *(int64_t *) &machine_code[mc_ptr] = 0x01; 2027 mc_ptr += 8; 2028 */ 2029 machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0); 2030 machine_code[mc_ptr++] = 0x89; 2031 machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8); 2032 machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0); 2033 machine_code[mc_ptr++] = 0x89; 2034 machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8); 2035 2036 machine_code[mc_ptr++] = 0x0f; 2037 machine_code[mc_ptr++] = 0x05; 2038 2039 machine_code[mc_ptr++] = 0x48; 2040 machine_code[mc_ptr++] = 0x83; 2041 machine_code[mc_ptr++] = 0xc4; 2042 machine_code[mc_ptr++] = 0x08; 2043 2044 used_regs &= ~(1 << syscall_arg[0]); 2045 used_regs &= ~(1 << syscall_arg[1]); 2046 used_regs &= ~(1 << syscall_arg[2]); 2047 reg = 0; 2048 break; 2049 case brk_sys: 2050 push(0, &pushed, push_order, "brk_sys (rax)"); 2051 push(syscall_arg[0], &pushed, push_order, "brk_sys (syscall_arg 0)"); 2052 j = compile_tree(output, tree->args, 0, syscall_arg[0]); 2053 machine_code[mc_ptr++] = 0xb8; 2054 *(int32_t *) &machine_code[mc_ptr] = 0x0c; 2055 mc_ptr += 4; 2056 machine_code[mc_ptr++] = 0x0f; 2057 machine_code[mc_ptr++] = 0x05; 2058 reg = 0; 2059 break; 2060 case exit_p: 2061 j = compile_tree(output, tree->args, 0, syscall_arg[0]); 2062 machine_code[mc_ptr++] = 0xb8; 2063 *(int32_t *) &machine_code[mc_ptr] = 0x3c; 2064 mc_ptr += 4; 2065 machine_code[mc_ptr++] = 0x0f; 2066 machine_code[mc_ptr++] = 0x05; 2067 return -2; 2068 } 2069 if (!discard_result) { 2070 if (reg < 0) { 2071 fprintf(stderr, "No value in <reg>\n"); 2072 fprintf(stderr, "type: %s\n", exp_str[tree->type]); 2073 exit(1); 2074 } 2075 if (out_reg == reg || out_reg < 0 && !(pushed & (1 << reg))) { 2076 out_reg = reg; 2077 used_regs |= (1 << out_reg); 2078 goto pop_used; 2079 } else if (out_reg < 0) { 2080 k = used_regs; 2081 used_regs |= pushed; 2082 out_reg = get_free_reg(1); 2083 used_regs = k; 2084 used_regs |= (1 << out_reg); 2085 } 2086 if (reg >= registers && out_reg >= registers) { 2087 j = get_free_reg(0); 2088 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 2089 machine_code[mc_ptr++] = 0x8b; 2090 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 2091 machine_code[mc_ptr++] = -regs[reg].rbp; 2092 2093 machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0); 2094 machine_code[mc_ptr++] = 0x89; 2095 machine_code[mc_ptr++] = 0x45 + (j % 8) * 8; 2096 machine_code[mc_ptr++] = -regs[out_reg].rbp; 2097 regs[out_reg].rev++; 2098 } else if (reg >= registers && out_reg < registers) { 2099 machine_code[mc_ptr++] = 0x48 | (out_reg > 7 ? 4 : 0); 2100 machine_code[mc_ptr++] = 0x8b; 2101 machine_code[mc_ptr++] = 0x45 + (out_reg % 8) * 8; 2102 machine_code[mc_ptr++] = -regs[reg].rbp; 2103 reg_hist[out_reg].type = 1; 2104 reg_hist[out_reg].reg = reg; 2105 reg_hist[out_reg].rev = ++regs[reg].rev; 2106 } else { 2107 machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0); 2108 machine_code[mc_ptr++] = 0x89; 2109 if (out_reg >= registers) { 2110 machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8; 2111 machine_code[mc_ptr++] = -regs[out_reg].rbp; 2112 reg_hist[reg].type |= 1; 2113 reg_hist[reg].reg = reg; 2114 reg_hist[reg].rev = ++regs[out_reg].rev; 2115 } else { 2116 machine_code[mc_ptr-2] |= (out_reg > 7 ? 1 : 0); 2117 machine_code[mc_ptr++] = 0xc0 + (out_reg % 8) + (reg % 8) * 8; 2118 memcpy(®_hist[out_reg], ®_hist[reg], sizeof(struct reg_history)); 2119 used_regs |= (1 << out_reg); 2120 } 2121 used_regs &= ~(1 << reg); 2122 } 2123 } 2124 pop_used: 2125 if (pushed) 2126 for (i = registers-1; i >= 0; i--) { 2127 if (push_order[i] >= 0) pop(push_order[i], &pushed); 2128 } 2129 end: 2130 return out_reg; 2131 } 2132 2133 struct elf_hdr { 2134 unsigned int magic; 2135 unsigned char class; 2136 unsigned char endianness; 2137 unsigned char version; 2138 unsigned char abi; 2139 unsigned char abi_version; 2140 unsigned char pad[7]; 2141 unsigned short type; 2142 unsigned short arch; 2143 unsigned int version2; 2144 unsigned long entry; 2145 unsigned long phoff; 2146 unsigned long shoff; 2147 unsigned int flags; 2148 unsigned short ehsize; 2149 unsigned short phsize; 2150 unsigned short phcount; 2151 unsigned short shsize; 2152 unsigned short shcount; 2153 unsigned short shstrindx; 2154 } __attribute((packed)); 2155 2156 struct prg_hdr { 2157 unsigned int type; 2158 unsigned int flags; 2159 unsigned long offset; 2160 unsigned long vaddr; 2161 unsigned long paddr; 2162 unsigned long fsize; 2163 unsigned long msize; 2164 unsigned long align; 2165 } __attribute((packed)); 2166 2167 struct sec_hdr { 2168 unsigned int name; 2169 unsigned int type; 2170 unsigned long flags; 2171 unsigned long addr; 2172 unsigned long offset; 2173 unsigned long size; 2174 unsigned int link; 2175 unsigned int info; 2176 unsigned long align; 2177 unsigned long esize; 2178 } __attribute((packed)); 2179 2180 struct elf_hdr elf_hdr = { 0x464c457f, 2, 1, 1, 0, 0, { 0 }, 2, 0x3e, 1, 0, 0x40, 0, 0, 0x40, 0x38, 0, 0x40, 0, 0 }; 2181 struct prg_hdr load_text = { 1, 5, 0, 0, 0, 0, 0, 1 }; 2182 struct prg_hdr load_rodata = { 1, 4, 0, 0, 0, 0, 0, 1 }; 2183 struct sec_hdr null_section = { 0 }; 2184 struct sec_hdr text_section = { 1, 1, 6, 0, 0, 0, 0, 0, 1, 0 }; 2185 struct sec_hdr rodata_section = { 7, 1, 2, 0, 0, 0, 0, 0, 1, 0 }; 2186 struct sec_hdr strtab_section = { 15, 3, 0, 0, 0, 0, 0, 0, 1, 0 }; 2187 char strtab[] = "\0.text\0.rodata\0.strtab"; 2188 2189 char padding[4096] = { 0 }; 2190 2191 int main(int argc, char **argv) 2192 { 2193 int failed = 0, i, outfd, use_rodata = 1, flag_s = 0, first_arg = 1; 2194 2195 if (argc > 1 && argv[1][0] == '-' && argv[1][1]) { 2196 switch (argv[1][1]) { 2197 case 's': 2198 flag_s = 1; 2199 break; 2200 } 2201 argc--; 2202 first_arg = 2; 2203 } 2204 if (argc == 1) { 2205 fname = "stdin"; 2206 outfd = 1; 2207 } else if (argc < 3) { 2208 fprintf(stderr, "Too few arguments\nUsage: %s <in-file> <out-file>\n", *argv); 2209 exit(1); 2210 } else { 2211 if (argv[first_arg][0] == '-' && !argv[first_arg][1]) { 2212 fname = "stdin"; 2213 yyin = stdin; 2214 } else { 2215 fname = argv[first_arg]; 2216 yyin = fopen(fname, "r"); 2217 } 2218 outfd = open(argv[first_arg + 1], O_TRUNC | O_WRONLY | O_CREAT, 2219 (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | 2220 S_IXGRP | S_IROTH | S_IXOTH) & 0x1ff); 2221 if (outfd == -1) { 2222 fprintf(stderr, "Unable to open out-file\n"); 2223 exit(1); 2224 } 2225 } 2226 2227 yyparse(); 2228 2229 if (flag_s) stringify(final, -3, 0, NULL, 0); 2230 2231 if (use_rodata) elf_hdr.phcount = 2; 2232 else elf_hdr.phcount = 1; 2233 if (use_rodata) elf_hdr.shcount = 4; 2234 else elf_hdr.shcount = 3; 2235 elf_hdr.shstrindx = elf_hdr.shcount - 1; 2236 2237 int hdr1_size = sizeof(elf_hdr) + sizeof(struct prg_hdr) * elf_hdr.phcount; 2238 start_addr = 0x400000 + hdr1_size; 2239 rodata_addr = 0x600000; 2240 2241 for (i = 0; i < final->args_count; i++) { 2242 compile_tree(stdout, &final->args[i], 1, -1); 2243 } 2244 for (i = 0; i < ftemp_len; i++) { 2245 if (ftemp[i].fptr) { 2246 fprintf(stderr, "No definition for function <%s> found\n", ftemp[i].fname); 2247 2248 } 2249 } 2250 if (failed) exit(1); 2251 if (entry_addr < 0) { 2252 fprintf(stderr, "No _start symbol found!\n"); 2253 exit(1); 2254 } 2255 2256 int section_pad = 16 - ((hdr1_size + mc_ptr) % 16); 2257 int rodata_offset = sizeof(elf_hdr) + sizeof(load_text) + sizeof(load_rodata) 2258 + mc_ptr + section_pad + sizeof(null_section) + sizeof(text_section) 2259 + sizeof(rodata_section) + sizeof(strtab_section) 2260 + sizeof(strtab); 2261 int rodata_pad_len = 4096 - (rodata_offset % 4096); 2262 rodata_offset += rodata_pad_len; 2263 2264 elf_hdr.entry = start_addr + entry_addr; 2265 elf_hdr.shoff = hdr1_size + mc_ptr + section_pad; 2266 2267 load_text.offset = 0; 2268 load_text.vaddr = 0x400000; 2269 load_text.paddr = 0x400000; 2270 load_text.fsize = hdr1_size + mc_ptr; 2271 load_text.msize = hdr1_size + mc_ptr; 2272 2273 load_rodata.offset = rodata_offset; 2274 load_rodata.vaddr = 0x600000; 2275 load_rodata.paddr = 0x600000; 2276 load_rodata.fsize = rd_ptr; 2277 load_rodata.msize = rd_ptr; 2278 2279 text_section.addr = start_addr; 2280 text_section.offset = hdr1_size; 2281 text_section.size = mc_ptr; 2282 2283 rodata_section.addr = load_rodata.vaddr; 2284 rodata_section.offset = load_rodata.offset; 2285 rodata_section.size = load_rodata.fsize; 2286 2287 strtab_section.offset = hdr1_size + mc_ptr + section_pad + sizeof(struct sec_hdr) * elf_hdr.shcount; 2288 strtab_section.size = sizeof(strtab); 2289 2290 write(outfd, &elf_hdr, sizeof(elf_hdr)); 2291 write(outfd, &load_text, sizeof(load_text)); 2292 if (use_rodata) write(outfd, &load_rodata, sizeof(load_rodata)); 2293 write(outfd, machine_code, mc_ptr); 2294 write(outfd, padding, section_pad); 2295 write(outfd, &null_section, sizeof(null_section)); 2296 write(outfd, &text_section, sizeof(text_section)); 2297 if (use_rodata) write(outfd, &rodata_section, sizeof(rodata_section)); 2298 write(outfd, &strtab_section, sizeof(strtab_section)); 2299 write(outfd, strtab, sizeof(strtab)); 2300 if (use_rodata) write(outfd, padding, rodata_pad_len); 2301 if (use_rodata) write(outfd, rodata, rd_ptr); 2302 }