commit 4f394f9ac8ea9732fd67d8a360a52ad1c229075a
parent 56b3154a739b979d92f86334d9785296ac252c6e
Author: William Djupström <william@deepztream.com>
Date: Mon, 4 Mar 2019 00:24:09 +0000
Currently broken, whatever
Diffstat:
| M | parse.y | | | 815 | ++++++++++++++++++++++++------------------------------------------------------- |
1 file changed, 243 insertions(+), 572 deletions(-)
diff --git a/parse.y b/parse.y
@@ -93,6 +93,7 @@ struct expression *find_idnt(char *name)
}
struct expression *ZERO = &(struct expression){ .type = number, .constant = 1 };
+struct expression *ONE = &(struct expression){ .type = number, .constant = 1, .i = 1 };
struct expression *final;
struct expression *e(enum e_type type, struct expression *arg1, struct expression *arg2, int nofree)
@@ -342,16 +343,16 @@ expression: IDENTIFIER {$$ = copy(find_idnt($1));}
| expression "<<" expression {$$ = e(shift_l, $1, $3, 0);}
| expression ">>" expression {$$ = e(shift_r, $1, $3, 0);}
| expression '=' expression {$$ = e(set, $1, $3, 0);}
-| expression "+=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "-=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "*=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "/=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "%=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "&=" expression {printf("uh-oh\n");$$ = NULL;}
+| expression "+=" expression {$$ = e(set, $1, e(add, $1, $3, 0), 0);}
+| expression "-=" expression {$$ = e(set, $1, e(add, $1, e(neg, $3, NULL, 0), 0), 0);}
+| expression "*=" expression {$$ = e(set, $1, e(mul, $1, $3, 0), 0);}
+| expression "/=" expression {$$ = e(set, $1, e(divide, $1, $3, 0), 0);}
+| expression "%=" expression {$$ = e(set, $1, e(mod, $1, $3, 0), 0);}
+| expression "&=" expression {$$ = e(set, $1, e(b_and, $1, $3, 0), 0);}
| expression "|=" expression {printf("uh-oh\n");$$ = NULL;}
| expression "^=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "<<=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression ">>=" expression {printf("uh-oh\n");$$ = NULL;}
+| expression "<<=" expression {$$ = e(set, $1, e(shift_l, $1, $3, 0), 0);}
+| expression ">>=" expression {$$ = e(set, $1, e(shift_r, $1, $3, 0), 0);}
| expression "==" expression {$$ = e(l_eq, $1, $3, 0);}
| expression "!=" expression {$$ = e(l_not, e(l_eq, $1, $3, 0), NULL, 0);}
| expression '<' expression {$$ = e(l_lt, $1, $3, 0);}
@@ -364,8 +365,8 @@ expression: IDENTIFIER {$$ = copy(find_idnt($1));}
| '&' expression %prec REF {$$ = e(ref, $2, NULL, 0);}
| '-' expression %prec NEG {$$ = e(neg, $2, NULL, 0);}
| '+' expression %prec NEG {printf("uh-oh\n");$$ = NULL;}
-| "++" expression {printf("uh-oh\n");$$ = NULL;}
-| "--" expression {printf("uh-oh\n");$$ = NULL;}
+| "++" expression {$$ = e(set, $2, e(add, $2, ONE, 0), 0);}
+| "--" expression {$$ = e(set, $2, e(add, $2, e(neg, ONE, NULL, 0), 0), 0);}
| expression "++" {printf("uh-oh\n");$$ = NULL;}
| expression "--" {printf("uh-oh\n");$$ = NULL;}
;
@@ -418,8 +419,20 @@ struct storage {
int type;
char *var;
char rbp;
+ int rev;
};
+struct reg_history {
+ /* 0 - undefined
+ * 1 - variable
+ * 2 - constant */
+ int type;
+ int reg;
+ int val;
+ int rev;
+};
+
struct storage regs[1024];
+struct reg_history reg_hist[16];
const int registers = 16;
int next_reg;
uint16_t used_regs;
@@ -451,7 +464,7 @@ int get_free_reg(int mark_used)
exit(1);
}
-void push(int reg, int *pushed, char *order) {
+void push(int reg, int *pushed, char *order, char *from) {
int i;
if (used_regs & (1 << reg)) {
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
@@ -480,6 +493,7 @@ void pop(int reg, int *pushed) {
*pushed &= ~(1 << reg);
used_regs |= (1 << reg);
next_rbp -= 8;
+ reg_hist[reg].type = 0;
}
int compile_tree(FILE *output, struct expression *tree, int discard_result, int out_reg)
@@ -491,7 +505,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
-1, -1, -1, -1 };
int pushed = 0;
struct expression *tmp;
- fprintf(stderr, "Type: %s\n", exp_str[tree->type]);
+ //fprintf(stderr, "Type: %s\n", exp_str[tree->type]);
switch (tree->type) {
case function:
next_reg = registers;
@@ -499,6 +513,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
next_rbp = 8;
tree->i = mc_ptr;
find_idnt(tree->args->str)->i = mc_ptr + start_addr;
+ memset(reg_hist, 0, sizeof(reg_hist));
if (!strcmp(tree->args->str, "_start")) {
entry_addr = mc_ptr;
machine_code[mc_ptr++] = 0x55;
@@ -532,7 +547,6 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
}
func_declares = tree->declares;
- used_regs |= (1 << 5);
machine_code[mc_ptr++] = 0x55;
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x89;
@@ -547,16 +561,22 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
if (tree->args[1].type == idnt && tree->args[1].id_type == parameter) {
- machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + 8*arg_order[0];
+ machine_code[mc_ptr++] = 0x45 + (arg_order[0] % 8) * 8;
machine_code[mc_ptr++] = -regs[registers].rbp;
+ reg_hist[arg_order[0]].type = 1;
+ reg_hist[arg_order[0]].reg = registers;
+ reg_hist[arg_order[0]].rev = ++regs[registers].rev;
} else if (tree->args[1].type == comma && tree->args[1].args->type == idnt && tree->args[1].args->id_type == parameter) {
for (i = 0; i < tree->args[1].args_count; i++) {
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x89;
machine_code[mc_ptr++] = 0x45 + 8*arg_order[i];
machine_code[mc_ptr++] = -regs[registers + i].rbp;
+ reg_hist[arg_order[i]].type = 1;
+ reg_hist[arg_order[i]].reg = registers + i;
+ reg_hist[arg_order[i]].rev = ++regs[registers + i].rev;
}
}
}
@@ -576,13 +596,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
case fcall:
for (i = 0; i < registers; i++) {
if (caller_save & (1 << i)) {
- push(i, &pushed, push_order);
- /*
- machine_code[mc_ptr++] = 0x48 | (i > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (i % 8);
- next_rbp += 8;
- pushed |= (1 << i);
- */
+ push(i, &pushed, push_order, "fcall (caller_save)");
}
}
if (tree->args_count == 2) {
@@ -594,109 +608,119 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
j = compile_tree(output, &tree->args[1], 0, arg_order[0]);
}
}
- if (!(pushed & 1)) {
- used_regs |= 1;
- }
j = find_idnt(tree->args->str)->i;
machine_code[mc_ptr++] = 0xe8;
*(int32_t *) &machine_code[mc_ptr] = j - start_addr - mc_ptr - 4;
mc_ptr += 4;
+ if (tree->args[1].type == comma)
+ for (i = 0; i < tree->args[1].args_count; i++)
+ used_regs &= ~(1 << arg_order[i]);
+ else
+ used_regs &= ~(1 << arg_order[0]);
+
+ memset(reg_hist, 0, sizeof(reg_hist));
if (!discard_result) {
- if (pushed & 1 && (out_reg < 0 || out_reg >= registers)) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
-
- } else if (out_reg >= 0 && out_reg < registers){
- reg = out_reg;
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xC0 + (reg % 8);
- }
- }
- for (i = registers - 1; i >= 0; i--) {
- if (pushed & (1 << i)) {
- machine_code[mc_ptr++] = 0x48 | (i > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (i % 8);
- next_rbp -= 8;
- pushed &= ~(1 << i);
- } else {
- if (i != reg) used_regs &= ~(1 << i);
- }
+ reg = 0;
+ used_regs |= !(pushed & 1);
}
break;
case add:
- j = compile_tree(output, tree->args, discard_result, get_free_reg(1));
- k = compile_tree(output, &tree->args[1], discard_result, get_free_reg(1));
+ j = compile_tree(output, tree->args, discard_result, -1);
+ k = compile_tree(output, &tree->args[1], discard_result, -1);
if (discard_result) {
if (j >= 0 && j < registers) used_regs &= ~(1 << j);
if (k >= 0 && k < registers) used_regs &= ~(1 << k);
break;
}
- reg = j;
- /*
- if (reg >= registers) {
- reg = get_free_reg(1);
- }
- if (j >= registers) {
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- }
- */
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x03;
- /*
- if (tree->args[1].type == idnt) {
- machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
- machine_code[mc_ptr++] = -regs[k].rbp;
+ if (out_reg < 0 || out_reg != j && out_reg != k) {
+ if (k >= registers) {
+ if (j >= registers) {
+ reg = out_reg;
+ if (out_reg < 0 || out_reg >= registers)
+ reg = get_free_reg(1);
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ j = reg;
+ }
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x03;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+ reg = j, l = k;
+ } else if (j >= registers) {
+ machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x03;
+ machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ reg = k, l = j;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x03;
+ machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + k;
+ reg = j, l = k;
+ }
} else {
- */
- machine_code[mc_ptr-2] |= k > 7 ? 1 : 0;
- machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + k;
- //}
- if (k >= 0 && k < registers) used_regs &= ~(1 << k);
+ if (out_reg == k) {
+ l = j;
+ j = k;
+ k = l;
+ }
+ if (j >= registers) {
+ if (k >= registers) {
+ reg = get_free_reg(1);
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+ k = reg;
+ }
+ machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x01;
+ machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ } else if (k >= registers) {
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x03;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (k > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x03;
+ machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + k;
+ if (reg_hist[j].type & 2 && reg_hist[k].type & 2) {
+ reg_hist[j].type = 2;
+ reg_hist[j].val += reg_hist[k].val;
+ } else if (reg_hist[j].type & 2) {
+ reg_hist[j].type = 0;
+ }
+ }
+ reg = j, l = k;
+ }
+ if (l < registers) used_regs &= ~(1 << l);
break;
case neg:
- j = compile_tree(output, tree->args, discard_result, out_reg);
+ j = compile_tree(output, tree->args, discard_result, (out_reg >= 0 ? out_reg : get_free_reg(1)));
if (discard_result) {
if (j < registers) used_regs &= ~(1 << j);
break;
}
reg = j;
- if (j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ if (reg >= registers) {
machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + reg*8;
- machine_code[mc_ptr++] = -regs[j].rbp;
+ machine_code[mc_ptr++] = 0xf7;
+ machine_code[mc_ptr++] = 0x5d;
+ machine_code[mc_ptr++] = -regs[reg].rbp;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0xf7;
+ machine_code[mc_ptr++] = 0xd8 + (reg % 8);
}
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0xf7;
- machine_code[mc_ptr++] = 0xd8 + (reg % 8);
break;
case mul:
- j = compile_tree(output, tree->args, discard_result, out_reg);
+ j = compile_tree(output, tree->args, discard_result, -1);
k = compile_tree(output, &tree->args[1], discard_result, -1);
if (discard_result) {
if (j < registers) used_regs &= ~(1 << j);
@@ -705,17 +729,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if ((out_reg == -1 || out_reg >= registers) && j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
if (j >= registers) {
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
@@ -728,17 +742,17 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
}
- machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x0F;
machine_code[mc_ptr++] = 0xAF;
if (k >= registers) {
- machine_code[mc_ptr++] = 0x45 + reg*8;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
machine_code[mc_ptr++] = -regs[k].rbp;
} else {
- machine_code[mc_ptr++] = 0xC0 + reg*8 + k;
+ machine_code[mc_ptr-3] |= (k > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + (k % 8);
+ used_regs &= ~(1 << k);
}
- //used_regs &= ~(1 << j);
- used_regs &= ~(1 << k);
break;
case divide:
if (discard_result) {
@@ -747,38 +761,17 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (j < registers) used_regs &= ~(1 << j);
break;
}
- used_regs |= 1 | 4;
- j = compile_tree(output, tree->args, 0, -1);
- used_regs &= ~(1 | 4);
- if (j != 0) {
- if (used_regs & 1) {
- fprintf(stderr, "Not implemented yet! (rax)\n");
- exit(1);
- } else {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x8b;
- if (j >= registers) {
- machine_code[mc_ptr++] = 0x45 + (0 % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- machine_code[mc_ptr-2] |= (j > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0xc0 + (j % 8);
- }
- used_regs |= (1 << 0);
- }
- used_regs &= ~(1 << j);
- }
- if (used_regs & 4) {
- fprintf(stderr, "Not implemented yet! (rdx)\n");
- }
- used_regs |= 1 << 2;
+ push(0, &pushed, push_order, "divide (rax)");
+ push(2, &pushed, push_order, "divide (rdx)");
+ j = compile_tree(output, tree->args, 0, 0);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x99;
+ used_regs |= (1 << 0) | (1 << 2);
k = compile_tree(output, &tree->args[1], 0, -1);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0xF7;
- if (tree->args[1].type == idnt) {
+ if (k >= registers) {
machine_code[mc_ptr++] = 0x7d;
machine_code[mc_ptr++] = -regs[k].rbp;
} else {
@@ -795,32 +788,9 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (j < registers) used_regs &= ~(1 << j);
break;
}
- used_regs |= 1 | 4;
- j = compile_tree(output, tree->args, 0, -1);
- used_regs &= ~(1 | 4);
- if (j != 0) {
- if (used_regs & 1) {
- fprintf(stderr, "Not implemented yet! (rax)\n");
- exit(1);
- } else {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x8b;
- if (j >= registers) {
- machine_code[mc_ptr++] = 0x45 + (0 % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- machine_code[mc_ptr-2] |= (j > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0xc0 + (j % 8);
- }
- used_regs |= (1 << 0);
- }
- used_regs &= ~(1 << j);
- }
- if (used_regs & 4) {
- fprintf(stderr, "Not implemented yet! (rdx)\n");
- }
- used_regs |= 1 << 0;
- used_regs |= 1 << 2;
+ push(0, &pushed, push_order, "mod (rax)");
+ push(2, &pushed, push_order, "mod (rdx)");
+ j = compile_tree(output, tree->args, 0, 0);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x99;
@@ -866,17 +836,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + reg*8;
@@ -917,17 +877,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + reg*8;
@@ -949,17 +899,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
@@ -986,42 +926,6 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
case set:
reg = compile_tree(output, tree->args, 0, -1);
j = compile_tree(output, &tree->args[1], 0, reg);
- /*
- if (j < 0) {
- fprintf(stderr, "No rvalue for assignment\n");
- exit(1);
- }
- used_regs &= ~(1 << j);
- if (j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- k = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- k = j;
- }
- if (reg >= registers) {
- machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
- machine_code[mc_ptr++] = -regs[reg].rbp;
- } else if (tree->args->type == deref) {
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x00 + (reg % 8) + (k % 8) * 8;
- }
- if (discard_result) reg = -1;
- */
break;
case ref:
if (tree->args->type != idnt) {
@@ -1031,18 +935,8 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (discard_result) break;
j = compile_tree(output, tree->args, 0, -1);
reg = out_reg;
- if (out_reg < 0 || out_reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- k = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- }
+ if (out_reg < 0 || out_reg >= registers)
+ reg = get_free_reg(1);
used_regs |= (1 << reg);
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8d;
@@ -1057,17 +951,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- used_regs |= (1 << reg);
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
@@ -1087,63 +971,46 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
fprintf(stderr, "Unable to locate identifier <%s>\n", tree->str);
exit(1);
}
- /*
- if (out_reg != -1 && out_reg < registers) {
- reg = out_reg;
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
- machine_code[mc_ptr++] = -regs[i].rbp;
- used_regs |= (1 << reg);
- } else {
- reg = i;
+ for (i = 0; i < registers; i++) {
+ if (reg_hist[i].type & 1 && reg_hist[i].reg == reg && reg_hist[i].rev == regs[reg].rev) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
}
- */
break;
case number:
if (discard_result) break;
- if (out_reg == -1 || out_reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
+ for (i = 0; i < registers; i++) {
+ if (reg_hist[i].type & 2 && reg_hist[i].val == tree->i) {
+ reg = i;
+ break;
}
- } else {
+ }
+ if (reg < 0) {
reg = out_reg;
+ if (reg == -1 || reg >= registers)
+ reg = get_free_reg(0);
+ if (tree->i) {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0xb8 + (reg % 8);
+ *(int64_t *) &machine_code[mc_ptr] = tree->i;
+ mc_ptr += 8;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0);
+ machine_code[mc_ptr++] = 0x33;
+ machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8;
+ }
+ reg_hist[reg].type = 2;
+ reg_hist[reg].val = tree->i;
}
used_regs |= (1 << reg);
- if (tree->i) {
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0xb8 + (reg % 8);
- *(int64_t *) &machine_code[mc_ptr] = tree->i;
- mc_ptr += 8;
- } else {
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0);
- machine_code[mc_ptr++] = 0x33;
- machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8;
- }
break;
case string:
if (discard_result) break;
- if (out_reg == -1 || out_reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- } else {
- reg = out_reg;
- }
+ reg = out_reg;
+ if (reg == -1 || reg >= registers)
+ reg = get_free_reg(0);
if (!tree->i) {
strcpy(&rodata[rd_ptr], tree->str);
tree->i = rodata_addr + rd_ptr;
@@ -1156,6 +1023,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
used_regs |= (1 << reg);
break;
case loop:
+ memset(reg_hist, 0, sizeof(reg_hist));
machine_code[mc_ptr++] = 0xe9;
k = mc_ptr;
mc_ptr += 4;
@@ -1221,17 +1089,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x83;
machine_code[mc_ptr++] = 0x7d;
@@ -1258,7 +1116,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
break;
case l_eq:
j = compile_tree(output, tree->args, discard_result, -1);
- k = compile_tree(output, &tree->args[1], discard_result, out_reg);
+ k = compile_tree(output, &tree->args[1], discard_result, -1);
if (discard_result) {
if (j < registers) used_regs &= ~(1 << j);
if (k < registers) used_regs &= ~(1 << k);
@@ -1268,17 +1126,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (j >= registers) {
if (k >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
@@ -1290,26 +1138,10 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
machine_code[mc_ptr++] = -regs[j].rbp;
} else if (k >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x3b;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
machine_code[mc_ptr++] = -regs[k].rbp;
-
- k = reg;
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x39;
- machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8;
} else {
machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x39;
@@ -1331,67 +1163,44 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
mc_ptr += 8;
break;
case l_lt:
- j = compile_tree(output, tree->args, discard_result, out_reg);
+ j = compile_tree(output, tree->args, discard_result, -1);
k = compile_tree(output, &tree->args[1], discard_result, -1);
if (discard_result) {
if (j < registers) used_regs &= ~(1 << j);
if (k < registers) used_regs &= ~(1 << k);
break;
}
- reg = k;
+ reg = j;
if (j >= registers) {
+ reg = k;
if (k >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
machine_code[mc_ptr++] = -regs[k].rbp;
- } else {
- //reg = k;
+ k = reg;
}
- k = reg;
machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x39;
machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
machine_code[mc_ptr++] = -regs[j].rbp;
} else if (k >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x3b;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
machine_code[mc_ptr++] = -regs[k].rbp;
-
- k = reg;
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x39;
- machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8;
} else {
machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x39;
machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8;
used_regs &= ~(1 << k);
}
+ if (reg != out_reg && out_reg >= 0) {
+ used_regs &= ~(1 << reg);
+ reg = out_reg;
+ }
machine_code[mc_ptr++] = 0x7c;
machine_code[mc_ptr++] = 0x05; //Offset
// Not less than:
@@ -1407,31 +1216,18 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
mc_ptr += 8;
break;
case ret:
- reg = compile_tree(output, tree->args, 0, 0);
- if (reg) {
- if (reg >= registers) {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45;
- machine_code[mc_ptr++] = -regs[reg].rbp;
- } else {
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0xC0 + (reg % 8);
- }
- }
+ compile_tree(output, tree->args, 0, 0);
machine_code[mc_ptr++] = 0xc9;
machine_code[mc_ptr++] = 0xc3;
return -3;
case writestring:
- push(syscall_arg[2], &pushed, push_order);
- compile_tree(output, tree->args, 0, syscall_arg[2]);
-
- push(syscall_arg[1], &pushed, push_order);
+ push(0, &pushed, push_order, "writestring (rax)");
+ push(syscall_arg[0], &pushed, push_order, "writestring (syscall_arg 0)");
+ push(syscall_arg[1], &pushed, push_order, "writestring (syscall_arg 1)");
+ push(syscall_arg[2], &pushed, push_order, "writestring (syscall_arg 2)");
compile_tree(output, &tree->args[1], 0, syscall_arg[1]);
+ compile_tree(output, tree->args, 0, syscall_arg[2]);
- push(syscall_arg[0], &pushed, push_order);
- push(0, &pushed, push_order);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0xb8;
*(int64_t *) &machine_code[mc_ptr] = 0x01;
@@ -1440,124 +1236,18 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x48 | (syscall_arg[0] > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x89;
machine_code[mc_ptr++] = 0xc0 + (syscall_arg[0] % 8);
- /*
- if (used_regs & (1 << 0)) {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x50;
- next_rbp += 8;
- pushed |= (1 << 0);
- }
- for (int i = 0; i <= 2; i++) {
- if (used_regs & (1 << arg_order[i])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[i] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[i]);
- }
- }
- */
-
- //used_regs |= (1 << 0) | (1 << syscall_arg[0]);
machine_code[mc_ptr++] = 0x0F;
machine_code[mc_ptr++] = 0x05;
reg = 0;
-
- // Reset saved variables
- /*
- for (i = 2; i >= 0; i--) {
- if (pushed & (1 << arg_order[i])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[i] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[i]);
- } else {
- used_regs &= ~(1 << arg_order[i]);
- }
- }
- if (pushed & (1 << 0)) {
- if (!discard_result) {
- reg = out_reg;
- if (reg < 0 || reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- }
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0xc0 + (reg % 8) * 8;
- }
-
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x58;
- next_rbp -= 8;
- pushed &= ~(1 << 0);
- } else {
- if (discard_result) used_regs &= ~(1 << 0);
- }
- */
break;
case printchar:
- push(arg_order[1], &pushed, push_order);
- j = compile_tree(output, tree->args, 0, syscall_arg[1]);
- /*
- if (used_regs & (1 << arg_order[1]) && j != arg_order[1]) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[1] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[1]);
- }
- if (j >= registers) {
- k = 0;
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8d;
- machine_code[mc_ptr++] = 0x45 + (arg_order[1] % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- k = 1;
-
- // Allocate extra space on the stack for the character
- // Because of scratch space, this might be unnecessary
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x81;
- machine_code[mc_ptr++] = 0xEC;
- *(int *) &machine_code[mc_ptr] = 0x08;
- mc_ptr += 4;
+ push(0, &pushed, push_order, "printchar (rax)");
+ push(syscall_arg[0], &pushed, push_order, "printchar (syscall_arg 0)");
+ push(syscall_arg[1], &pushed, push_order, "printchar (syscall_arg 1)");
+ push(syscall_arg[2], &pushed, push_order, "printchar (syscall_arg 2)");
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
- machine_code[mc_ptr++] = -next_rbp;
-
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8d;
- machine_code[mc_ptr++] = 0x45 + (arg_order[1] % 8) * 8;
- machine_code[mc_ptr++] = -next_rbp;
- used_regs &= ~(1 << j);
- }
- */
- push(0, &pushed, push_order);
- push(syscall_arg[0], &pushed, push_order);
- push(syscall_arg[2], &pushed, push_order);
-
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0xb8;
- *(int64_t *) &machine_code[mc_ptr] = 0x01;
- mc_ptr += 8;
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8);
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8);
+ j = compile_tree(output, tree->args, 0, syscall_arg[1]);
// Allocate extra space on the stack for the character
// Because of scratch space, this might be unnecessary
@@ -1575,8 +1265,18 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x8d;
machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
machine_code[mc_ptr++] = -next_rbp;
- used_regs &= ~(1 << j);
-
+
+ machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0xb8;
+ *(int64_t *) &machine_code[mc_ptr] = 0x01;
+ mc_ptr += 8;
+ machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8);
+ machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8);
+
machine_code[mc_ptr++] = 0x0f;
machine_code[mc_ptr++] = 0x05;
@@ -1584,57 +1284,6 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x83;
machine_code[mc_ptr++] = 0xc4;
machine_code[mc_ptr++] = 0x08;
- // Reset saved variables
- /*
- if (pushed & (1 << arg_order[1])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[1] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[1]);
- } else {
- used_regs &= ~(1 << arg_order[1]);
- }
- if (pushed & (1 << arg_order[2])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[2] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[2]);
- } else {
- used_regs &= ~(1 << arg_order[2]);
- }
- if (pushed & (1 << arg_order[0])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[0] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[0]);
- } else {
- used_regs &= ~(1 << arg_order[0]);
- }
- if (pushed & (1 << 0)) {
- if (!discard_result) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0xc0 + (reg % 8) * 8;
- }
-
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x58;
- next_rbp -= 8;
- pushed &= ~(1 << 0);
- }
- if (discard_result) used_regs &= ~(1 << 0);
- */
reg = 0;
break;
case exit_p:
@@ -1650,10 +1299,19 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (!discard_result) {
if (reg < 0) {
fprintf(stderr, "No value in <reg>\n");
+ fprintf(stderr, "type: %s\n", exp_str[tree->type]);
exit(1);
}
- if (out_reg < 0) return reg;
- if (reg == out_reg) goto end;
+ if (out_reg < 0 && !(pushed & (1 << reg))) {
+ out_reg = reg;
+ goto pop_used;
+ } else if (out_reg < 0) {
+ k = used_regs;
+ used_regs |= pushed;
+ out_reg = get_free_reg(1);
+ used_regs = k;
+ }
+ if (reg == out_reg) goto pop_used;
if (reg >= registers && out_reg >= registers) {
j = get_free_reg(0);
machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
@@ -1665,27 +1323,37 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x89;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
machine_code[mc_ptr++] = -regs[out_reg].rbp;
+ regs[out_reg].rev++;
} else if (reg >= registers && out_reg < registers) {
machine_code[mc_ptr++] = 0x48 | (out_reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (out_reg % 8) * 8;
machine_code[mc_ptr++] = -regs[reg].rbp;
+ reg_hist[out_reg].type = 1;
+ reg_hist[out_reg].reg = reg;
+ reg_hist[out_reg].rev = ++regs[reg].rev;
} else {
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x89;
if (out_reg >= registers) {
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
machine_code[mc_ptr++] = -regs[out_reg].rbp;
+ reg_hist[reg].type |= 1;
+ reg_hist[reg].reg = reg;
+ reg_hist[reg].rev = ++regs[out_reg].rev;
} else {
machine_code[mc_ptr-2] |= (out_reg > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0xc0 + (out_reg % 8) + (reg % 8) * 8;
+ memcpy(®_hist[out_reg], ®_hist[reg], sizeof(struct reg_history));
}
used_regs &= ~(1 << reg);
}
}
+pop_used:
if (pushed)
- for (i = 0; pushed && i < registers; i++)
- pop(push_order[i], &pushed);
+ for (i = registers-1; i >= 0; i--) {
+ if (push_order[i] >= 0) pop(push_order[i], &pushed);
+ }
end:
return out_reg;
}
@@ -1750,9 +1418,12 @@ char padding[4096] = { 0 };
int main(int argc, char **argv)
{
- int i, outfd, use_rodata = 0;
+ int i, outfd, use_rodata = 1;
- if (argc < 3) {
+ if (argc == 1) {
+ fname = "stdin";
+ outfd = 1;
+ } else if (argc < 3) {
fprintf(stderr, "Too few arguments\nUsage: %s <in-file> <out-file>\n", *argv);
exit(1);
} else {
@@ -1767,7 +1438,7 @@ int main(int argc, char **argv)
yyparse();
- stringify(final, -3, 0, NULL, 0);
+ //stringify(final, -3, 0, NULL, 0);
if (use_rodata) elf_hdr.phcount = 2;
else elf_hdr.phcount = 1;