So many bug fixes like omg why didn't u use bp for stacc idiot
This commit is contained in:
parent
13333c971a
commit
d0262c586e
@ -5,6 +5,7 @@
|
||||
#include"scope.h"
|
||||
#include<assert.h>
|
||||
#include<stdlib.h>
|
||||
#include"x86/arch.h"
|
||||
|
||||
struct Spill2StackState {
|
||||
AST *targetTLC;
|
||||
@ -30,7 +31,7 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
|
||||
|
||||
ASTExprStackPointer *rsp = calloc(1, sizeof(*rsp));
|
||||
rsp->nodeKind = AST_EXPR_STACK_POINTER;
|
||||
rsp->type = primitive_parse("u32");
|
||||
rsp->type = type_u(arch_gpr_size());
|
||||
|
||||
ASTExprPrimitive *offset = calloc(1, sizeof(*offset));
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
|
@ -153,6 +153,10 @@ void ast_usedef_reset(AST *chu) {
|
||||
}
|
||||
|
||||
s->statement.dirty = true;
|
||||
|
||||
s->statement.rd.defCount = 0;
|
||||
free(s->statement.rd.defs);
|
||||
s->statement.rd.defs = NULL;
|
||||
}
|
||||
|
||||
for(size_t rdsteps = 0;; rdsteps++) {
|
||||
|
@ -80,6 +80,8 @@ int main(int argc_, char **argv_) {
|
||||
stahp(0, 0, "Failed to read input (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
arch_init();
|
||||
|
||||
Token *tokens = nct_lex(f);
|
||||
|
||||
if(in) fclose(f);
|
||||
|
53
src/parse.c
53
src/parse.c
@ -38,9 +38,6 @@ typedef struct {
|
||||
// Used by pushstat to add statements
|
||||
ASTChunk *currentChunk;
|
||||
|
||||
// Used to place guard variable uses after loops to stop reg allocation from fucking up
|
||||
Scope *loopScope;
|
||||
|
||||
// Used for generating statements that load & store arguments
|
||||
int isInFunction;
|
||||
|
||||
@ -143,36 +140,6 @@ static AST *exprvar(Parser *P, ScopeItem *v) {
|
||||
a->exprVar.type = v->type;
|
||||
a->exprVar.thing = v;
|
||||
|
||||
/*if(P->loopScope) {
|
||||
// XXX: O(n)!!!!!!!!!
|
||||
|
||||
int inloop = 0;
|
||||
for(Scope *vt = v->owner; vt; vt = vt->parent) {
|
||||
if(vt->parent == P->loopScope) {
|
||||
inloop = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!inloop) {
|
||||
int alreadyAdded = 0;
|
||||
for(size_t i = 0; i < P->guardedVarCount; i++) {
|
||||
if(P->guardedVars[i]->thing == v) {
|
||||
alreadyAdded = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!alreadyAdded) {
|
||||
ASTExprVar *ev = alloc_node(P, sizeof(*ev));
|
||||
memcpy(ev, a, sizeof(*ev));
|
||||
|
||||
P->guardedVars = realloc(P->guardedVars, sizeof(*P->guardedVars) * (P->guardedVarCount + 1));
|
||||
P->guardedVars[P->guardedVarCount++] = ev;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -261,7 +228,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
|
||||
ASTExprStackPointer *ret = alloc_node(P, sizeof(*ret));
|
||||
ret->nodeKind = AST_EXPR_STACK_POINTER;
|
||||
ret->type = primitive_parse("u32");
|
||||
ret->type = type_u(arch_sp_size());
|
||||
|
||||
e = (AST*) ret;
|
||||
} else if(!strcmp(peek(P, 0).content, "@salloc")) {
|
||||
@ -288,7 +255,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
ret->ofExpr = nct_parse_expression(P, lOP - 1);
|
||||
}
|
||||
|
||||
ret->type = primitive_parse("u32");
|
||||
ret->type = type_u(arch_gpr_size());
|
||||
|
||||
e = (AST*) ret;
|
||||
} else {
|
||||
@ -494,7 +461,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
if(typesize != 1) {
|
||||
ASTExprPrimitive *scale = alloc_node(P, sizeof(*scale));
|
||||
scale->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
scale->type = primitive_parse("u32");
|
||||
scale->type = type_u(arch_gpr_size());
|
||||
scale->val = typesize;
|
||||
|
||||
ASTExprBinaryOp *mul = alloc_node(P, sizeof(*mul));
|
||||
@ -1135,11 +1102,11 @@ static void nct_parse_statement(Parser *P) {
|
||||
ret->nodeKind = AST_STMT_LOOP;
|
||||
ret->next = NULL;
|
||||
|
||||
int isFirstLoop = P->loopScope == NULL;
|
||||
//int isFirstLoop = P->loopScope == NULL;
|
||||
|
||||
if(isFirstLoop) {
|
||||
P->loopScope = P->scope;
|
||||
}
|
||||
//if(isFirstLoop) {
|
||||
//P->loopScope = P->scope;
|
||||
//}
|
||||
|
||||
expect(P, TOKEN_SQUIGGLY_L);
|
||||
ret->body = (AST*) nct_parse_chunk(P, 0, 1, NULL, NULL);
|
||||
@ -1147,8 +1114,8 @@ static void nct_parse_statement(Parser *P) {
|
||||
|
||||
pushstat(P, ret);
|
||||
|
||||
if(isFirstLoop) {
|
||||
P->loopScope = NULL;
|
||||
//if(isFirstLoop) {
|
||||
//P->loopScope = NULL;
|
||||
|
||||
/*for(size_t i = 0; i < P->guardedVarCount; i++) {
|
||||
ASTExprVar *ev = P->guardedVars[i];
|
||||
@ -1163,7 +1130,7 @@ static void nct_parse_statement(Parser *P) {
|
||||
P->guardedVarCount = 0;
|
||||
free(P->guardedVars);
|
||||
P->guardedVars = NULL;*/
|
||||
}
|
||||
//}
|
||||
|
||||
return;
|
||||
} else if(maybe(P, TOKEN_BREAK)) {
|
||||
|
@ -19,7 +19,6 @@ typedef struct UseDef {
|
||||
struct UseDef *next;
|
||||
} UseDef;
|
||||
|
||||
// Stack, necessary for "possible reaching defs" such as from if statements
|
||||
typedef struct ReachingDefs {
|
||||
size_t defCount;
|
||||
union AST **defs;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include<stdint.h>
|
||||
#include<stdbool.h>
|
||||
#include<string.h>
|
||||
#include<stdio.h>
|
||||
|
||||
typedef enum {
|
||||
TYPE_TYPE_PRIMITIVE, TYPE_TYPE_RECORD, TYPE_TYPE_POINTER, TYPE_TYPE_FUNCTION, TYPE_TYPE_ARRAY, TYPE_TYPE_GENERIC, TYPE_TYPE_ERROR
|
||||
@ -114,4 +115,10 @@ static inline bool type_is_segmented_pointer(Type *type) {
|
||||
return type->type == TYPE_TYPE_RECORD && !!strstr(type->record.name, " @far*");
|
||||
}
|
||||
|
||||
static inline Type *type_u(size_t size) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "u%lu", size);
|
||||
return primitive_parse(buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,9 +27,15 @@ RegisterClass REG_CLASSES[] = {
|
||||
},
|
||||
[REG_CLASS_IA16_PTRS] = {
|
||||
.rMask = HWR_IND | HWR_BX,
|
||||
.rs = {HWR_DI, HWR_SI, HWR_BX, HWR_BP},
|
||||
.rsN = {"di", "si", "bx", "bp"},
|
||||
.rsS = {2, 2, 2, 2},
|
||||
.rs = {HWR_DI, HWR_SI, HWR_BX},
|
||||
.rsN = {"di", "si", "bx"},
|
||||
.rsS = {2, 2, 2},
|
||||
},
|
||||
[REG_CLASS_IA16_USEABLE]= {
|
||||
.rMask = HWR_IND | HWR_GPR,
|
||||
.rs = {HWR_AX, HWR_CX, HWR_DX, HWR_DI, HWR_SI, HWR_BX},
|
||||
.rsN = {"ax", "cx", "dx", "di", "si", "bx"},
|
||||
.rsS = {2, 2, 2, 2, 2, 2},
|
||||
},
|
||||
[REG_CLASS_DATASEGS] = {
|
||||
.rMask = HWR_SEGREGS,
|
||||
@ -50,3 +56,7 @@ bool arch_verify_target() {
|
||||
int arch_ptr_size() {
|
||||
return x86_ia16() ? 2 : 4;
|
||||
}
|
||||
|
||||
void arch_init() {
|
||||
|
||||
}
|
||||
|
107
src/x86/arch.h
107
src/x86/arch.h
@ -60,45 +60,10 @@ typedef struct RegisterClass {
|
||||
#define REG_CLASS_16_32 2
|
||||
#define REG_CLASS_IND 3
|
||||
#define REG_CLASS_IA16_PTRS 4
|
||||
#define REG_CLASS_DATASEGS 5
|
||||
#define REG_CLASS_IA16_USEABLE 5
|
||||
#define REG_CLASS_DATASEGS 6
|
||||
extern RegisterClass REG_CLASSES[];
|
||||
|
||||
// lol
|
||||
static inline bool is_reg_b(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !strcmp(name, "bl") || !strcmp(name, "bh") || !!strstr(name, "bx");
|
||||
}
|
||||
static inline bool is_reg_di(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !!strstr(name, "di");
|
||||
}
|
||||
static inline bool is_reg_si(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !!strstr(name, "si");
|
||||
}
|
||||
static inline void reg_cast_up(int *cls, int *res) {
|
||||
const char *name = REG_CLASSES[*cls].rsN[*res];
|
||||
if(strstr(name, "a")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 1;
|
||||
} else if(strstr(name, "b")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 3;
|
||||
} else if(strstr(name, "c")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 5;
|
||||
} else if(strstr(name, "dl") || strstr(name, "dh") || strstr(name, "dx")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 7;
|
||||
} else if(strstr(name, "di")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 9;
|
||||
} else if(strstr(name, "si")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 11;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
I086 = 0,
|
||||
I186 = 1,
|
||||
@ -151,6 +116,10 @@ static inline bool x86_imul_supported() {
|
||||
return x86_target() >= I186;
|
||||
}
|
||||
|
||||
static inline bool x86_is_marked_ptr(ScopeItem *si) {
|
||||
return si->data.var.preclassed && si->data.var.registerClass == REG_CLASS_IA16_PTRS;
|
||||
}
|
||||
|
||||
// Can expression be expressed as a single x86 operand?
|
||||
#define XOP_NOT_XOP 0
|
||||
#define XOP_NOT_MEM 1
|
||||
@ -176,11 +145,10 @@ static inline int is_xop(AST *e) {
|
||||
}
|
||||
|
||||
if(c->nodeKind == AST_EXPR_VAR && c->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
if(x86_ia16()) { // In IA-16, pointers MUST be preclassed to REG_CLASS_IA16_PTRS
|
||||
if(!c->exprVar.thing->data.var.preclassed || c->exprVar.thing->data.var.registerClass != REG_CLASS_IA16_PTRS) {
|
||||
if(x86_ia16() && !x86_is_marked_ptr(c->exprVar.thing)) {
|
||||
// In IA-16, pointers MUST be preclassed to REG_CLASS_IA16_PTRS
|
||||
return XOP_NOT_XOP;
|
||||
}
|
||||
}
|
||||
|
||||
return XOP_MEM;
|
||||
} else if(
|
||||
@ -190,8 +158,18 @@ static inline int is_xop(AST *e) {
|
||||
if(c->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
return XOP_MEM;
|
||||
} else if(c->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR) {
|
||||
if(x86_ia16() && !x86_is_marked_ptr(c->exprBinOp.operands[1]->exprVar.thing)) {
|
||||
// In IA-16, pointers MUST be preclassed to REG_CLASS_IA16_PTRS
|
||||
return XOP_NOT_XOP;
|
||||
}
|
||||
|
||||
return XOP_MEM;
|
||||
} else if(c->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && c->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && c->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && c->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR) {
|
||||
if(x86_ia16() && !x86_is_marked_ptr(c->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing)) {
|
||||
// In IA-16, pointers MUST be preclassed to REG_CLASS_IA16_PTRS
|
||||
return XOP_NOT_XOP;
|
||||
}
|
||||
|
||||
int scale = c->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val;
|
||||
|
||||
if(scale == 1 || scale == 2 || scale == 4 || scale == 8) {
|
||||
@ -307,3 +285,52 @@ static inline void arch_add_hidden_variables(Scope *scope) {
|
||||
static inline bool x86_is_lea(AST *s) {
|
||||
return !x86_ia16() && s->nodeKind == AST_STMT_ASSIGN && s->stmtAssign.to->nodeKind == AST_EXPR_BINARY_OP && s->stmtAssign.to->exprBinOp.operator == BINOP_ADD && is_xop(s->stmtAssign.what) == XOP_NOT_MEM && is_xop(s->stmtAssign.to->exprBinOp.operands[0]) == XOP_NOT_MEM && is_xop(s->stmtAssign.to->exprBinOp.operands[1]) == XOP_NOT_MEM;
|
||||
}
|
||||
|
||||
static inline int arch_sp_size() {
|
||||
return x86_max_gpr_size();
|
||||
}
|
||||
|
||||
static inline int arch_gpr_size() {
|
||||
return x86_max_gpr_size();
|
||||
}
|
||||
|
||||
// lol
|
||||
static inline bool is_reg_b(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !strcmp(name, "bl") || !strcmp(name, "bh") || !!strstr(name, "bx");
|
||||
}
|
||||
static inline bool is_reg_di(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !!strstr(name, "di");
|
||||
}
|
||||
static inline bool is_reg_si(int cls, int res) {
|
||||
const char *name = REG_CLASSES[cls].rsN[res];
|
||||
return !!strstr(name, "si");
|
||||
}
|
||||
static inline void reg_cast_to_gpr(int *cls, int *res) {
|
||||
const char *name = REG_CLASSES[*cls].rsN[*res];
|
||||
if(strstr(name, "a")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 1;
|
||||
} else if(strstr(name, "b")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 3;
|
||||
} else if(strstr(name, "c")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 5;
|
||||
} else if(strstr(name, "dl") || strstr(name, "dh") || strstr(name, "dx")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 7;
|
||||
} else if(strstr(name, "di")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 9;
|
||||
} else if(strstr(name, "si")) {
|
||||
*cls = REG_CLASS_16_32;
|
||||
*res = 11;
|
||||
}
|
||||
if(x86_ia16()) {
|
||||
(*res)--;
|
||||
}
|
||||
}
|
||||
|
||||
void arch_init();
|
55
src/x86/cg.c
55
src/x86/cg.c
@ -78,8 +78,8 @@ static const char *xv_sz(ScopeItem *v, int sz) {
|
||||
int cls = v->data.var.registerClass, reg = v->data.var.color;
|
||||
|
||||
if(type_size(v->type) != sz) {
|
||||
if(sz == 4) {
|
||||
reg_cast_up(&cls, ®);
|
||||
if(sz == x86_max_gpr_size()) {
|
||||
reg_cast_to_gpr(&cls, ®);
|
||||
} else abort();
|
||||
}
|
||||
|
||||
@ -185,13 +185,17 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
|
||||
} else if(p->nodeKind == AST_EXPR_VAR && p->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0));
|
||||
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
if(x86_ia16()) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "[bp + %li]", p->exprBinOp.operands[1]->exprPrim.val - tlc->chunk.stackReservation);
|
||||
} else {
|
||||
pr = snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val);
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else if(e->nodeKind == AST_EXPR_STACK_POINTER) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "esp");
|
||||
pr = snprintf(ret, XOPBUFSZ, x86_ia16() ? "sp" : "esp");
|
||||
} else if(e->nodeKind == AST_EXPR_VAR) {
|
||||
ScopeItem *v = e->exprVar.thing;
|
||||
|
||||
@ -243,8 +247,14 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
AST *s = a->chunk.statementFirst;
|
||||
|
||||
if(a->chunk.stackReservation) {
|
||||
if(x86_ia16()) {
|
||||
printf("push bp\n");
|
||||
printf("mov bp, sp\n");
|
||||
printf("sub sp, %lu\n", a->chunk.stackReservation);
|
||||
} else {
|
||||
printf("sub esp, %lu\n", a->chunk.stackReservation);
|
||||
}
|
||||
}
|
||||
|
||||
// Potentially complex pattern matching
|
||||
while(s) {
|
||||
@ -352,15 +362,20 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
|
||||
AST *e = s->stmtAssign.to;
|
||||
|
||||
if(x86_ia16()) {
|
||||
puts("push cx");
|
||||
puts("push dx");
|
||||
} else {
|
||||
puts("push ecx");
|
||||
puts("push edx");
|
||||
}
|
||||
|
||||
int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
|
||||
|
||||
size_t argSize = 0;
|
||||
|
||||
for(int i = argCount - 1; i >= 0; i--) {
|
||||
printf("push %s\n", xop_sz(cg->tlc, e->exprCall.args[i], 4));
|
||||
printf("push %s\n", xop_sz(cg->tlc, e->exprCall.args[i], arch_gpr_size()));
|
||||
|
||||
argSize += (type_size(e->exprCall.args[i]->expression.type) + 3) & ~3;
|
||||
}
|
||||
@ -371,10 +386,21 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
printf("call %s\n", xop(cg->tlc, e->exprCall.what));
|
||||
}
|
||||
|
||||
if(argSize) printf("add esp, %lu\n", argSize);
|
||||
if(argSize) {
|
||||
if(x86_ia16()) {
|
||||
printf("add sp, %lu\n", argSize);
|
||||
} else {
|
||||
printf("add esp, %lu\n", argSize);
|
||||
}
|
||||
}
|
||||
|
||||
if(x86_ia16()) {
|
||||
puts("pop dx");
|
||||
puts("pop cx");
|
||||
} else {
|
||||
puts("pop edx");
|
||||
puts("pop ecx");
|
||||
}
|
||||
|
||||
} else if(s->nodeKind == AST_STMT_ASSIGN) {
|
||||
|
||||
@ -455,8 +481,8 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
|
||||
} else {
|
||||
|
||||
const char *dest = xop_sz(cg->tlc, s->stmtAssign.what, 4);
|
||||
const char *src = xop_sz(cg->tlc, s->stmtAssign.to->exprCast.what, 4);
|
||||
const char *dest = xop_sz(cg->tlc, s->stmtAssign.what, x86_max_gpr_size());
|
||||
const char *src = xop_sz(cg->tlc, s->stmtAssign.to->exprCast.what, x86_max_gpr_size());
|
||||
|
||||
if(strcmp(dest, src)) {
|
||||
printf("mov %s, %s\n", dest, src);
|
||||
@ -520,8 +546,21 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
}
|
||||
|
||||
if(a->chunk.stackReservation) {
|
||||
if(x86_ia16()) {
|
||||
printf("add sp, %lu\n", a->chunk.stackReservation);
|
||||
} else {
|
||||
printf("add esp, %lu\n", a->chunk.stackReservation);
|
||||
}
|
||||
}
|
||||
|
||||
if(x86_ia16()) {
|
||||
if(x86_target() >= I186) {
|
||||
printf("leave\n");
|
||||
} else {
|
||||
printf("mov sp, bp\n");
|
||||
printf("pop bp\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("ret\n");
|
||||
|
||||
@ -735,7 +774,7 @@ static void determine_register_classes(AST *tlc) {
|
||||
if(type_size(tlc->chunk.vars[v]->type) == 1) {
|
||||
tlc->chunk.vars[v]->data.var.registerClass = REG_CLASS_8;
|
||||
} else {
|
||||
tlc->chunk.vars[v]->data.var.registerClass = REG_CLASS_NOT_8;
|
||||
tlc->chunk.vars[v]->data.var.registerClass = x86_ia16() ? REG_CLASS_IA16_USEABLE : REG_CLASS_NOT_8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
|
||||
// ret specifically returns in eax always, so it needs to be in a precolored var
|
||||
AST *retval = s->stmtReturn.val;
|
||||
|
||||
if(retval && (!is_xop(retval) || retval->nodeKind == AST_EXPR_PRIMITIVE || (retval->nodeKind == AST_EXPR_VAR && retval->exprVar.thing->kind == SCOPEITEM_VAR && !strchr(REG_CLASSES[retval->exprVar.thing->data.var.registerClass].rsN[retval->exprVar.thing->data.var.color], 'a')))) {
|
||||
if(retval && (!is_xop(retval) || retval->nodeKind == AST_EXPR_PRIMITIVE || (retval->nodeKind == AST_EXPR_VAR && retval->exprVar.thing->kind == SCOPEITEM_VAR && (!retval->exprVar.thing->data.var.precolored || !strchr(REG_CLASSES[retval->exprVar.thing->data.var.registerClass].rsN[retval->exprVar.thing->data.var.color], 'a'))))) {
|
||||
|
||||
retval = s->stmtReturn.val = varify(tlc, chu, stmtPrev, s, retval);
|
||||
this->effective = 1;
|
||||
@ -474,8 +474,8 @@ static void pre_dumb_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, A
|
||||
|
||||
ASTExprPrimitive *offset = calloc(1, sizeof(*offset));
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
offset->type = primitive_parse("u32");
|
||||
offset->val = 4 + i * 4;
|
||||
offset->type = type_u(x86_max_gpr_size());
|
||||
offset->val = 4 + i * x86_max_gpr_size();
|
||||
offset->stackGrowth = true;
|
||||
|
||||
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
|
||||
@ -640,6 +640,27 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
|
||||
*nptr = (AST*) prim;
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_CAST) {
|
||||
// TODO: Move all compile-time constant casting from ast_cast_expr to here.
|
||||
|
||||
AST *what = n->exprCast.what;
|
||||
Type *to = n->exprCast.to;
|
||||
|
||||
if(what->nodeKind == AST_EXPR_PRIMITIVE && (to->type == TYPE_TYPE_PRIMITIVE || to->type == TYPE_TYPE_POINTER)) {
|
||||
ASTExprPrimitive *ret = calloc(1, sizeof(*ret));
|
||||
ret->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
ret->type = to;
|
||||
|
||||
if(to->type == TYPE_TYPE_PRIMITIVE) {
|
||||
ret->val = what->exprPrim.val & ((1UL << to->primitive.width) - 1);
|
||||
} else {
|
||||
ret->val = what->exprPrim.val & ((1UL << (8 * type_size(to))) - 1);
|
||||
}
|
||||
|
||||
*nptr = ret;
|
||||
|
||||
*success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user