summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/TOC.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/unsorted/TOC.c')
-rw-r--r--compiler_and_linker/unsorted/TOC.c2272
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);
-}