diff options
Diffstat (limited to 'compiler_and_linker/unsorted/TOC.c')
-rw-r--r-- | compiler_and_linker/unsorted/TOC.c | 2272 |
1 files changed, 0 insertions, 2272 deletions
diff --git a/compiler_and_linker/unsorted/TOC.c b/compiler_and_linker/unsorted/TOC.c deleted file mode 100644 index 7af09e3..0000000 --- a/compiler_and_linker/unsorted/TOC.c +++ /dev/null @@ -1,2272 +0,0 @@ -#include "cos.h" -#include "compiler/TOC.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CInit.h" -#include "compiler/CInt64.h" -#include "compiler/CFunc.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/Exceptions.h" -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/InstrSelection.h" -#include "compiler/Intrinsics.h" -#include "compiler/ObjGenMachO.h" -#include "compiler/Operands.h" -#include "compiler/PCode.h" -#include "compiler/PCodeInfo.h" -#include "compiler/PPCError.h" -#include "compiler/RegisterInfo.h" -#include "compiler/StackFrame.h" -#include "compiler/enode.h" -#include "compiler/objects.h" -#include "compiler/types.h" - -ObjectList *toclist; -ObjectList *exceptionlist; -void *descriptorlist; -PoolEntry *floatconstpool; -PoolEntry *doubleconstpool; -ObjectList *floatconstlist; -PoolEntry *vectorconstpool; -ObjectList *vectorconstlist; -Object toc0; -Boolean no_descriptors; -Object pic_base; -VarInfo pic_base_varinfo; -short pic_base_reg; -CodeLabelList *codelabellist; - -UInt8 lvslBytes[16][16] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, - 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, - 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E -}; - -UInt8 lvsrBytes[16][16] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, - 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, - 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, - 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 -}; - -// forward decls -static void estimate_func_param_size(ENode *node); - -static int disables_optimizer(ENode *node) { - ENode *funcref = node->data.funccall.funcref; - if (ENODE_IS(funcref, EOBJREF)) { - if (!strcmp(CMangler_GetLinkName(funcref->data.objref)->name, "___setjmp")) - return 1; - if (!strcmp(CMangler_GetLinkName(funcref->data.objref)->name, "___vec_setjmp")) - return 1; - } - return 0; -} - -void setupaddressing(void) { - floatconstlist = NULL; - descriptorlist = NULL; - toclist = NULL; - exceptionlist = NULL; - vectorconstlist = NULL; - vectorconstpool = NULL; - floatconstpool = NULL; - doubleconstpool = NULL; - - no_descriptors = 1; - memclrw(&toc0, sizeof(toc0)); - - pic_base_reg = 0; - memclrw(&pic_base, sizeof(pic_base)); - memclrw(&pic_base_varinfo, sizeof(pic_base_varinfo)); - pic_base.otype = OT_OBJECT; - pic_base.type = (Type *) &void_ptr; - pic_base.datatype = DNONLAZYPTR; - pic_base.u.toc.info = &pic_base_varinfo; -} - -void createNonLazyPointer(Object *obj) { - Object *toc; - ObjectList *list; - - toc = galloc(sizeof(Object)); - obj->toc = toc; - memclrw(toc, sizeof(Object)); - - toc->otype = OT_OBJECT; - toc->name = CParser_GetUniqueName(); - toc->toc = NULL; - toc->section = SECT_NONLAZY_PTRS; - toc->u.toc.info = CodeGen_GetNewVarInfo(); - toc->sclass = TK_STATIC; - toc->qual = Q_CONST; - toc->datatype = DNONLAZYPTR; - toc->flags |= OBJECT_FLAGS_2; - toc->type = CDecl_NewPointerType(obj->type); - toc->u.toc.over_load = obj; - toc->u.toc.linkname = CMangler_GetLinkName(obj); - - list = galloc(sizeof(ObjectList)); - memclrw(list, sizeof(ObjectList)); - list->object = toc; - list->next = toclist; - toclist = list; -} - -void referenceIndirectPointer(Object *obj) { - VarInfo *vi = obj->toc->u.toc.info; - vi->used = 1; - vi->usage += copts.optimizesize ? 1 : curstmtvalue; -} - -Object *createIndirect(Object *obj, Boolean flag1, Boolean flag2) { - CError_ASSERT(622, !copts.no_common || (obj->section != SECT_COMMON_VARS) || (obj->qual & Q_20000)); - - if (CParser_HasInternalLinkage(obj)) - return NULL; - if (ObjGen_IsExported(obj)) - return NULL; - - if (!copts.no_common && obj->datatype == DDATA && obj->section == SECT_DEFAULT && (obj->qual & Q_1000000)) - obj->section = SECT_COMMON_VARS; - - if (copts.codegen_dynamic && (!copts.no_common || !(obj->qual & Q_1000000))) { - if (!obj->toc) - createNonLazyPointer(obj); - else if (flag1) - obj->toc->u.toc.info = CodeGen_GetNewVarInfo(); - - if (flag2) - referenceIndirectPointer(obj); - - return obj->toc; - } else { - return NULL; - } -} - -Object *createfloatconstant(Type *type, Float *data) { - ObjectList *list; - Object *obj; - UInt32 *check; - - for (list = floatconstlist; list; list = list->next) { - obj = list->object; - check = (UInt32 *) obj->u.data.u.floatconst; - if (obj->type == type && check[0] == ((UInt32 *) data)[0] && check[1] == ((UInt32 *) data)[1]) - return obj; - } - - obj = galloc(sizeof(Object)); - memclrw(obj, sizeof(Object)); - obj->otype = OT_OBJECT; - obj->type = type; - obj->name = CParser_GetUniqueName(); - obj->toc = NULL; - obj->u.data.info = NULL; - obj->u.data.linkname = obj->name; - obj->sclass = TK_STATIC; - obj->qual = Q_CONST | Q_INLINE_DATA; - obj->datatype = DDATA; - if (type->size == 8) - obj->section = SECT_8BYTE_LITERALS; - else if (type->size == 4) - obj->section = SECT_4BYTE_LITERALS; - else - CError_FATAL(807); - - obj->flags |= OBJECT_FLAGS_2; - - obj->u.data.u.floatconst = galloc(sizeof(Float)); - *obj->u.data.u.floatconst = *data; - - list = galloc(sizeof(ObjectList)); - memclrw(list, sizeof(ObjectList)); - list->object = obj; - list->next = floatconstlist; - floatconstlist = list; - - ObjGen_DeclareFloatConst(obj); - return obj; -} - -Object *createvectorconstant(Type *type, MWVector128 *data) { - ObjectList *list; - Object *obj; - MWVector128 *check; - - for (list = vectorconstlist; list; list = list->next) { - obj = list->object; - check = obj->u.data.u.vector128const; - if (check->ul[0] == data->ul[0] && check->ul[1] == data->ul[1] && check->ul[2] == data->ul[2] && check->ul[3] == data->ul[3]) - return obj; - } - - obj = galloc(sizeof(Object)); - memclrw(obj, sizeof(Object)); - obj->otype = OT_OBJECT; - obj->type = type; - obj->name = CParser_GetUniqueName(); - obj->toc = NULL; - obj->u.data.info = NULL; - obj->u.data.linkname = obj->name; - obj->sclass = TK_STATIC; - obj->qual = Q_CONST | Q_INLINE_DATA; - obj->datatype = DDATA; - if (type->size == 16) - obj->section = SECT_16BYTE_LITERALS; - else - CError_FATAL(900); - - obj->flags |= OBJECT_FLAGS_2; - - obj->u.data.u.vector128const = galloc(sizeof(MWVector128)); - *obj->u.data.u.vector128const = *data; - - list = galloc(sizeof(ObjectList)); - memclrw(list, sizeof(ObjectList)); - list->object = obj; - list->next = vectorconstlist; - vectorconstlist = list; - - ObjGen_DeclareVectorConst(obj); - return obj; -} - -void DeclarePooledConstants(void) { - PoolEntry *entry; - char *buffer; - SInt32 fsize; - SInt32 dsize; - SInt32 vsize; - - fsize = 0; - for (entry = floatconstpool; entry; entry = entry->next) - fsize += 4; - - if (fsize) { - floatconstpool->object->type = CDecl_NewArrayType(TYPE(&stfloat), fsize); - buffer = galloc(fsize); - for (entry = floatconstpool; entry; entry = entry->next) - memcpy(buffer + entry->offset, entry->buffer, 4); - CInit_DeclareReadOnlyData(floatconstpool->object, buffer, NULL, fsize); - } - - dsize = 0; - for (entry = doubleconstpool; entry; entry = entry->next) - dsize += 8; - - if (dsize) { - doubleconstpool->object->type = CDecl_NewArrayType(TYPE(&stdouble), dsize); - buffer = galloc(dsize); - for (entry = doubleconstpool; entry; entry = entry->next) - memcpy(buffer + entry->offset, entry->buffer, 8); - CInit_DeclareReadOnlyData(doubleconstpool->object, buffer, NULL, dsize); - } - - vsize = 0; - for (entry = vectorconstpool; entry; entry = entry->next) - vsize += 16; - - if (vsize) { - vectorconstpool->object->type = CDecl_NewArrayType(TYPE(&stvectorsignedlong), vsize); - buffer = galloc(vsize); - for (entry = vectorconstpool; entry; entry = entry->next) - memcpy(buffer + entry->offset, entry->buffer, 16); - CInit_DeclareReadOnlyData(vectorconstpool->object, buffer, NULL, vsize); - } -} - -static Object *CreatePooledFloatConst(Type *type, Float *data, SInt32 *pOffset) { - if (type->size == 8u) { - PoolEntry *entry; - void *buffer; - Object *object; - SInt32 offset; - - buffer = galloc(8u); - CMach_InitFloatMem(type, *data, buffer); - if (cparamblkptr->precompile == 1) - CError_Error(CErrorStr180); - - for (entry = doubleconstpool; entry; entry = entry->next) { - if (!memcmp(entry->buffer, buffer, 8u)) - break; - } - - if (!entry) { - if (doubleconstpool) { - object = doubleconstpool->object; - offset = doubleconstpool->offset + 8u; - doubleconstpool->object->type->size += 8u; - } else { - DeclInfo di; - memclrw(&di, sizeof(di)); - di.thetype = CDecl_NewArrayType(TYPE(&stdouble), 8u); - di.name = GetHashNameNodeExport("@doubleBase0"); - di.qual = Q_CONST; - di.storageclass = TK_STATIC; - di.is_extern_c = 1; - di.section = SECT_CONST; - object = CParser_NewGlobalDataObject(&di); - object->nspace = cscope_root; - offset = 0; - } - - entry = galloc(sizeof(PoolEntry)); - entry->next = doubleconstpool; - doubleconstpool = entry; - entry->object = object; - entry->offset = offset; - entry->buffer = galloc(8u); - memcpy(entry->buffer, buffer, 8u); - } - - *pOffset = entry->offset; - return entry->object; - } - - if (type->size == 4u) { - PoolEntry *entry; - void *buffer; - Object *object; - SInt32 offset; - - buffer = galloc(4u); - CMach_InitFloatMem(type, *data, buffer); - if (cparamblkptr->precompile == 1) - CError_Error(CErrorStr180); - - for (entry = floatconstpool; entry; entry = entry->next) { - if (!memcmp(entry->buffer, buffer, 4u)) - break; - } - - if (!entry) { - if (floatconstpool) { - object = floatconstpool->object; - offset = floatconstpool->offset + 4u; - object->type->size += 4u; - } else { - DeclInfo di; - memclrw(&di, sizeof(di)); - di.thetype = CDecl_NewArrayType(TYPE(&stfloat), 4u); - di.name = GetHashNameNodeExport("@floatBase0"); - di.qual = Q_CONST; - di.storageclass = TK_STATIC; - di.is_extern_c = 1; - di.section = SECT_CONST; - object = CParser_NewGlobalDataObject(&di); - object->nspace = cscope_root; - offset = 0; - } - - entry = galloc(sizeof(PoolEntry)); - entry->next = floatconstpool; - floatconstpool = entry; - entry->object = object; - entry->offset = offset; - entry->buffer = galloc(4u); - memcpy(entry->buffer, buffer, 4u); - } - - *pOffset = entry->offset; - return entry->object; - } - - CError_FATAL(1183); - return NULL; -} - -Object *CreateFloatConst(Type *type, Float *data, SInt32 *pOffset) { - *pOffset = 0; - return createfloatconstant(type, data); -} - -static void RewriteFloatConst(ENode *expr) { - Object *obj; - SInt32 n; - ENode *subexpr; - - obj = CreateFloatConst(expr->rtype, &expr->data.floatval, &n); - if (n) { - subexpr = makediadicnode(create_objectrefnode(obj), intconstnode(TYPE(&stunsignedlong), n), EADD); - } else { - subexpr = create_objectrefnode(obj); - } - - expr->type = EINDIRECT; - expr->cost = 1; - expr->flags |= Q_CONST; - expr->data.monadic = subexpr; -} - -static void RewriteVectorConst(ENode *expr) { - PoolEntry *entry; - Object *object; - SInt32 offset; - ENode *inner; - UInt8 data[16]; - - CMach_InitVectorMem(expr->rtype, expr->data.vector128val, data, 1); - - if (cparamblkptr->precompile == 1) - CError_Error(CErrorStr180); - - for (entry = vectorconstpool; entry; entry = entry->next) { - if (!memcmp(entry->buffer, data, 16)) - break; - } - - if (!entry) { - if (vectorconstpool) { - object = vectorconstpool->object; - offset = vectorconstpool->offset + 16; - vectorconstpool->object->type->size += 16; - } else { - DeclInfo di; - memclrw(&di, sizeof(di)); - di.thetype = CDecl_NewArrayType(TYPE(&stvectorsignedlong), 16); - di.name = GetHashNameNodeExport("@vectorBase0"); - di.qual = Q_CONST; - di.storageclass = TK_STATIC; - di.is_extern_c = 1; - di.section = SECT_CONST; - object = CParser_NewGlobalDataObject(&di); - object->nspace = cscope_root; - offset = 0; - } - - entry = galloc(sizeof(PoolEntry)); - entry->next = vectorconstpool; - vectorconstpool = entry; - entry->object = object; - entry->offset = offset; - entry->buffer = galloc(16); - memcpy(entry->buffer, data, 16); - } - - if (entry->offset) { - inner = makediadicnode( - create_objectrefnode(entry->object), - intconstnode(TYPE(&stunsignedlong), entry->offset), - EADD); - } else { - inner = create_objectrefnode(entry->object); - } - - expr->type = EINDIRECT; - expr->cost = 1; - expr->flags |= ENODE_FLAG_CONST; - expr->data.monadic = inner; -} - -static Object *createcodelabel(CLabel *label) { - CodeLabelList *list; - Object *obj; - - for (list = codelabellist; list; list = list->next) { - if (list->label == label) - return list->object; - } - - obj = galloc(sizeof(Object)); - memclrw(obj, sizeof(Object)); - obj->otype = OT_OBJECT; - obj->type = (Type *) &void_ptr; - obj->name = label->uniquename; - obj->toc = NULL; - obj->u.data.info = NULL; // not sure if this is the right union! - obj->sclass = TK_STATIC; - obj->qual = Q_CONST; - obj->datatype = DDATA; - obj->flags |= OBJECT_FLAGS_2 | OBJECT_DEFINED; - - list = galloc(sizeof(CodeLabelList)); - memclrw(list, sizeof(CodeLabelList)); - list->object = obj; - list->label = label; - list->next = codelabellist; - codelabellist = list; - - return obj; -} - -void dumpcodelabels(Object *func) { - CodeLabelList *list; - - for (list = codelabellist; list; list = list->next) - ObjGen_DeclareCodeLabel(list->object, list->label->pclabel->block->codeOffset, func); -} - -static void referenceexception(Object *obj) { - ObjectList *list; - - if (obj && obj->otype == OT_OBJECT && obj->datatype == DLOCAL) { - for (list = exceptionlist; list; list = list->next) { - if (list->object == obj) - return; - } - - list = lalloc(sizeof(ObjectList)); - memclrw(list, sizeof(ObjectList)); - list->object = obj; - list->next = exceptionlist; - exceptionlist = list; - } -} - -static ENodeType invert_relop(ENodeType nodetype) { - switch (nodetype) { - case ELESS: return EGREATEREQU; - case EGREATER: return ELESSEQU; - case ELESSEQU: return EGREATER; - case EGREATEREQU: return ELESS; - case EEQU: return ENOTEQU; - case ENOTEQU: return EEQU; - default: return nodetype; - } -} - -static ENode *COND_to_COMPARE(ENode *cond, ENode *expr1, ENode *expr2) { - SInt32 val1; - SInt32 val2; - SInt32 condval; - ENodeType invop; - - while (expr1->type == ETYPCON && TYPE_FITS_IN_REGISTER(expr1->rtype)) - expr1 = expr1->data.monadic; - while (expr2->type == ETYPCON && TYPE_FITS_IN_REGISTER(expr2->rtype)) - expr2 = expr2->data.monadic; - - if (expr1->type != EINTCONST || !TYPE_FITS_IN_REGISTER(expr1->rtype) || !CInt64_IsInRange(expr1->data.intval, 4)) - return NULL; - if (expr2->type != EINTCONST || !TYPE_FITS_IN_REGISTER(expr2->rtype) || !CInt64_IsInRange(expr2->data.intval, 4)) - return NULL; - - val1 = expr1->data.intval.lo; - val2 = expr2->data.intval.lo; - condval = 0; - switch (val1) { - case 1: - if (val2 != 0) - return NULL; - break; - case 0: - condval = 1; - if (val2 != 1) - return NULL; - break; - default: - return NULL; - } - - while (cond->type == ELOGNOT) { - condval = (condval + 1) & 1; - cond = cond->data.monadic; - } - - if (condval) { - invop = invert_relop(cond->type); - if (invop == cond->type) - return NULL; - cond->type = invop; - } - - return cond; -} - -static ENode *comparewithzero(ENode *expr) { - ENode *expr1; - ENode *expr2; - ENode *tmp; - - expr1 = lalloc(sizeof(ENode)); - memclrw(expr1, sizeof(ENode)); - expr2 = lalloc(sizeof(ENode)); - memclrw(expr2, sizeof(ENode)); - - while (expr->type == EFORCELOAD || expr->type == ETYPCON || expr->type == ECOMMA) { - if (!TYPE_FITS_IN_REGISTER(expr->rtype)) - break; - if (expr->type == ECOMMA) { - expr->data.diadic.right = comparewithzero(expr->data.diadic.right); - return expr; - } - expr = expr->data.monadic; - } - - if (expr->type == ECOND && TYPE_FITS_IN_REGISTER(expr->rtype)) { - tmp = COND_to_COMPARE(expr->data.cond.cond, expr->data.cond.expr1, expr->data.cond.expr2); - if (tmp) - expr = tmp; - } - - if (expr->type >= ELESS && expr->type <= ENOTEQU) - return expr; - - if (IS_TYPE_FLOAT(expr->rtype)) { - static Float float0 = {0.0}; - - expr2->type = EFLOATCONST; - expr2->cost = 0; - expr2->rtype = (expr->rtype->size == 4) ? (Type *) &stfloat : (Type *) &stdouble; - expr2->data.floatval = float0; - } else { - expr2->type = EINTCONST; - expr2->cost = 0; - if (TYPE_IS_8BYTES(expr->rtype)) - expr2->rtype = (Type *) &stsignedlonglong; - else - expr2->rtype = (Type *) &stsignedint; - expr2->data.intval.lo = 0; - expr2->data.intval.hi = 0; - } - - expr1->type = ENOTEQU; - expr1->cost = expr->cost; - expr1->rtype = (Type *) &stsignedint; - expr1->data.diadic.left = expr; - expr1->data.diadic.right = expr2; - return expr1; -} - -static void rewritefunctioncallreturningstruct(ENode *expr) { - ENode *ret_expr; - ENode *copy; - - ret_expr = expr->data.funccall.args->node; - - copy = lalloc(sizeof(ENode)); - memclrw(copy, sizeof(ENode)); - - *copy = *expr; - expr->type = ECOMMA; - expr->data.diadic.left = copy; - expr->data.diadic.right = ret_expr; -} - -static void rewritestrcpy(ENode *expr) { - ENode *int_expr; - ENodeList *list; - - int_expr = lalloc(sizeof(ENode)); - memclrw(int_expr, sizeof(ENode)); - int_expr->type = EINTCONST; - int_expr->cost = 0; - int_expr->flags = 0; - int_expr->rtype = (Type *) &stunsignedlong; - CInt64_SetLong(&int_expr->data.intval, expr->data.funccall.args->next->node->data.string.size); - - list = lalloc(sizeof(ENodeList)); - memclrw(list, sizeof(ENodeList)); - list->next = NULL; - list->node = int_expr; - expr->data.funccall.args->next->next = list; - expr->data.funccall.funcref->data.objref = __memcpy_object; -} - -static SInt32 magnitude(Type *type) { - if (IS_TYPE_FLOAT(type)) - return type->size * 4; - else if (is_unsigned(type)) - return (type->size * 2) + 1; - else - return type->size * 2; -} - -static Type *promote_type(Type *type) { - if (IS_TYPE_ENUM(type)) - type = TYPE_ENUM(type)->enumtype; - if (TYPE_INTEGRAL(type)->integral > stsignedint.integral) - return type; - else - return (Type *) &stsignedint; -} - -static Type *common_type(Type *type1, Type *type2) { - Type *tmp; - - if (IS_TYPE_FLOAT(type1) || IS_TYPE_FLOAT(type2)) { - if (TYPE_INTEGRAL(type1)->integral > TYPE_INTEGRAL(type2)->integral) - return type1; - else - return type2; - } - - type1 = promote_type(type1); - type2 = promote_type(type2); - if (type1 != type2) { - if (TYPE_INTEGRAL(type1)->integral < TYPE_INTEGRAL(type2)->integral) { - tmp = type1; - type1 = type2; - type2 = tmp; - } - - if (type1->size == type2->size && !is_unsigned(type1) && is_unsigned(type2)) { - if (type1 == (Type *) &stsignedlong) { - type1 = (Type *) &stunsignedlong; - } else { - CError_ASSERT(1789, type1 == (Type *) &stsignedlonglong); - type1 = (Type *) &stunsignedlonglong; - } - } - } - - return type1; -} - -static void rewrite_opassign(ENode *expr, ENodeType exprtype) { - ENode *left_sub; - ENode *right; - Type *left_type; - Type *right_type; - ENode *new_expr; - ENode *tmp; - Type *commontype; - Type *promo_left; - Type *promo_right; - - left_sub = expr->data.diadic.left->data.monadic; - right = expr->data.diadic.right; - left_type = expr->data.diadic.left->rtype; - right_type = expr->data.diadic.right->rtype; - - new_expr = lalloc(sizeof(ENode)); - memclrw(new_expr, sizeof(ENode)); - new_expr->type = exprtype; - new_expr->rtype = left_type; - new_expr->data.diadic.left = expr->data.diadic.left; - new_expr->data.diadic.right = right; - - expr->type = EASS; - expr->data.diadic.left = left_sub; - expr->data.diadic.right = new_expr; - - if (left_sub->type != EOBJREF) { - ENode *define; - ENode *reuse; - - define = lalloc(sizeof(ENode)); - memclrw(define, sizeof(ENode)); - define->type = EDEFINE; - define->rtype = left_type; - - reuse = lalloc(sizeof(ENode)); - memclrw(reuse, sizeof(ENode)); - reuse->type = EREUSE; - reuse->rtype = left_type; - reuse->data.monadic = define; - - if (left_sub->type != EBITFIELD) { - define->data.monadic = expr->data.diadic.left; - expr->data.diadic.left = define; - new_expr->data.diadic.left->data.diadic.left = reuse; - } else { - ENode *copy; - define->data.monadic = left_sub->data.diadic.left; - left_sub->data.diadic.left = define; - - copy = lalloc(sizeof(ENode)); - *copy = *left_sub; - copy->data.diadic.left = reuse; - new_expr->data.diadic.left->data.diadic.left = copy; - } - } - - switch (exprtype) { - case EADD: - case ESUB: - if (IS_TYPE_POINTER(left_type)) - break; - if (right->type == EINTCONST && TYPE_FITS_IN_REGISTER(left_type)) - break; - case EAND: - case EXOR: - case EOR: - if (left_type == right_type) - break; - case EMUL: - case EDIV: - case EMODULO: - commontype = common_type(left_type, right_type); - if (left_type != commontype) { - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = left_type; - tmp->data.monadic = expr->data.diadic.right; - expr->data.diadic.right = tmp; - - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = commontype; - tmp->data.monadic = new_expr->data.diadic.left; - new_expr->data.diadic.left = tmp; - } - if (right_type != commontype) { - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = commontype; - tmp->data.monadic = new_expr->data.diadic.right; - new_expr->data.diadic.right = tmp; - } - new_expr->rtype = commontype; - break; - - case ESHL: - case ESHR: - promo_left = promote_type(left_type); - promo_right = promote_type(right_type); - if (left_type != promo_left) { - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = left_type; - tmp->data.monadic = expr->data.diadic.right; - expr->data.diadic.right = tmp; - - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = promo_left; - tmp->data.monadic = new_expr->data.diadic.left; - new_expr->data.diadic.left = tmp; - } - if (right_type != promo_right) { - if (new_expr->data.diadic.right->type == EINTCONST && promo_right == (Type *) &stsignedint) { - new_expr->data.diadic.right->rtype = (Type *) &stsignedint; - } else { - tmp = lalloc(sizeof(ENode)); - memclrw(tmp, sizeof(ENode)); - tmp->type = ETYPCON; - tmp->rtype = promo_right; - tmp->data.monadic = new_expr->data.diadic.right; - new_expr->data.diadic.right = tmp; - } - } - new_expr->rtype = promo_left; - break; - } -} - -static void rewrite_preincdec(ENode *expr) { - ENode *subexpr; // r31 - Type *type; // r28 - ENode *new_expr; // r29 - - subexpr = expr->data.monadic; - type = expr->rtype; - - new_expr = lalloc(sizeof(ENode)); - memclrw(new_expr, sizeof(ENode)); - - if (IS_TYPE_FLOAT(type)) { - new_expr->type = EFLOATCONST; - new_expr->cost = 0; - new_expr->rtype = type; - new_expr->data.floatval = one_point_zero; - } else if (IS_TYPE_POINTER(type)) { - new_expr->type = EINTCONST; - new_expr->cost = 0; - new_expr->rtype = (Type *) &stunsignedlong; - new_expr->data.intval.hi = 0; - new_expr->data.intval.lo = TYPE_POINTER(type)->target->size; - } else { - new_expr->type = EINTCONST; - new_expr->cost = 0; - new_expr->rtype = type; - new_expr->data.intval.hi = 0; - new_expr->data.intval.lo = 1; - } - - expr->type = (expr->type == EPREDEC) ? ESUBASS : EADDASS; - expr->data.diadic.left = subexpr; - expr->data.diadic.right = new_expr; -} - -// Don't know what this would be called in the original, but weh -typedef union signed_vec { - SInt8 sc[16]; - SInt16 ss[8]; - SInt32 sl[4]; -} signed_vec; - -Boolean canoptimizevectorconst(MWVector128 *vecp, Type *type, COVCResult *result) { - // this function is very broken - signed_vec vec; - union { SInt32 lg; SInt8 ch[4]; } conv32; - union { SInt16 sh; SInt8 ch[2]; } conv16; - char flag; - SInt8 first8; - SInt16 first16; - SInt32 first32; - int i; - char ci; - UInt32 l0, l1, l2, l3; - - if (IS_TYPE_VECTOR(type)) { - vec = *((signed_vec *) vecp); - - first8 = vec.sc[0]; - flag = 1; - i = 1; - while (flag && i < 16) - flag = first8 == vec.sc[i++]; - /*flag = 1; - for (i = 1; flag && i < 16; i++) { - flag = first8 == vec.sc[i]; - }*/ - - if (flag && first8 < 16 && first8 > -17) { - if (result) { - result->op1 = PC_VSPLTISB; - result->op2 = -1; - result->arg = first8; - } - return 1; - } - - first16 = vec.ss[0]; - flag = 1; - for (i = 1; flag && i < 8; i++) { - flag = vec.ss[i] == first16; - } - - conv16.sh = first16; - if (flag && conv16.ch[0] == 0 && conv16.ch[1] < 16 && conv16.ch[1] >= 0) { - if (result) { - result->op1 = PC_VSPLTISH; - result->op2 = -1; - result->arg = conv16.ch[1]; - } - return 1; - } - - if (flag && conv16.ch[0] == -1 && (conv16.ch[1] & 0xF0) == 0xF0) { - if (result) { - result->op1 = PC_VSPLTISH; - result->op2 = -1; - result->arg = conv16.ch[1]; - } - return 1; - } - - first32 = vec.sl[0]; - flag = 1; - for (i = 1; flag && i < 4; i++) { - flag = vec.sl[i] == first32; - } - - conv32.lg = first32; - if (flag && conv32.ch[0] == 0 && conv32.ch[1] == 0 && conv32.ch[2] == 0 && conv32.ch[3] < 16 && conv32.ch[3] >= 0) { - if (result) { - result->op1 = PC_VSPLTISW; - result->op2 = -1; - result->arg = conv32.ch[3]; - } - return 1; - } - - if (flag && conv32.ch[0] == -1 && conv32.ch[1] == -1 && conv32.ch[2] == -1 && (conv32.ch[3] & 0xF0) == 0xF0) { - if (result) { - result->op1 = PC_VSPLTISW; - result->op2 = -1; - result->arg = conv32.ch[3]; - } - return 1; - } - - l0 = vec.sl[0]; - l1 = vec.sl[1]; - l2 = vec.sl[2]; - l3 = vec.sl[3]; - for (ci = 0; ci < 16; ci++) { - UInt32 *l; - UInt32 *r; - - l = (UInt32 *) lvslBytes[(char) ci]; - r = (UInt32 *) lvsrBytes[(char) ci]; - if (l0 == l[0] && l1 == l[1] && l2 == l[2] && l3 == l[3]) { - if (result) { - result->op1 = -1; - result->op2 = PC_LVSL; - result->arg = ci; - } - return 1; - } - if (l0 == r[0] && l1 == r[1] && l2 == r[2] && l3 == r[3]) { - if (result) { - result->op1 = -1; - result->op2 = PC_LVSR; - result->arg = ci; - } - return 1; - } - } - } - - return 0; -} - -static SInt32 countindirects(ENode *expr) { - SInt32 tmp1; - SInt32 tmp2; - - switch (expr->type) { - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EVECTOR128CONST: - return 0; - case ECOND: - if (expr->data.cond.cond->hascall || expr->data.cond.expr1->hascall || expr->data.cond.expr2->hascall) - return 2; - - if ((tmp1 = countindirects(expr->data.cond.cond)) >= 2) - return 2; - if ((tmp2 = countindirects(expr->data.cond.expr1)) >= 2) - return 2; - if (tmp2 > tmp1) - tmp1 = tmp2; - if ((tmp2 = countindirects(expr->data.cond.expr2)) >= 2) - return 2; - if (tmp2 > tmp1) - tmp1 = tmp2; - return tmp1; - case EFUNCCALL: - case EFUNCCALLP: - return 2; - case EMUL: - case EMULV: - case EDIV: - case EMODULO: - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - if ((tmp1 = countindirects(expr->data.diadic.left)) >= 2) - return 2; - if ((tmp2 = countindirects(expr->data.diadic.right)) >= 2) - return 2; - if (tmp2 > tmp1) - tmp1 = tmp2; - return tmp1; - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - if (expr->type == EINDIRECT) - return countindirects(expr->data.monadic) + 1; - else - return countindirects(expr->data.monadic); - default: - return 2; - } -} - -static Boolean DetectCondSideAffect(ENode *expr) { - switch (expr->type) { - case EMUL: - case EMULV: - case EDIV: - case EMODULO: - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case EAND: - case EXOR: - case EOR: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - if (DetectCondSideAffect(expr->data.diadic.left)) - return 1; - return DetectCondSideAffect(expr->data.diadic.right); - case EINDIRECT: - if (expr->data.monadic->type == EINDIRECT) - return 1; - if (expr->data.monadic->type == EOBJREF) { - if (expr->data.monadic->data.objref->datatype != DLOCAL && expr->data.monadic->data.objref->datatype != DDATA) - return 1; - if (IS_TYPE_POINTER(expr->data.monadic->data.objref->type)) - return 1; - return Registers_GetVarInfo(expr->data.monadic->data.objref)->noregister != 0; - } - return 1; - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - return DetectCondSideAffect(expr->data.monadic); - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EVECTOR128CONST: - return 0; - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case ELAND: - case ELOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOND: - case EFUNCCALL: - case EFUNCCALLP: - case EMFPOINTER: - case ENULLCHECK: - case EPRECOMP: - case EDEFINE: - case EREUSE: - case EASSBLK: - case ECONDASS: - return 1; - default: - CError_FATAL(2523); - return 1; - } -} - -static UInt8 WeightandSumOps(ENode *expr) { - UInt32 score; - - switch (expr->type) { - case ECOND: - case ECONDASS: - score = WeightandSumOps(expr->data.cond.cond); - score += WeightandSumOps(expr->data.cond.expr1); - score += WeightandSumOps(expr->data.cond.expr2); - break; - case EMUL: - case EMULV: - case EMULASS: - score = WeightandSumOps(expr->data.diadic.left) + 10; - score += WeightandSumOps(expr->data.diadic.right); - break; - case EDIV: - case EMODULO: - case EDIVASS: - case EMODASS: - score = WeightandSumOps(expr->data.diadic.left) + 20; - score += WeightandSumOps(expr->data.diadic.right); - break; - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - score = WeightandSumOps(expr->data.diadic.left) + 1; - score += WeightandSumOps(expr->data.diadic.right); - break; - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - score = WeightandSumOps(expr->data.monadic) + 1; - break; - case EINDIRECT: - if (expr->data.monadic->type == EOBJREF && expr->data.monadic->data.objref->datatype == DLOCAL) - if (!Registers_GetVarInfo(expr->data.monadic->data.objref)->noregister) - return 0; - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - score = WeightandSumOps(expr->data.monadic); - break; - case EOBJREF: - score = 0; - break; - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EVECTOR128CONST: - score = 0; - break; - case EFUNCCALL: - case EFUNCCALLP: - score = 5; - break; - default: - score = 255; - } - - if (score >= 255) - score = 255; - return (UInt8) score; -} - -Boolean TOC_use_fsel(ENode *expr) { - ENode *left; - ENode *right; - Type *rtype; - int score1; - int score2; - - left = expr->data.cond.expr1; - right = expr->data.cond.expr2; - rtype = expr->rtype; - - if (!copts.peephole) return 0; - if (!copts.gen_fsel) return 0; - if (left->hascall) return 0; - if (right->hascall) return 0; - if (!IS_TYPE_FLOAT(rtype)) return 0; - if (!IS_TYPE_FLOAT(left->rtype)) return 0; - if (!IS_TYPE_FLOAT(right->rtype)) return 0; - - if (expr->data.cond.cond->type < ELESS || expr->data.cond.cond->type > ENOTEQU) - return 0; - if (!IS_TYPE_FLOAT(expr->data.cond.cond->data.diadic.right->rtype)) - return 0; - if (expr->data.cond.cond->type == ELOGNOT || expr->data.cond.cond->type == ELAND || expr->data.cond.cond->type == ELOR) - return 0; - - if (expr->type == ECONDASS) { - if (left->type != EINDIRECT) - return 0; - if (left->data.monadic->type != EOBJREF) - return 0; - } - - if (DetectCondSideAffect(left)) - return 0; - if (DetectCondSideAffect(right)) - return 0; - - if (expr->type == ECONDASS) - score1 = 1; - else - score1 = WeightandSumOps(left); - score2 = WeightandSumOps(right); - - if (score1 > copts.gen_fsel) - return 0; - else if (score2 > copts.gen_fsel) - return 0; - else - return 1; -} - -Boolean TOC_use_isel(ENode *expr, Boolean flag) { - int opt; - ENode *left; - ENode *right; - Type *rtype; - Object *obj; - int score1; - int score2; - - left = expr->data.cond.expr1; - right = expr->data.cond.expr2; - rtype = expr->rtype; - if (flag) - opt = 10; - else - opt = copts.gen_isel; - - if (!opt) return 0; - if (!copts.peephole) return 0; - if (left->hascall) return 0; - if (right->hascall) return 0; - if (!TYPE_FITS_IN_REGISTER(rtype)) return 0; - if (!TYPE_FITS_IN_REGISTER(left->rtype)) return 0; - if (!TYPE_FITS_IN_REGISTER(right->rtype)) return 0; - - if (expr->data.cond.cond->type < ELESS || expr->data.cond.cond->type > ENOTEQU) - return 0; - if (TYPE_IS_8BYTES(rtype)) - return 0; - - if (flag) { - if (!TYPE_FITS_IN_REGISTER(expr->data.cond.cond->data.diadic.right->rtype)) - return 0; - if (TYPE_IS_8BYTES(expr->data.cond.cond->data.diadic.right->rtype)) - return 0; - } - - if (expr->type == ECONDASS) { - if (left->type != EINDIRECT) - return 0; - if (left->data.monadic->type != EOBJREF) - return 0; - if (flag) { - obj = left->data.monadic->data.objref; - if (obj->datatype != DLOCAL) - return 0; - if ((Registers_GetVarInfo(obj) ? Registers_GetVarInfo(obj)->reg : 0) == 0) - return 0; - if (obj->u.var.info->rclass != RegClass_GPR) - return 0; - } - } - - if (DetectCondSideAffect(left)) - return 0; - if (DetectCondSideAffect(right)) - return 0; - - if (expr->type == ECONDASS) - score1 = 1; - else - score1 = WeightandSumOps(left); - score2 = WeightandSumOps(right); - - if (score1 > opt) - return 0; - else if (score2 > opt) - return 0; - else - return 1; -} - -SInt32 GetSizeSkip(ENode *expr) { - if (expr->type == EASS) - expr = expr->data.diadic.right; - if (expr->type == ETYPCON && expr->data.monadic->rtype->size < expr->rtype->size) - return expr->data.monadic->rtype->size; - else - return expr->rtype->size; -} - -void Optimize64bitMath(ENode *expr) { - ENode *left; // r23 - ENode *right; // r28 - SInt32 leftsize; // r24 - SInt32 rightsize; // r25 - SInt32 totalsize; // r22 - int unsignedflag; // r4 - - CError_ASSERT(2886, TYPE_IS_8BYTES(expr->rtype)); - - left = expr->data.diadic.left; - right = expr->data.diadic.right; - leftsize = GetSizeSkip(left); - totalsize = (leftsize + (rightsize = GetSizeSkip(right))); - unsignedflag = is_unsigned(expr->rtype) != 0; - - switch (totalsize) { - case 2: - case 3: - case 4: - if (unsignedflag) { - left->rtype = (Type *) &stunsignedint; - right->rtype = (Type *) &stunsignedint; - } else { - left->rtype = (Type *) &stsignedint; - right->rtype = (Type *) &stsignedint; - } - break; - case 5: - case 6: - case 8: - case 9: - case 10: - case 12: - if (expr->type != ESUB || leftsize >= rightsize) { - if (leftsize < 4) { - if (unsignedflag) - left->rtype = (Type *) &stunsignedint; - else - left->rtype = (Type *) &stsignedint; - } else { - if (left->type == ETYPCON && left->data.monadic->rtype != (Type *) &stfloat) - expr->data.diadic.left = left->data.monadic; - } - if (rightsize < 4) { - if (unsignedflag) - right->rtype = (Type *) &stunsignedint; - else - right->rtype = (Type *) &stsignedint; - } else { - if (right->type == ETYPCON && right->data.monadic->rtype != (Type *) &stfloat) - expr->data.diadic.right = right->data.monadic; - } - } - break; - case 16: - break; - default: - CError_FATAL(2975); - } -} - -static Boolean OptimizeNestedAssginments(ENode **pexpr, Object *check) { - ENode *expr; - Boolean success1; - Boolean success2; - - expr = *pexpr; - switch (expr->type) { - case EOBJREF: - return check != expr->data.objref; - case EMUL: - case EMULV: - case EDIV: - case EMODULO: - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBCLR: - case EBTST: - case EBSET: - switch (expr->type) { - case EASS: - if (ENODE_IS(expr->data.diadic.left, EOBJREF) && expr->data.diadic.left->data.objref == check) { - *pexpr = expr->data.diadic.right; - return OptimizeNestedAssginments(pexpr, check); - } - break; - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - CError_FATAL(3033); - return 0; - } - if (OptimizeNestedAssginments(&expr->data.diadic.right, check)) - return OptimizeNestedAssginments(&expr->data.diadic.left, check); - else - return 0; - break; - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - case EINDIRECT: - case EMONMIN: - case EBINNOT: - case ELOGNOT: - case EFORCELOAD: - case ETYPCON: - case EBITFIELD: - return OptimizeNestedAssginments(&expr->data.monadic, check); - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EVECTOR128CONST: - return 1; - case ECOND: - success2 = OptimizeNestedAssginments(&expr->data.cond.expr2, check); - success1 = OptimizeNestedAssginments(&expr->data.cond.expr1, check); - if (!success2 || !success1) - return 0; - return OptimizeNestedAssginments(&expr->data.cond.cond, check) == 0; - case ECONDASS: - if (!OptimizeNestedAssginments(&expr->data.cond.expr2, check)) - return 0; - if (OptimizeNestedAssginments(&expr->data.cond.cond, check)) - return OptimizeNestedAssginments(&expr->data.cond.expr1, check) == 0; - else - return 0; - case EFUNCCALL: - case EFUNCCALLP: - case EMFPOINTER: - case ENULLCHECK: - case EPRECOMP: - case EDEFINE: - case EREUSE: - case EASSBLK: - return 0; - default: - CError_FATAL(3083); - return 0; - } -} - -static void expandTOCexpression(ENode *expr, Type *type, int ignored) { - Object *obj; - Object *tmpobj; - ENode *cond; - ENode *tmpexpr; - ENode *newexpr; - ENodeList *list; - - expr->ignored = ignored; - switch (expr->type) { - case EINTCONST: - expr->hascall = 0; - break; - case EFLOATCONST: - uses_globals = 1; - RewriteFloatConst(expr); - expandTOCexpression(expr, NULL, 0); - break; - case EVECTOR128CONST: - if (!canoptimizevectorconst(&expr->data.vector128val, expr->rtype, NULL)) { - uses_globals = 1; - RewriteVectorConst(expr); - expandTOCexpression(expr, NULL, 0); - } - break; - case ESTRINGCONST: - uses_globals = 1; - CInit_RewriteString(expr, 1); - expandTOCexpression(expr, NULL, 0); - break; - case EOBJREF: - obj = expr->data.objref; - CError_ASSERT(3203, obj->datatype != DALIAS); - if (obj->datatype == DFUNC || obj->datatype == DVFUNC) - uses_globals = 1; - if (obj->datatype == DDATA) { - uses_globals = 1; - if (createIndirect(obj, 0, 1)) { - tmpexpr = lalloc(sizeof(ENode)); - memclrw(tmpexpr, sizeof(ENode)); - tmpexpr->type = EOBJREF; - tmpexpr->cost = 0; - tmpexpr->data.objref = obj->toc; - tmpexpr->rtype = CDecl_NewPointerType(expr->rtype); - - expr->type = EINDIRECT; - expr->cost = 1; - expr->data.monadic = tmpexpr; - } - } - expr->hascall = 0; - break; - case ECONDASS: - expr->ignored = 0; - case ECOND: - if (!ENODE_IS_RANGE(expr->data.cond.cond, ELESS, ENOTEQU)) - expr->data.cond.cond = comparewithzero(expr->data.cond.cond); - expandTOCexpression(expr->data.cond.expr1, NULL, ignored); - expandTOCexpression(expr->data.cond.expr2, NULL, ignored); - if (TOC_use_fsel(expr)) { - cond = expr->data.cond.cond; - if (ENODE_IS(cond->data.diadic.right, EFLOATCONST) && CMach_FloatIsZero(cond->data.diadic.right->data.floatval)) { - expandTOCexpression(cond->data.diadic.left, NULL, 0); - } else if (ENODE_IS(cond->data.diadic.left, EFLOATCONST) && CMach_FloatIsZero(cond->data.diadic.left->data.floatval)) { - expandTOCexpression(cond->data.diadic.right, NULL, 0); - } else { - expandTOCexpression(expr->data.cond.cond, NULL, 0); - } - } else { - expandTOCexpression(expr->data.cond.cond, NULL, 0); - } - expr->hascall = expr->data.cond.cond->hascall | expr->data.cond.expr1->hascall | expr->data.cond.expr2->hascall; - break; - case EFUNCCALL: - case EFUNCCALLP: - if (is_intrinsic_function_call(expr)) { - expr->hascall = 0; - if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_008) { - if (copts.altivec_model) - update_frame_align(16); - dynamic_stack = 1; - requires_frame = 1; - } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_035) { - if (expr->data.funccall.args->next->node->type == ESTRINGCONST) { - rewritestrcpy(expr); - } else { - requires_frame = 1; - makes_call = 1; - expr->hascall = 1; - } - } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_036) { - if (expr->data.funccall.args->next->next->node->type != EINTCONST) { - requires_frame = 1; - makes_call = 1; - expr->hascall = 1; - } - } - } else { - requires_frame = 1; - makes_call = 1; - expr->hascall = 1; - } - - if (disables_optimizer(expr)) { - disable_optimizer |= 1; - if (copts.disable_registers) - disable_optimizer |= 2; - } - - if (ENODE_IS(expr->data.funccall.funcref, EINDIRECT) && IS_TYPE_FUNC(expr->data.funccall.funcref->rtype)) - *expr->data.funccall.funcref = *expr->data.funccall.funcref->data.monadic; - - if (ENODE_IS(expr->data.funccall.funcref, EOBJREF)) { - expr->data.funccall.funcref->hascall = 0; - if (expr->data.funccall.funcref->data.objref->datatype == DVFUNC && (expr->data.funccall.funcref->flags & ENODE_FLAG_80)) { - tmpobj = galloc(sizeof(Object)); - *tmpobj = *expr->data.funccall.funcref->data.objref; - tmpobj->datatype = DFUNC; - expr->data.funccall.funcref->data.objref = tmpobj; - } - } else { - expandTOCexpression(expr->data.funccall.funcref, NULL, 0); - } - - for (list = expr->data.funccall.args; list; list = list->next) - expandTOCexpression(list->node, NULL, 0); - - if (expr->hascall) - estimate_func_param_size(expr); - - if (is_intrinsic_function_call(expr)) { - for (list = expr->data.funccall.args; list; list = list->next) - expr->hascall |= list->node->hascall; - } - - if (CMach_PassResultInHiddenArg(TYPE_FUNC(expr->data.funccall.functype)->functype)) - rewritefunctioncallreturningstruct(expr); - - break; - case ECOMMA: - expandTOCexpression(expr->data.diadic.left, NULL, 1); - expandTOCexpression(expr->data.diadic.right, NULL, ignored); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - break; - case ELAND: - case ELOR: - if (!ENODE_IS(expr->data.diadic.left, ELOGNOT) && !ENODE_IS2(expr->data.diadic.left, ELAND, ELOR) && !ENODE_IS_RANGE(expr->data.diadic.left, ELESS, ENOTEQU)) - expr->data.diadic.left = comparewithzero(expr->data.diadic.left); - if (!ENODE_IS(expr->data.diadic.right, ELOGNOT) && !ENODE_IS2(expr->data.diadic.right, ELAND, ELOR) && !ENODE_IS_RANGE(expr->data.diadic.right, ELESS, ENOTEQU)) - expr->data.diadic.right = comparewithzero(expr->data.diadic.right); - expandTOCexpression(expr->data.diadic.left, NULL, 0); - expandTOCexpression(expr->data.diadic.right, NULL, 0); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - break; - case EDIVASS: - if (!IS_TYPE_FLOAT(expr->rtype) && IS_TYPE_FLOAT(expr->data.diadic.right->rtype)) - uses_globals = 1; - rewrite_opassign(expr, EDIV); - goto opassign_common; - case EMULASS: - if (!IS_TYPE_FLOAT(expr->rtype) && IS_TYPE_FLOAT(expr->data.diadic.right->rtype)) - uses_globals = 1; - rewrite_opassign(expr, EMUL); - goto opassign_common; - case EADDASS: - if (!IS_TYPE_FLOAT(expr->rtype) && IS_TYPE_FLOAT(expr->data.diadic.right->rtype)) - uses_globals = 1; - rewrite_opassign(expr, EADD); - goto opassign_common; - case ESUBASS: - if (!IS_TYPE_FLOAT(expr->rtype) && IS_TYPE_FLOAT(expr->data.diadic.right->rtype)) - uses_globals = 1; - rewrite_opassign(expr, ESUB); - goto opassign_common; - case EMODASS: - if (!IS_TYPE_FLOAT(expr->rtype) && IS_TYPE_FLOAT(expr->data.diadic.right->rtype)) - uses_globals = 1; - rewrite_opassign(expr, EMODULO); - goto opassign_common; - case ESHLASS: - rewrite_opassign(expr, ESHL); - goto opassign_common; - case ESHRASS: - rewrite_opassign(expr, ESHR); - goto opassign_common; - case EANDASS: - rewrite_opassign(expr, EAND); - goto opassign_common; - case EXORASS: - rewrite_opassign(expr, EXOR); - goto opassign_common; - case EORASS: - rewrite_opassign(expr, EOR); - goto opassign_common; - case EASS: - if (ENODE_IS(expr->data.diadic.left, EINDIRECT)) - expr->data.diadic.left = expr->data.diadic.left->data.monadic; - opassign_common: - expandTOCexpression(expr->data.diadic.left, NULL, 0); - expandTOCexpression(expr->data.diadic.right, NULL, 0); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - break; - case EEQU: - case ENOTEQU: - if (ENODE_IS(expr->data.diadic.right, EINTCONST) && expr->data.diadic.right->data.intval.lo == 0 && expr->data.diadic.right->data.intval.hi == 0) { - for (tmpexpr = expr->data.diadic.left; ENODE_IS2(tmpexpr, EFORCELOAD, ETYPCON); tmpexpr = tmpexpr->data.monadic) { - if (!TYPE_FITS_IN_REGISTER(tmpexpr->rtype)) - break; - } - if (ENODE_IS(tmpexpr, ELOGNOT) && TYPE_FITS_IN_REGISTER(tmpexpr->data.monadic->rtype)) { - if (ENODE_IS(expr, EEQU)) - expr->type = ENOTEQU; - else - expr->type = EEQU; - expr->data.diadic.left = tmpexpr->data.monadic; - expandTOCexpression(expr, NULL, 0); - break; - } - if (ENODE_IS(tmpexpr, EEQU)) { - if (ENODE_IS(expr, EEQU)) - tmpexpr->type = ENOTEQU; - *expr = *tmpexpr; - expandTOCexpression(expr, NULL, 0); - break; - } - if (ENODE_IS(tmpexpr, ENOTEQU)) { - if (ENODE_IS(expr, EEQU)) - tmpexpr->type = EEQU; - *expr = *tmpexpr; - expandTOCexpression(expr, NULL, 0); - break; - } - if (ENODE_IS(tmpexpr, ECOND)) { - newexpr = COND_to_COMPARE(tmpexpr->data.cond.cond, tmpexpr->data.cond.expr1, tmpexpr->data.cond.expr2); - if (newexpr) { - *tmpexpr = *newexpr; - expandTOCexpression(expr, NULL, 0); - break; - } - } - } - case EDIV: - if (ENODE_IS(expr, EDIV) && ENODE_IS(expr->data.diadic.right, EFLOATCONST) && CMach_FloatIsPowerOf2(expr->data.diadic.right->data.floatval)) { - expr->type = EMUL; - expr->data.diadic.right->data.floatval = CMach_FloatReciprocal(expr->data.diadic.right->data.floatval); - } - case EMODULO: - case ESHL: - case ESHR: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - expandTOCexpression(expr->data.diadic.left, NULL, 0); - expandTOCexpression(expr->data.diadic.right, NULL, 0); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - if (TYPE_IS_8BYTES(expr->rtype)) { - if (ENODE_IS2(expr, ESHL, ESHR) && !ENODE_IS(expr->data.diadic.right, EINTCONST)) { - expr->hascall = 1; - requires_frame = 1; - makes_call = 1; - } - if (ENODE_IS2(expr, EDIV, EMODULO)) { - if (ENODE_IS(expr->data.diadic.right, EINTCONST)) { - if (I8_log2n(((SInt64) expr->data.diadic.right->data.intval.hi << 32) + expr->data.diadic.right->data.intval.lo) <= 0) { - expr->hascall = 1; - requires_frame = 1; - makes_call = 1; - } - } else { - expr->hascall = 1; - requires_frame = 1; - makes_call = 1; - } - } - } - break; - case ESUB: - if (ENODE_IS(expr->data.diadic.right, EINTCONST)) { - expr->type = EADD; - expr->data.diadic.right->data.intval = CInt64_Neg(expr->data.diadic.right->data.intval); - } - case EMUL: - case EADD: - case EAND: - case EXOR: - case EOR: - expandTOCexpression(expr->data.diadic.left, type, 0); - expandTOCexpression(expr->data.diadic.right, type, 0); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - if (ENODE_IS3(expr, EMUL, EADD, ESUB) && TYPE_IS_8BYTES(expr->rtype)) - Optimize64bitMath(expr); - if (type) { - if ( - ENODE_IS(expr->data.diadic.left, ETYPCON) && - IS_TYPE_INT_OR_ENUM(expr->data.diadic.left->rtype) && - IS_TYPE_INT_OR_ENUM(expr->data.diadic.left->data.monadic->rtype) && - expr->data.diadic.left->data.monadic->rtype->size >= type->size && - !TYPE_IS_8BYTES(expr->data.diadic.left->data.monadic->rtype) - ) - expr->data.diadic.left = expr->data.diadic.left->data.monadic; - - if ( - ENODE_IS(expr->data.diadic.right, ETYPCON) && - IS_TYPE_INT_OR_ENUM(expr->data.diadic.right->rtype) && - IS_TYPE_INT_OR_ENUM(expr->data.diadic.right->data.monadic->rtype) && - expr->data.diadic.right->data.monadic->rtype->size >= type->size && - !TYPE_IS_8BYTES(expr->data.diadic.right->data.monadic->rtype) - ) - expr->data.diadic.right = expr->data.diadic.right->data.monadic; - - expr->rtype = type; - } - break; - - case ETYPCON: - tmpexpr = expr->data.monadic; - if ((IS_TYPE_INT_OR_ENUM(expr->rtype) && expr->rtype->size < 4) && IS_TYPE_INT_OR_ENUM(tmpexpr->rtype) && !TYPE_IS_8BYTES(tmpexpr->rtype)) { - expandTOCexpression(tmpexpr, expr->rtype, 0); - } else { - expandTOCexpression(tmpexpr, NULL, expr->rtype->type == TYPEVOID); - } - - expr->hascall = tmpexpr->hascall; - if (IS_TYPE_INT_OR_ENUM(tmpexpr->rtype) && IS_TYPE_FLOAT(expr->rtype)) - uses_globals = 1; - - if ((TYPE_IS_8BYTES(tmpexpr->rtype) && IS_TYPE_FLOAT(expr->rtype)) || (TYPE_IS_8BYTES(expr->rtype) && IS_TYPE_FLOAT(tmpexpr->rtype))) { - uses_globals = 1; - expr->hascall = 1; - requires_frame = 1; - makes_call = 1; - } - - if (IS_TYPE_FLOAT(tmpexpr->rtype)) { - if (is_unsigned(expr->rtype) && expr->rtype->size == 4) { - expr->hascall = 1; - requires_frame = 1; - makes_call = 1; - } else { - uses_globals = 1; - } - } - - if (IS_TYPE_VECTOR(expr->rtype) && !IS_TYPE_VECTOR(tmpexpr->rtype)) - PPCError_Error(PPCErrorStr114); - break; - - case EPOSTINC: - if (!expr->ignored) { - if (IS_TYPE_FLOAT(expr->data.monadic->rtype) && is_unsigned(expr->rtype)) - uses_globals = 1; - expandTOCexpression(expr->data.monadic, NULL, 0); - expr->hascall = expr->data.monadic->hascall; - break; - } - expr->type = EPREINC; - case EPREINC: - rewrite_preincdec(expr); - rewrite_opassign(expr, EADD); - goto opassign_common; - - case EPOSTDEC: - if (!expr->ignored) { - if (IS_TYPE_FLOAT(expr->data.monadic->rtype) && is_unsigned(expr->rtype)) - uses_globals = 1; - expandTOCexpression(expr->data.monadic, NULL, 0); - expr->hascall = expr->data.monadic->hascall; - break; - } - expr->type = EPREDEC; - case EPREDEC: - rewrite_preincdec(expr); - rewrite_opassign(expr, ESUB); - goto opassign_common; - - case ELOGNOT: - if (!ENODE_IS(expr->data.monadic, ELOGNOT) && !ENODE_IS2(expr->data.monadic, ELAND, ELOR) && !ENODE_IS_RANGE(expr->data.monadic, ELESS, ENOTEQU)) - expr->data.monadic = comparewithzero(expr->data.monadic); - case EMONMIN: - case EBINNOT: - tmpexpr = expr->data.monadic; - expandTOCexpression(tmpexpr, type, 0); - expr->hascall = tmpexpr->hascall; - if (type && ENODE_IS(expr->data.monadic, ETYPCON)) { - if (IS_TYPE_INT_OR_ENUM(expr->data.monadic->rtype) && IS_TYPE_INT_OR_ENUM(expr->data.monadic->data.monadic->rtype)) { - if (expr->data.monadic->data.monadic->rtype->size >= type->size) { - expr->data.monadic = expr->data.monadic->data.monadic; - expr->rtype = type; - } - } - } - break; - - case EINDIRECT: - case EFORCELOAD: - case EBITFIELD: - tmpexpr = expr->data.monadic; - expandTOCexpression(tmpexpr, NULL, 0); - expr->hascall = tmpexpr->hascall; - break; - - case EDEFINE: - tmpexpr = expr->data.monadic; - expandTOCexpression(tmpexpr, NULL, 0); - expr->hascall = tmpexpr->hascall; - break; - - case EREUSE: - expr->hascall = expr->data.monadic->hascall; - break; - - case ENULLCHECK: - expandTOCexpression(expr->data.diadic.left, NULL, 0); - expandTOCexpression(expr->data.diadic.right, NULL, 0); - expr->hascall = expr->data.diadic.left->hascall | expr->data.diadic.right->hascall; - break; - - case EPRECOMP: - expr->hascall = 0; - break; - - case ELABEL: - obj = createcodelabel(expr->data.label); - newexpr = lalloc(sizeof(ENode)); - memclrw(newexpr, sizeof(ENode)); - newexpr->type = EOBJREF; - newexpr->cost = 0; - newexpr->data.objref = obj; - newexpr->rtype = CDecl_NewPointerType(obj->type); - - expr->type = EINDIRECT; - expr->cost = 1; - expr->data.monadic = newexpr; - expr->hascall = 0; - break; - } -} - -static void checkexceptionreferences(ExceptionAction *action) { - for (; action; action = action->prev) { - switch (action->type) { - case EAT_DESTROYLOCAL: - referenceexception(action->data.destroy_local.local); - break; - case EAT_DESTROYLOCALCOND: - referenceexception(action->data.destroy_local_cond.local); - referenceexception(action->data.destroy_local_cond.cond); - break; - case EAT_DESTROYLOCALOFFSET: - referenceexception(action->data.destroy_local_offset.local); - break; - case EAT_DESTROYLOCALPOINTER: - referenceexception(action->data.destroy_local_pointer.pointer); - break; - case EAT_DESTROYLOCALARRAY: - referenceexception(action->data.destroy_local_array.localarray); - break; - case EAT_DESTROYBASE: - referenceexception(action->data.destroy_member.objectptr); // wrong union? - break; - case EAT_DESTROYPARTIALARRAY: - referenceexception(action->data.destroy_partial_array.arraypointer); - referenceexception(action->data.destroy_partial_array.arraycounter); - referenceexception(action->data.destroy_partial_array.element_size); - break; - case EAT_DESTROYMEMBER: - referenceexception(action->data.destroy_member.objectptr); - break; - case EAT_DESTROYMEMBERCOND: - referenceexception(action->data.destroy_member_cond.objectptr); - referenceexception(action->data.destroy_member_cond.cond); - break; - case EAT_DESTROYMEMBERARRAY: - referenceexception(action->data.destroy_member_array.objectptr); - break; - case EAT_DELETEPOINTER: - case EAT_DELETELOCALPOINTER: - referenceexception(action->data.delete_pointer.pointerobject); - break; - case EAT_DELETEPOINTERCOND: - referenceexception(action->data.delete_pointer_cond.pointerobject); - referenceexception(action->data.delete_pointer_cond.cond); - break; - case EAT_CATCHBLOCK: - referenceexception(action->data.catch_block.catch_object); - referenceexception(action->data.catch_block.catch_info_object); - break; - case EAT_ACTIVECATCHBLOCK: - referenceexception(action->data.active_catch_block.catch_info_object); - break; - } - } -} - -void expandTOCreferences(Statement **stmts) { - Statement *stmt; - IAOperand *op; - int i; - InlineAsm *ia; - VarInfo *vi; - - codelabellist = NULL; - exceptionlist = NULL; - - for (stmt = *stmts; stmt; stmt = stmt->next) { - curstmtvalue = stmt->value; - if (stmt->flags & StmtFlag_1) { - has_catch_blocks = 1; - dynamic_stack = 1; - requires_frame = 1; - } - - switch (stmt->type) { - case ST_EXPRESSION: - expandTOCexpression(stmt->expr, NULL, 1); - if (stmt->expr->type == ETYPCON && IS_TYPE_VOID(stmt->expr->rtype)) - stmt->expr = stmt->expr->data.monadic; - break; - case ST_GOTOEXPR: - expandTOCexpression(stmt->expr, NULL, 0); - break; - case ST_IFGOTO: - case ST_IFNGOTO: - if (stmt->expr->type < ELESS || stmt->expr->type > ENOTEQU) - stmt->expr = comparewithzero(stmt->expr); - expandTOCexpression(stmt->expr, NULL, 0); - break; - case ST_RETURN: - if (!stmt->expr) - continue; - expandTOCexpression( - stmt->expr, NULL, - IS_TYPE_ARRAY(stmt->expr->rtype) || IS_TYPE_NONVECTOR_STRUCT(stmt->expr->rtype) || IS_TYPE_CLASS(stmt->expr->rtype) || - IS_TYPE_12BYTES_MEMBERPOINTER(stmt->expr->rtype)); - break; - case ST_SWITCH: - uses_globals = 1; - expandTOCexpression(stmt->expr, NULL, 0); - break; - case ST_ENDCATCHDTOR: - requires_frame = 1; - makes_call = 1; - break; - case ST_ASM: - if ((ia = (InlineAsm *) stmt->expr)) { - if (ia->flags & IAFlag1) { - if (ia->opcode == IADirective_FrFree) - requires_frame = 1; - } else { - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - if (op->type == IAOpnd_Reg) { - if (!op->u.reg.object) { - if (op->u.reg.num == INVALID_PIC_REG) - uses_globals = 1; - else if (op->u.reg.effect & EffectWrite) - asm_used_register(op->u.reg.rclass, op->u.reg.num); - } else if ((vi = Registers_GetVarInfo(op->u.reg.object))) { - vi->flags |= VarInfoFlag40; - } - } else if (op->type == IAOpnd_3) { - uses_globals = 1; - } - } - - if (ia->flags & IAFlag2) - makes_call = 1; - } - } - break; - } - - checkexceptionreferences(stmt->dobjstack); - } -} - -void resetTOCvarinfo(void) { - ObjectList *list; - - for (list = toclist; list; list = list->next) - list->object->u.toc.info = CodeGen_GetNewVarInfo(); -} - -Boolean needdescriptor(void) { - // completely unused, dunno what args this might take - return 0; -} - -Object *createstaticinitobject(void) { - char buf[100]; - char *p; - Str255 fname; - TypeFunc *tfunc; - Object *obj; - - COS_FileGetFSSpecInfo(&cparamblkptr->sourcefile, NULL, NULL, fname); - sprintf(buf, "__sinit_%*.*s", -fname[0], fname[0], &fname[1]); - for (p = &buf[1]; *p; p++) { - if (*p == '.') - *p = '_'; - } - - tfunc = galloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - tfunc->type = TYPEFUNC; - tfunc->functype = &stvoid; - tfunc->args = NULL; - tfunc->flags = FUNC_DEFINED; - - obj = galloc(sizeof(Object)); - memclrw(obj, sizeof(Object)); - obj->otype = OT_OBJECT; - obj->type = (Type *) tfunc; - obj->name = GetHashNameNodeExport(buf); - obj->sclass = TK_STATIC; - obj->datatype = DFUNC; - - return obj; -} - -static void estimate_func_param_size(ENode *node) { - SInt32 work; - ENodeList *list; - SInt32 align; - - work = 0; - for (list = node->data.funccall.args; list; list = list->next) { - align = ~7 & (CMach_ArgumentAlignment(list->node->rtype) + 7); - work += ~(align - 1) & (list->node->rtype->size + align - 1); - } - - estimate_out_param_size(work); -} |