summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted')
-rw-r--r--compiler_and_linker/unsorted/Alias.c747
-rw-r--r--compiler_and_linker/unsorted/CABI.c2033
-rw-r--r--compiler_and_linker/unsorted/CBrowse.c737
-rw-r--r--compiler_and_linker/unsorted/CClass.c2312
-rw-r--r--compiler_and_linker/unsorted/CCompiler.c2
-rw-r--r--compiler_and_linker/unsorted/CDecl.c4845
-rw-r--r--compiler_and_linker/unsorted/CError.c1098
-rw-r--r--compiler_and_linker/unsorted/CException.c2183
-rw-r--r--compiler_and_linker/unsorted/CExpr.c4971
-rw-r--r--compiler_and_linker/unsorted/CExpr2.c4206
-rw-r--r--compiler_and_linker/unsorted/CExprConvMatch.c2518
-rw-r--r--compiler_and_linker/unsorted/CFunc.c3224
-rw-r--r--compiler_and_linker/unsorted/CIRTransform.c534
-rw-r--r--compiler_and_linker/unsorted/CInit.c3082
-rw-r--r--compiler_and_linker/unsorted/CInline.c4206
-rw-r--r--compiler_and_linker/unsorted/CMachine.c1488
-rw-r--r--compiler_and_linker/unsorted/CMangler.c713
-rw-r--r--compiler_and_linker/unsorted/COptimizer.c1831
-rw-r--r--compiler_and_linker/unsorted/CParser.c3477
-rw-r--r--compiler_and_linker/unsorted/CPrec.c3482
-rw-r--r--compiler_and_linker/unsorted/CPreprocess.c676
-rw-r--r--compiler_and_linker/unsorted/CRTTI.c940
-rw-r--r--compiler_and_linker/unsorted/CSOM.c2069
-rw-r--r--compiler_and_linker/unsorted/CTemplateClass.c1632
-rw-r--r--compiler_and_linker/unsorted/CTemplateFunc.c1383
-rw-r--r--compiler_and_linker/unsorted/CTemplateNew.c1880
-rw-r--r--compiler_and_linker/unsorted/CTemplateTools.c1962
-rw-r--r--compiler_and_linker/unsorted/CodeGen.c2437
-rw-r--r--compiler_and_linker/unsorted/CodeMotion.c906
-rw-r--r--compiler_and_linker/unsorted/Coloring.c268
-rw-r--r--compiler_and_linker/unsorted/ConstantPropagation.c643
-rw-r--r--compiler_and_linker/unsorted/DumpIR.c (renamed from compiler_and_linker/unsorted/uDump.c)2
-rw-r--r--compiler_and_linker/unsorted/Exceptions.c857
-rw-r--r--compiler_and_linker/unsorted/FuncLevelAsmPPC.c393
-rw-r--r--compiler_and_linker/unsorted/FunctionCalls.c642
-rw-r--r--compiler_and_linker/unsorted/GCCInlineAsm.c230
-rw-r--r--compiler_and_linker/unsorted/IROUseDef.c1432
-rw-r--r--compiler_and_linker/unsorted/InlineAsm.c680
-rw-r--r--compiler_and_linker/unsorted/InlineAsmPPC.c2586
-rw-r--r--compiler_and_linker/unsorted/InstrSelection.c5348
-rw-r--r--compiler_and_linker/unsorted/InterferenceGraph.c364
-rw-r--r--compiler_and_linker/unsorted/Intrinsics.c4894
-rw-r--r--compiler_and_linker/unsorted/IrOptimizer.c400
-rw-r--r--compiler_and_linker/unsorted/IroBitVect.c112
-rw-r--r--compiler_and_linker/unsorted/IroCSE.c1038
-rw-r--r--compiler_and_linker/unsorted/IroDump.c660
-rw-r--r--compiler_and_linker/unsorted/IroEmptyLoop.c560
-rw-r--r--compiler_and_linker/unsorted/IroEval.c914
-rw-r--r--compiler_and_linker/unsorted/IroExprRegeneration.c1531
-rw-r--r--compiler_and_linker/unsorted/IroFlowgraph.c439
-rw-r--r--compiler_and_linker/unsorted/IroJump.c267
-rw-r--r--compiler_and_linker/unsorted/IroLinearForm.c1797
-rw-r--r--compiler_and_linker/unsorted/IroLoop.c2324
-rw-r--r--compiler_and_linker/unsorted/IroMalloc.c564
-rw-r--r--compiler_and_linker/unsorted/IroPointerAnalysis.c5734
-rw-r--r--compiler_and_linker/unsorted/IroPointerAnalysisADTs.c2736
-rw-r--r--compiler_and_linker/unsorted/IroPropagate.c593
-rw-r--r--compiler_and_linker/unsorted/IroRangePropagation.c774
-rw-r--r--compiler_and_linker/unsorted/IroSubable.c160
-rw-r--r--compiler_and_linker/unsorted/IroTransform.c2794
-rw-r--r--compiler_and_linker/unsorted/IroUnrollLoop.c2305
-rw-r--r--compiler_and_linker/unsorted/IroUtil.c1262
-rw-r--r--compiler_and_linker/unsorted/IroVars.c1430
-rw-r--r--compiler_and_linker/unsorted/LoopDetection.c885
-rw-r--r--compiler_and_linker/unsorted/LoopOptimization.c1553
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation601.c552
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation603.c626
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation603e.c650
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation604.c670
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation7400.c744
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation750.c678
-rw-r--r--compiler_and_linker/unsorted/MachineSimulation821.c615
-rw-r--r--compiler_and_linker/unsorted/MachineSimulationAltiVec.c752
-rw-r--r--compiler_and_linker/unsorted/ObjGenMachO.c4
-rw-r--r--compiler_and_linker/unsorted/Operands.c1040
-rw-r--r--compiler_and_linker/unsorted/PCodeAssembly.c1613
-rw-r--r--compiler_and_linker/unsorted/PCodeInfo.c1354
-rw-r--r--compiler_and_linker/unsorted/PCodeListing.c536
-rw-r--r--compiler_and_linker/unsorted/PCodeUtilities.c345
-rw-r--r--compiler_and_linker/unsorted/PPCError.c70
-rw-r--r--compiler_and_linker/unsorted/Peephole.c2753
-rw-r--r--compiler_and_linker/unsorted/RegisterInfo.c381
-rw-r--r--compiler_and_linker/unsorted/Scheduler.c547
-rw-r--r--compiler_and_linker/unsorted/SpillCode.c452
-rw-r--r--compiler_and_linker/unsorted/StackFrame.c1252
-rw-r--r--compiler_and_linker/unsorted/StrengthReduction.c751
-rw-r--r--compiler_and_linker/unsorted/StructMoves.c792
-rw-r--r--compiler_and_linker/unsorted/Switch.c518
-rw-r--r--compiler_and_linker/unsorted/TOC.c2272
-rw-r--r--compiler_and_linker/unsorted/ValueNumbering.c661
-rw-r--r--compiler_and_linker/unsorted/VectorArraysToRegs.c548
91 files changed, 4 insertions, 131917 deletions
diff --git a/compiler_and_linker/unsorted/Alias.c b/compiler_and_linker/unsorted/Alias.c
deleted file mode 100644
index 8223bf4..0000000
--- a/compiler_and_linker/unsorted/Alias.c
+++ /dev/null
@@ -1,747 +0,0 @@
-#include "compiler/Alias.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/CMachine.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CopyPropagation.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/ValueNumbering.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-static Alias *aliases;
-static int n_aliases;
-static int n_gathered_aliases;
-static Alias *alias_hash[997];
-Alias *worst_case;
-Object worst_case_obj;
-
-static TypePointer worst_case_memory_type = {
- TYPEARRAY,
- 0xFFFFFF,
- TYPE(&stchar)
-};
-
-static Boolean is_safe_const(Object *obj) {
- Type *type;
-
- type = obj->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (TYPE_FITS_IN_REGISTER(type) || IS_TYPE_VECTOR(type) || IS_TYPE_FLOAT(type) || IS_TYPE_STRUCT(type))
- return is_const_object(obj);
-
- if (IS_TYPE_CLASS(type))
- return is_const_object(obj) && CClass_IsPODClass(TYPE_CLASS(type));
-
- return 0;
-}
-
-void initialize_aliases(void) {
- int i;
-
- memclrw(&worst_case_obj, sizeof(Object));
- worst_case_obj.otype = OT_OBJECT;
- worst_case_obj.type = TYPE(&worst_case_memory_type);
- worst_case_obj.datatype = DDATA;
- worst_case_obj.name = GetHashNameNodeExport("@worst_case@");
-
- aliases = NULL;
- n_aliases = 0;
- n_gathered_aliases = 0;
- for (i = 0; i < 997; i++)
- alias_hash[i] = NULL;
-
- worst_case = make_alias_set();
- add_alias_member(worst_case, make_alias(&worst_case_obj, 0, 0));
-}
-
-static UInt32 hash_alias(Object *object, SInt32 offset, SInt32 size) {
- return (UInt32) (object->name->hashval * offset * size) % 997;
-}
-
-static Alias *create_alias(AliasType type, Object *object, SInt32 offset, SInt32 size, Boolean addToHash) {
- Alias *alias;
- UInt32 hash;
-
- alias = lalloc(sizeof(Alias));
- memclrw(alias, sizeof(Alias));
- alias->type = type;
- alias->index = n_aliases++;
- alias->next = aliases;
- aliases = alias;
- alias->object = object;
- alias->offset = offset;
- alias->size = size;
-
- if (addToHash) {
- hash = hash_alias(object, offset, size);
- alias->hashNext = alias_hash[hash];
- alias_hash[hash] = alias;
- }
-
- return alias;
-}
-
-static Alias *lookup_alias(Object *object, SInt32 offset, SInt32 size) {
- Alias *scan;
-
- for (scan = alias_hash[hash_alias(object, offset, size)]; scan; scan = scan->hashNext) {
- if (scan->object == object && scan->offset == offset && scan->size == size)
- return scan;
- }
-
- return NULL;
-}
-
-Alias *make_alias(Object *object, SInt32 offset, SInt32 size) {
- Alias *alias;
- Alias *alias2;
-
- if (!offset && !size)
- size = object->type->size;
-
- alias = lookup_alias(object, offset, size);
- if (!alias) {
- if (offset > 0 || size != object->type->size) {
- alias2 = make_alias(object, 0, object->type->size);
- alias = create_alias(AliasType1, object, offset, size, 1);
- add_alias_member(alias2, alias);
- } else {
- alias = create_alias(AliasType0, object, offset, size, 1);
- }
-
- switch (object->datatype) {
- case DLOCAL:
- case DNONLAZYPTR:
- break;
- default:
- if (!is_safe_const(object))
- add_alias_member(worst_case, make_alias(object, 0, 0));
- }
- }
-
- if (offset > object->type->size)
- return NULL;
- else
- return alias;
-}
-
-Alias *make_alias_set(void) {
- return create_alias(AliasType2, NULL, 0, 0, 0);
-}
-
-void add_alias_member(Alias *parent, Alias *child) {
- AliasMember *member;
-
- if (child->type == AliasType2) {
- for (member = child->parents; member; member = member->nextParent)
- add_alias_member(parent, member->child);
- } else {
- if (parent == worst_case && child->type == AliasType1)
- child = make_alias(child->object, 0, 0);
-
- for (member = parent->parents; member; member = member->nextParent) {
- if (member->child == child)
- return;
- }
-
- member = lalloc(sizeof(AliasMember));
- member->parent = parent;
- member->child = child;
- member->nextParent = parent->parents;
- parent->parents = member;
- member->nextChild = child->children;
- child->children = member;
- }
-}
-
-Alias *make_alias_set_from_IR(void) {
- CError_FATAL(333);
- return NULL;
-}
-
-static Boolean aliases_overlap(Alias *a, Alias *b) {
- return (
- a->offset == b->offset ||
- (a->offset > b->offset && a->offset < (b->offset + b->size)) ||
- (b->offset > a->offset && b->offset < (a->offset + a->size))
- );
-}
-
-static int is_address_load(PCode *pcode) {
- Object *obj;
-
- switch (pcode->op) {
- case PC_LWZ:
- if (pcode->args[2].kind == PCOp_MEMORY && pcode->args[2].data.mem.obj->datatype == DNONLAZYPTR)
- return 1;
- break;
- case PC_LBZU:
- case PC_LBZUX:
- case PC_LHZU:
- case PC_LHZUX:
- case PC_LHAU:
- case PC_LHAUX:
- case PC_LWZU:
- case PC_LWZUX:
- case PC_STBU:
- case PC_STBUX:
- case PC_STHU:
- case PC_STHUX:
- case PC_STWU:
- case PC_STWUX:
- return 1;
- case PC_ADDI:
- case PC_ADDIS:
- if (pcode->args[0].data.reg.reg < n_real_registers[RegClass_GPR]) {
- if (pcode->args[2].kind == PCOp_MEMORY) {
- obj = pcode->args[2].data.mem.obj;
- if (obj->datatype == DLOCAL && !is_safe_const(obj))
- add_alias_member(worst_case, make_alias(obj, 0, 0));
- return 0;
- }
- } else {
- return 1;
- }
- break;
- case PC_ADD:
- return 1;
- }
-
- return 0;
-}
-
-static int addresspropagatestouse(int candidateID, int useID) {
- PCode *candidate_pcode; // r30
- PCode *use_pcode; // r29
- int reg; // r28
- short reg2;
- Object *object; // r27
- SInt32 offset; // r26
- Alias *alias; // r25
- Boolean flag24; // r24
- SInt32 size; // r23
- Alias *aliasSet; // r22
- int i;
- PCode *scan;
- PCodeArg *op;
-
- candidate_pcode = Candidates[candidateID].pcode;
- use_pcode = Uses[useID].pcode;
- flag24 = 0;
- size = 1;
- reg = candidate_pcode->args[0].data.reg.reg;
-
- if (candidate_pcode->alias && (candidate_pcode->alias->type == AliasType0 || candidate_pcode->alias->type == AliasType1)) {
- object = candidate_pcode->alias->object;
- offset = candidate_pcode->alias->offset;
- if (offset == 0 && candidate_pcode->alias->size == object->type->size)
- flag24 = 1;
- } else if (candidate_pcode->args[2].kind == PCOp_MEMORY) {
- object = candidate_pcode->args[2].data.mem.obj;
- if (candidate_pcode->op == PC_ADDIS)
- offset = candidate_pcode->args[2].data.mem.offset << 16;
- else
- offset = candidate_pcode->args[2].data.mem.offset;
- } else {
- return 0;
- }
-
- CError_ASSERT(478, object->otype == OT_OBJECT);
-
- if ((candidate_pcode->flags & (fIsRead | fIsWrite)) && (candidate_pcode->flags & fUpdatesPtr)) {
- reg = candidate_pcode->args[1].data.reg.reg;
- offset = 0;
- flag24 = 1;
- } else if (candidate_pcode->op == PC_LWZ) {
- if (object->datatype != DNONLAZYPTR)
- return 0;
-
- object = object->u.var.realObj;
- CError_ASSERT(495, object->otype == OT_OBJECT);
- offset = 0;
- } else if (candidate_pcode->op == PC_ADDI) {
- if (!candidate_pcode->alias && object)
- candidate_pcode->alias = make_alias(object, offset, 1);
- } else if (candidate_pcode->op == PC_ADDIS) {
- if (!candidate_pcode->alias && object)
- candidate_pcode->alias = make_alias(object, offset, 1);
- } else if (candidate_pcode->op == PC_ADD) {
- offset = 0;
- flag24 = 1;
- } else {
- CError_FATAL(509);
- }
-
- if (
- !(use_pcode->flags & (fIsRead | fIsWrite)) &&
- use_pcode->op != PC_ADDI &&
- use_pcode->op != PC_ADD &&
- use_pcode->op != PC_ADDIS
- ) {
- if (object->datatype == DLOCAL && !is_safe_const(object))
- add_alias_member(worst_case, make_alias(object, 0, 0));
- return 1;
- }
-
- if (
- (use_pcode->flags & (fIsWrite | fPCodeFlag40000)) &&
- use_pcode->args[0].kind == PCOp_REGISTER &&
- use_pcode->args[0].arg == RegClass_GPR &&
- use_pcode->args[0].data.reg.reg == reg &&
- object->datatype == DLOCAL &&
- !is_safe_const(object)
- )
- add_alias_member(worst_case, make_alias(object, 0, 0));
-
- if (use_pcode->argCount < 3)
- return 1;
-
- CError_ASSERT(543, use_pcode->args[1].kind == PCOp_REGISTER);
-
- if (candidate_pcode->block == use_pcode->block && precedes(candidate_pcode, use_pcode)) {
- for (scan = candidate_pcode->nextPCode; scan && scan != use_pcode; scan = scan->nextPCode) {
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite) &&
- op->data.reg.reg == reg)
- return 1;
- }
- }
- } else {
- if (!bitvectorgetbit(candidateID, propinfo[use_pcode->block->blockIndex].vec8)) {
- if (bitvectorgetbit(candidate_pcode->defID, usedefinfo[use_pcode->block->blockIndex].defvec8)) {
- for (scan = use_pcode->block->firstPCode; scan && scan != use_pcode; scan = scan->nextPCode) {
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite) &&
- op->data.reg.reg == reg)
- return 1;
- }
- }
- } else {
- return 1;
- }
- }
-
- for (scan = use_pcode->block->firstPCode; scan; scan = scan->nextPCode) {
- if (scan == use_pcode)
- break;
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite) &&
- op->data.reg.reg == reg)
- return 1;
- }
- }
- }
-
- CError_ASSERT(598, object != NULL);
-
- if (use_pcode->op == PC_ADDI || use_pcode->op == PC_ADD || use_pcode->op == PC_ADDIS) {
- if (use_pcode->args[0].data.reg.reg < n_real_registers[RegClass_GPR] && !is_safe_const(object))
- add_alias_member(worst_case, make_alias(object, 0, 0));
- }
-
- if (use_pcode->flags & (fIsRead | fIsWrite))
- size = nbytes_loaded_or_stored_by(use_pcode);
-
- if (use_pcode->args[2].kind == PCOp_REGISTER) {
- if (use_pcode->args[1].data.reg.reg == 0) {
- if (use_pcode->args[2].data.reg.reg == reg)
- alias = make_alias(object, offset, size);
- } else {
- if (use_pcode->args[1].data.reg.reg == reg)
- reg2 = use_pcode->args[2].data.reg.reg;
- else if (use_pcode->args[2].data.reg.reg == reg)
- reg2 = use_pcode->args[1].data.reg.reg;
- else
- return 1;
-
- for (scan = use_pcode->prevPCode; scan; scan = scan->prevPCode) {
- if (scan->op == PC_LI && scan->args[0].data.reg.reg == reg2)
- break;
-
- for (i = 0; i < scan->argCount; i++) {
- if (scan->args[i].kind == PCOp_REGISTER &&
- scan->args[i].arg == RegClass_GPR &&
- scan->args[i].data.reg.reg == reg2 &&
- (scan->args[i].data.reg.effect & EffectWrite)) {
- scan = NULL;
- break;
- }
- }
-
- if (!scan)
- break;
- }
-
- if (scan) {
- offset += scan->args[1].data.mem.offset;
- alias = make_alias(object, offset, size);
- } else {
- alias = make_alias(object, 0, 0);
- }
- }
- } else {
- if (use_pcode->args[1].kind != PCOp_REGISTER ||
- use_pcode->args[1].arg != RegClass_GPR ||
- use_pcode->args[1].data.reg.reg != reg)
- return 1;
-
- if (use_pcode->args[1].data.reg.effect & EffectWrite) {
- alias = make_alias(object, 0, 0);
- } else if (use_pcode->args[2].kind == PCOp_IMMEDIATE) {
- if (use_pcode->op == PC_ADDIS) {
- offset += use_pcode->args[2].data.imm.value << 16;
- alias = make_alias(object, offset, 1);
- } else {
- offset += use_pcode->args[2].data.imm.value;
- alias = make_alias(object, offset, size);
- }
- } else {
- return 1;
- }
- }
-
- if (flag24)
- alias = make_alias(object, 0, 0);
-
- if (!alias)
- return 1;
-
- if (!use_pcode->alias) {
- if (
- use_pcode->op == PC_ADDI ||
- use_pcode->op == PC_ADD ||
- use_pcode->op == PC_ADDIS ||
- ((candidate_pcode->flags & (fIsRead | fIsWrite)) && (candidate_pcode->flags & fUpdatesPtr))
- )
- recursive_propagation = 1;
- }
-
- if (use_pcode->alias) {
- if (use_pcode->alias == worst_case) {
- add_alias_member(worst_case, make_alias(object, 0, 0));
- } else if (use_pcode->alias == alias) {
- return 1;
- } else if (use_pcode->alias->type == AliasType0 || use_pcode->alias->type == AliasType1) {
- if (object == use_pcode->alias->object) {
- use_pcode->alias = make_alias(object, 0, 0);
- } else {
- aliasSet = make_alias_set();
- if (
- use_pcode->op == PC_ADDI ||
- use_pcode->op == PC_ADD ||
- use_pcode->op == PC_ADDIS ||
- ((use_pcode->flags & (fIsRead | fIsWrite)) && (use_pcode->flags & fUpdatesPtr))
- ) {
- if (alias->type == AliasType2)
- add_alias_member(worst_case, alias);
- else
- add_alias_member(worst_case, make_alias(use_pcode->alias->object, 0, 0));
- }
- add_alias_member(aliasSet, use_pcode->alias);
- add_alias_member(aliasSet, alias);
- use_pcode->alias = aliasSet;
- }
- } else {
- add_alias_member(use_pcode->alias, alias);
- }
- } else {
- use_pcode->alias = alias;
- }
-
- propagated_instructions = 1;
- return 1;
-}
-
-static void finishpropagatealiases(int id) {
- propagated_instructions = 1;
-}
-
-static Propagation alias_prop = {
- &is_address_load,
- &addresspropagatestouse,
- &finishpropagatealiases,
- "ALIAS",
- "ALIASES",
- "A%" PRId32,
- 1
-};
-
-static void propagatealiasinfo(Object *proc) {
- propagateinstructions(proc, &alias_prop, (copts.optimizationlevel >= 4) ? 4 : 1, 1);
-}
-
-void gather_alias_info(void) {
- UInt32 *myvec; // r31
- Alias *alias; // r22
- AliasMember *member;
- AliasMember *member2;
- PCodeBlock *block; // r21
- PCode *pcode; // r20
- PCodeArg *op; // r19
- RegUseOrDef *list; // r18
- int i; // r17
- Alias *alias_choice; // r16
- int aliases_idx; // r15 (helper in r23)
- PCode *defpcode; // r14
- Alias *alias_array[3];
- UseOrDef *def;
- int defID;
-
- if (coloring) {
- propagatealiasinfo(gFunction);
- myvec = oalloc(4 * ((number_of_Defs + 31) >> 5));
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- bitvectorcopy(myvec, usedefinfo[block->blockIndex].defvec8, number_of_Defs);
-
- for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
- if (pcode->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- if (!pcode->alias) {
- pcode->alias = worst_case;
- } else {
- if ((pcode->alias->type == AliasType0 || pcode->alias->type == AliasType1) &&
- pcode->alias->size == nbytes_loaded_or_stored_by(pcode)) {
- pcode->flags &= ~fIsPtrOp;
- } else {
- pcode->flags |= fIsPtrOp;
- }
-
- if (pcode->alias != worst_case) {
- aliases_idx = 0;
- alias_choice = NULL;
- op = pcode->args;
- for (i = 0; i < pcode->argCount; i++, op++) {
- if (
- (!(pcode->flags & (fIsWrite | fPCodeFlag40000)) || op != pcode->args) &&
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectRead)
- ) {
- alias_array[aliases_idx] = NULL;
- if (aliases_idx >= 2) {
- alias_choice = worst_case;
- break;
- }
- alias_array[aliases_idx] = pcode->alias;
-
- for (list = reg_Defs[RegClass_GPR][op->data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(list->id, myvec)) {
- defpcode = Defs[list->id].pcode;
- if (!defpcode->alias || !is_address_load(defpcode) || defpcode->alias == worst_case) {
- alias_array[aliases_idx] = worst_case;
- break;
- }
- }
- }
-
- aliases_idx++;
- }
- }
-
- if (!alias_choice) {
- if (aliases_idx > 0) {
- alias_choice = alias_array[0];
- if (aliases_idx == 2) {
- if (alias_array[0] != worst_case) {
- if (alias_array[1] != worst_case)
- alias_choice = worst_case;
- } else if (alias_array[1] != worst_case) {
- alias_choice = alias_array[1];
- }
- }
- }
-
- if (alias_choice == worst_case) {
- pcode->flags |= fIsPtrOp;
- if (pcode->alias->type == AliasType2)
- add_alias_member(worst_case, pcode->alias);
- else
- add_alias_member(worst_case, make_alias(pcode->alias->object, 0, 0));
- }
-
- if (alias_choice)
- pcode->alias = alias_choice;
- }
- }
- }
- } else {
- if ((pcode->flags & fIsCall) && !pcode->alias)
- pcode->alias = worst_case;
- }
-
- for (def = &Defs[defID = pcode->defID]; defID < number_of_Defs && def->pcode == pcode; defID++, def++) {
- if (def->v.kind == PCOp_REGISTER && def->v.arg == RegClass_GPR) {
- for (list = reg_Defs[RegClass_GPR][def->v.u.reg]; list; list = list->next)
- bitvectorclearbit(list->id, myvec);
- }
- bitvectorsetbit(defID, myvec);
- }
- }
- }
-
- freeoheap();
- } else {
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
- if ((pcode->flags & (fIsRead | fIsWrite | fIsCall | fPCodeFlag20000 | fPCodeFlag40000)) && !pcode->alias)
- pcode->alias = worst_case;
- }
- }
- }
-
- if (n_gathered_aliases != n_aliases) {
- for (alias = aliases; alias; alias = alias->next) {
- if (alias->type == AliasType2) {
- alias->vec24 = lalloc(4 * ((n_aliases + 31) >> 5));
- bitvectorinitialize(alias->vec24, n_aliases, 0);
- for (member = alias->parents; member; member = member->nextParent) {
- bitvectorsetbit(member->child->index, alias->vec24);
- for (member2 = member->child->parents; member2; member2 = member2->nextParent)
- bitvectorsetbit(member2->child->index, alias->vec24);
- }
- }
- }
- n_gathered_aliases = n_aliases;
- }
-}
-
-static Boolean may_alias_alias(Alias *a, Alias *b) {
- switch ((a->type * 3) + b->type) {
- case (AliasType0 * 3) + AliasType0:
- return a == b;
- case (AliasType0 * 3) + AliasType1:
- case (AliasType1 * 3) + AliasType0:
- return a->object == b->object;
- case (AliasType1 * 3) + AliasType1:
- return (a->object == b->object) && aliases_overlap(a, b);
- case (AliasType0 * 3) + AliasType2:
- case (AliasType1 * 3) + AliasType2:
- return bitvectorgetbit(a->index, b->vec24) != 0;
- case (AliasType2 * 3) + AliasType0:
- case (AliasType2 * 3) + AliasType1:
- return bitvectorgetbit(b->index, a->vec24) != 0;
- case (AliasType2 * 3) + AliasType2:
- return (a == b) || !bitvectorintersectionisempty(a->vec24, b->vec24, n_aliases);
- default:
- CError_FATAL(1054);
- return 1;
- }
-}
-
-Boolean may_alias(PCode *a, PCode *b) {
- return may_alias_alias(a->alias, b->alias);
-}
-
-Boolean uniquely_aliases(PCode *a, PCode *b) {
- if (may_alias_alias(a->alias, b->alias)) {
- if (
- a->alias->type != AliasType2 &&
- b->alias->type != AliasType2 &&
- a->alias &&
- b->alias &&
- a->alias->size == nbytes_loaded_or_stored_by(a) &&
- b->alias->size == nbytes_loaded_or_stored_by(b)
- )
- return 1;
- }
-
- return 0;
-}
-
-Boolean may_alias_worst_case(PCode *pcode) {
- return may_alias_alias(pcode->alias, worst_case);
-}
-
-Boolean may_alias_object(PCode *pcode, Object *object) {
- return may_alias_alias(pcode->alias, make_alias(object, 0, 0));
-}
-
-void initialize_alias_values(void) {
- Alias *alias;
-
- for (alias = aliases; alias; alias = alias->next) {
- alias->valuenumber = nextvaluenumber++;
- alias->valuepcode = NULL;
- }
-}
-
-void update_alias_value(Alias *alias, PCode *pcode) {
- AliasMember *member;
- AliasMember *member2;
- AliasMember *member3;
-
- switch (alias->type) {
- case AliasType0:
- killmemory(alias, pcode);
- for (member = alias->children; member; member = member->nextChild) {
- CError_ASSERT(1152, member->parent->type == AliasType2);
- killmemory(member->parent, NULL);
- }
- for (member = alias->parents; member; member = member->nextParent) {
- CError_ASSERT(1157, member->child->type == AliasType1);
- killmemory(member->child, NULL);
- for (member2 = member->child->children; member2; member2 = member2->nextChild) {
- if (member2->parent != alias) {
- CError_ASSERT(1163, member2->parent->type == AliasType2);
- killmemory(member2->parent, NULL);
- }
- }
- }
- break;
-
- case AliasType1:
- killmemory(alias, pcode);
- for (member = alias->children; member; member = member->nextChild) {
- killmemory(member->parent, NULL);
- if (member->parent->type == AliasType0) {
- for (member2 = member->parent->parents; member2; member2 = member2->nextParent) {
- if (member2->child != alias && aliases_overlap(alias, member2->child)) {
- killmemory(member2->child, NULL);
- }
- }
- }
- }
- break;
-
- case AliasType2:
- killmemory(alias, NULL);
- for (member = alias->parents; member; member = member->nextParent) {
- killmemory(member->child, NULL);
- for (member2 = member->child->children; member2; member2 = member2->nextChild) {
- if (member2->parent != alias)
- killmemory(member2->parent, NULL);
- }
- for (member3 = member->child->parents; member3; member3 = member3->nextParent) {
- killmemory(member3->child, NULL);
- for (member2 = member3->child->children; member2; member2 = member2->nextChild) {
- if (member2->parent != member->child)
- killmemory(member2->parent, NULL);
- }
- }
- }
- break;
- }
-}
-
-void update_all_alias_values(void) {
- Alias *alias;
-
- for (alias = aliases; alias; alias = alias->next)
- killmemory(alias, NULL);
-}
-
diff --git a/compiler_and_linker/unsorted/CABI.c b/compiler_and_linker/unsorted/CABI.c
deleted file mode 100644
index 2a88de1..0000000
--- a/compiler_and_linker/unsorted/CABI.c
+++ /dev/null
@@ -1,2033 +0,0 @@
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CSOM.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-typedef struct OffsetList {
- struct OffsetList *next;
- SInt32 offset;
-} OffsetList;
-
-static OffsetList *trans_vtboffsets;
-static BClassList cabi_pathroot;
-static BClassList *cabi_pathcur;
-static TypeClass *cabi_loop_class;
-static Boolean cabi_loop_construct;
-
-short CABI_GetStructResultArgumentIndex(TypeFunc *tfunc) {
- return 0;
-}
-
-Type *CABI_GetSizeTType(void) {
- return TYPE(&stunsignedlong);
-}
-
-Type *CABI_GetPtrDiffTType(void) {
- return TYPE(&stsignedlong);
-}
-
-SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) {
- SInt16 align = CMach_GetTypeAlign(type);
- if (align <= 1)
- return 0;
- else
- return (align - 1) & (align - ((size & (align - 1))));
-}
-
-void CABI_ReverseBitField(TypeBitfield *tbitfield) {
- UInt8 bits;
- UInt8 a;
- UInt8 b;
-
- switch (tbitfield->bitfieldtype->size) {
- case 1:
- bits = 8;
- break;
- case 2:
- bits = 16;
- break;
- case 4:
- bits = 32;
- break;
- case 8:
- bits = 64;
- break;
- default:
- CError_FATAL(172);
- }
-
- b = tbitfield->bitlength;
- a = tbitfield->offset;
- tbitfield->offset = (bits - a) - b;
-}
-
-static void CABI_AllocateZeroVTablePointer(void *unk, TypeClass *tclass) {
- ClassList *base;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual && base->base->vtable)
- return;
- }
-
- tclass->size += void_ptr.size;
-}
-
-static SInt32 CABI_GetBaseSize(TypeClass *tclass) {
- SInt32 size = tclass->size;
-
- if (copts.vbase_abi_v2 && tclass->vbases)
- return tclass->vbases->offset;
-
- return size;
-}
-
-static void CABI_AllocateBases(ClassLayout *layout, TypeClass *tclass) {
- Boolean flag;
- TypeClass *baseclass;
- ClassList *base;
- VClassList *vbase;
- SInt32 size;
-
- flag = 0;
- size = tclass->size;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual) {
- baseclass = base->base;
- if (!(baseclass->flags & CLASS_EMPTY)) {
- base->offset = size + CMach_MemberAlignValue(TYPE(baseclass), size);
- if (copts.vbase_abi_v2) {
- size = base->offset + CABI_GetBaseSize(baseclass);
- } else {
- size = base->offset + baseclass->size;
- for (vbase = baseclass->vbases; vbase; vbase = vbase->next)
- size -= vbase->base->size;
- }
- flag = 0;
- } else {
- if (flag)
- base->offset = ++size;
- else
- base->offset = size;
- flag = 1;
- }
- }
- }
-
- tclass->size = size;
-}
-
-static void CABI_AllocateVirtualBasePointers(ClassLayout *layout, TypeClass *tclass) {
- ClassList *base;
- SInt32 size;
-
- size = tclass->size;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->is_virtual) {
- base->offset = size + CMach_MemberAlignValue(TYPE(&void_ptr), size);
- size = base->offset + void_ptr.size;
- }
- }
-
- tclass->size = size;
-}
-
-static SInt32 CABI_GetMemberOffset(TypeClass *tclass, HashNameNode *name) {
- ObjMemberVar *ivar;
-
- if (!name)
- return 0;
-
- ivar = tclass->ivars;
- while (1) {
- if (ivar->name == name)
- return ivar->offset;
-
- if (!(ivar = ivar->next))
- CError_FATAL(362);
- }
-}
-
-static void CABI_AllocateMembers(ClassLayout *layout, TypeClass *tclass) {
- ObjMemberVar *ivar;
- SInt32 initialSize;
- SInt32 maxSize;
- TypeClass *unionClass;
- SInt32 unionStart;
- Boolean inAnonUnion;
- Boolean removeNoNameIvars;
-
- removeNoNameIvars = 0;
- initialSize = maxSize = tclass->size;
- CMach_StructLayoutInitOffset(maxSize);
-
- unionClass = NULL;
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (!ivar->anonunion) {
- if (!(ivar->offset & 0x80000000)) {
- if (tclass->mode == CLASS_MODE_UNION)
- CMach_StructLayoutInitOffset(initialSize);
-
- if (IS_TYPE_BITFIELD(ivar->type))
- ivar->offset = CMach_StructLayoutBitfield(TYPE_BITFIELD(ivar->type), ivar->qual);
- else
- ivar->offset = CMach_StructLayoutGetOffset(ivar->type, ivar->qual);
-
- if (tclass->mode == CLASS_MODE_UNION) {
- SInt32 tmp = CMach_StructLayoutGetCurSize();
- if (tmp > maxSize)
- maxSize = tmp;
- }
-
- unionClass = NULL;
- } else {
- CError_ASSERT(412, unionClass);
- ivar->offset = unionStart + CABI_GetMemberOffset(unionClass, ivar->name);
- if (!inAnonUnion)
- ivar->anonunion = 1;
- inAnonUnion = 0;
- }
-
- if (ivar->name == no_name_node || ivar->name == NULL)
- removeNoNameIvars = 1;
- } else {
- CError_ASSERT(422, IS_TYPE_CLASS(ivar->type));
-
- if (tclass->mode == CLASS_MODE_UNION)
- CMach_StructLayoutInitOffset(initialSize);
-
- unionStart = CMach_StructLayoutGetOffset(ivar->type, ivar->qual);
- unionClass = TYPE_CLASS(ivar->type);
- inAnonUnion = 1;
-
- if (tclass->mode == CLASS_MODE_UNION) {
- SInt32 tmp = CMach_StructLayoutGetCurSize();
- if (tmp > maxSize)
- maxSize = tmp;
- }
-
- removeNoNameIvars = 1;
- }
-
- if (layout->vtable_ivar == ivar)
- tclass->vtable->offset = ivar->offset;
- }
-
- if (removeNoNameIvars) {
- ObjMemberVar **ptr = &tclass->ivars;
- while (*ptr) {
- if ((*ptr)->name == NULL || (*ptr)->name == no_name_node)
- *ptr = (*ptr)->next;
- else
- ptr = &(*ptr)->next;
- }
- }
-
- if (tclass->mode == CLASS_MODE_UNION)
- tclass->size = maxSize;
- else
- tclass->size = CMach_StructLayoutGetCurSize();
-
- if (copts.reverse_bitfields) {
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (IS_TYPE_BITFIELD(ivar->type))
- CABI_ReverseBitField(TYPE_BITFIELD(ivar->type));
- }
- }
-}
-
-static void CABI_AllocateVirtualBases(ClassLayout *layout, TypeClass *tclass) {
- VClassList *vbase;
- SInt32 size;
-
- size = tclass->size;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- vbase->offset = size + CMach_MemberAlignValue(TYPE(vbase->base), size);
- size = vbase->offset + CABI_GetBaseSize(vbase->base);
-
- if (vbase->has_override)
- size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size) + 4;
- }
-
- tclass->size = size;
-}
-
-static Boolean CABI_FindZeroDeltaVPtr(TypeClass *tclass) {
- ClassList *base;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual && base->base->vtable && !base->offset) {
- tclass->vtable->offset = base->base->vtable->offset;
- return 1;
- }
- }
-
- return 0;
-}
-
-static Object *CABI_FindZeroVirtualBaseMember(TypeClass *tclass, Object *obj) {
- NameSpaceObjectList *nsol;
- ClassList *base;
- Object *chk;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual && !base->offset && !base->voffset && base->base->vtable) {
- for (nsol = CScope_FindName(base->base->nspace, obj->name); nsol; nsol = nsol->next) {
- chk = OBJECT(nsol->object);
- if (
- chk->otype == OT_OBJECT &&
- chk->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(chk->type), TYPE_FUNC(obj->type), 0) == 1
- )
- return chk;
- }
-
- if ((chk = CABI_FindZeroVirtualBaseMember(base->base, obj)))
- return chk;
- }
- }
-
- return NULL;
-}
-
-void CABI_AddVTable(TypeClass *tclass) {
- tclass->vtable = galloc(sizeof(VTable));
- memclrw(tclass->vtable, sizeof(VTable));
-}
-
-SInt32 CABI_GetVTableOffset(TypeClass *tclass) {
- return 0;
-}
-
-static SInt32 CABI_GetBaseVTableSize(TypeClass *tclass) {
- VClassList *vbase;
- SInt32 size;
-
- size = tclass->vtable->size;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base->vtable)
- size -= CABI_GetBaseVTableSize(vbase->base);
- }
-
- return size;
-}
-
-static void CABI_ApplyClassFlags(Object *obj, UInt8 flags, Boolean unused) {
- if (flags & CLASS_EFLAGS_INTERNAL)
- obj->flags = obj->flags | OBJECT_INTERNAL;
- if (flags & CLASS_EFLAGS_IMPORT)
- obj->flags = obj->flags | OBJECT_IMPORT;
- if (flags & CLASS_EFLAGS_EXPORT)
- obj->flags = obj->flags | OBJECT_EXPORT;
-}
-
-static void CABI_AllocateVTable(ClassLayout *layout, TypeClass *tclass) {
- SInt32 size;
- ObjBase *objbase;
- Object *obj;
- ObjMemberVar *ivar;
- ClassList *base;
- VClassList *vbase;
- int i;
-
- size = 0;
-
- if (!tclass->vtable) {
- CABI_AddVTable(tclass);
- layout->xA = layout->lex_order_count - 1;
- }
-
- if (!CABI_FindZeroDeltaVPtr(tclass)) {
- ivar = galloc(sizeof(ObjMemberVar));
- memclrw(ivar, sizeof(ObjMemberVar));
-
- ivar->otype = OT_MEMBERVAR;
- ivar->access = ACCESSPUBLIC;
- ivar->name = vptr_name_node;
- ivar->type = TYPE(&void_ptr);
- layout->vtable_ivar = ivar;
-
- for (i = layout->xA; ; i--) {
- if (i < 0) {
- ivar->next = tclass->ivars;
- tclass->ivars = ivar;
- break;
- }
-
- CError_ASSERT(666, layout->objlist[i]);
-
- if (layout->objlist[i]->otype == OT_MEMBERVAR) {
- ivar->next = OBJ_MEMBER_VAR(layout->objlist[i])->next;
- OBJ_MEMBER_VAR(layout->objlist[i])->next = ivar;
- break;
- }
- }
-
- if (tclass->flags & (CLASS_SINGLE_OBJECT | CLASS_COM_OBJECT))
- size = void_ptr.size;
- else
- size = 8;
- } else {
- layout->vtable_ivar = NULL;
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable && !base->is_virtual) {
- base->voffset = size;
- if (copts.vbase_abi_v2) {
- size += CABI_GetBaseVTableSize(base->base);
- } else {
- size += base->base->vtable->size;
- for (vbase = base->base->vbases; vbase; vbase = vbase->next) {
- if (vbase->base->vtable)
- size -= vbase->base->vtable->size;
- }
- }
- }
- }
-
- for (i = 0; i < layout->lex_order_count; i++) {
- CError_ASSERT(714, objbase = layout->objlist[i]);
-
- if (objbase->otype == OT_OBJECT && OBJECT(objbase)->datatype == DVFUNC) {
- TypeMemberFunc *tmethod = TYPE_METHOD(OBJECT(objbase)->type);
- Object *baseobj = CABI_FindZeroVirtualBaseMember(tclass, OBJECT(objbase));
-
- if (baseobj) {
- tmethod->vtbl_index = TYPE_METHOD(baseobj->type)->vtbl_index;
- } else {
- tmethod->vtbl_index = size;
- size += 4;
- }
- }
- }
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base->vtable) {
- vbase->voffset = size;
- if (copts.vbase_abi_v2)
- size += CABI_GetBaseVTableSize(vbase->base);
- else
- size += vbase->base->vtable->size;
- }
- }
-
- obj = CParser_NewCompilerDefDataObject();
- CABI_ApplyClassFlags(obj, tclass->eflags, 0);
-
- obj->name = CMangler_VTableName(tclass);
- obj->type = CDecl_NewStructType(size, 4);
- obj->qual = Q_CONST;
- obj->nspace = tclass->nspace;
- switch (tclass->action) {
- case CLASS_ACTION_0:
- obj->sclass = TK_STATIC;
- obj->qual |= Q_20000;
- break;
- }
-
- CParser_UpdateObject(obj, NULL);
-
- tclass->vtable->object = obj;
- tclass->vtable->owner = tclass;
- tclass->vtable->size = size;
-}
-
-void CABI_LayoutClass(ClassLayout *layout, TypeClass *tclass) {
- char saveAlignMode = copts.structalignment;
-
- tclass->size = 0;
- if (!tclass->sominfo) {
- if (tclass->bases)
- CABI_AllocateBases(layout, tclass);
- if (tclass->flags & CLASS_HAS_VBASES)
- CABI_AllocateVirtualBasePointers(layout, tclass);
- if (layout->has_vtable)
- CABI_AllocateVTable(layout, tclass);
- CABI_AllocateMembers(layout, tclass);
- if (tclass->flags & CLASS_HAS_VBASES)
- CABI_AllocateVirtualBases(layout, tclass);
- } else {
- copts.structalignment = AlignMode2_PPC;
- CABI_AllocateMembers(layout, tclass);
- }
-
- tclass->align = CMach_GetClassAlign(tclass);
- if (tclass->size == 0) {
- tclass->size = 1;
- tclass->flags = tclass->flags | CLASS_EMPTY;
- } else {
- tclass->size += CABI_StructSizeAlignValue(TYPE(tclass), tclass->size);
- }
-
- tclass->flags = tclass->flags | CLASS_COMPLETED;
-
- copts.structalignment = saveAlignMode;
-}
-
-void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *func) {
- DefArgCtorInfo *info;
- Boolean saveDebugInfo;
- ENodeList *copied;
- ENodeList *argexprs;
- FuncArg *args;
- CScopeSave savedScope;
- Statement firstStmt;
- Statement returnStmt;
-
- CError_FATAL(860);
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- CError_ASSERT(866, info = func->u.func.defargdata);
-
- CABI_ApplyClassFlags(func, tclass->eflags, 0);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- if (tclass->flags & CLASS_HAS_VBASES)
- arguments->next->object->name = no_name_node;
-
- firstStmt.next = &returnStmt;
-
- memclrw(&returnStmt, sizeof(Statement));
- returnStmt.type = ST_RETURN;
- returnStmt.expr = lalloc(sizeof(ENode));
- returnStmt.expr->type = EFUNCCALL;
- returnStmt.expr->cost = 200;
- returnStmt.expr->flags = 0;
- returnStmt.expr->rtype = TYPE(&void_ptr);
-
- returnStmt.expr->data.funccall.funcref = CExpr_MakeObjRefNode(info->default_func, 0);
- returnStmt.expr->data.funccall.functype = TYPE_FUNC(info->default_func->type);
- args = TYPE_FUNC(info->default_func->type)->args;
- returnStmt.expr->data.funccall.args = lalloc(sizeof(ENodeList));
- argexprs = returnStmt.expr->data.funccall.args;
-
- argexprs->node = create_objectnode(arguments->object);
-
- if (tclass->flags & CLASS_HAS_VBASES) {
- args = args->next;
- argexprs->next = lalloc(sizeof(ENodeList));
- argexprs = argexprs->next;
- argexprs->node = create_objectnode(arguments->next->object);
- }
-
- args = args->next;
- argexprs->next = lalloc(sizeof(ENodeList));
- argexprs = argexprs->next;
- argexprs->node = CInline_CopyExpression(info->default_arg, CopyMode0);
-
- while ((args = args->next) && args->dexpr) {
- argexprs->next = lalloc(sizeof(ENodeList));
- argexprs = argexprs->next;
- argexprs->node = CInline_CopyExpression(args->dexpr, CopyMode0);
- }
-
- argexprs->next = NULL;
-
- CFunc_CodeCleanup(&firstStmt);
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-
- func->u.func.defargdata = NULL;
-}
-
-static Object *CABI_ThisArg(void) {
- CError_ASSERT(931, arguments && IS_TYPE_POINTER_ONLY(arguments->object->type));
- return arguments->object;
-}
-
-ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {
- ENode *expr;
-
- if (tclass) {
- if (!tclass->sominfo) {
- expr = create_objectnode(CABI_ThisArg());
- if (tclass->flags & CLASS_HANDLEOBJECT)
- expr = makemonadicnode(expr, EINDIRECT);
- } else {
- expr = CSOM_SOMSelfObjectExpr(tclass);
- }
- } else {
- expr = create_objectnode(CABI_ThisArg());
- expr->rtype = TYPE(&void_ptr);
- }
-
- if (offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
-
- return expr;
-}
-
-static Object *CABI_VArg(void) {
- CError_ASSERT(976, arguments && arguments->next && IS_TYPE_INT(arguments->next->object->type));
- return arguments->next->object;
-}
-
-static ENode *CABI_MakeVArgExpr(void) {
- return create_objectnode(CABI_VArg());
-}
-
-static ENode *CABI_MakeCopyConArgExpr(TypeClass *tclass, Boolean flag) {
- ObjectList *args;
-
- CError_ASSERT(1000, args = arguments);
- CError_ASSERT(1001, args = args->next);
- if (flag && (tclass->flags & CLASS_HAS_VBASES))
- CError_ASSERT(1002, args = args->next);
- CError_ASSERT(1003, IS_TYPE_POINTER_ONLY(args->object->type));
-
- return create_objectnode(args->object);
-}
-
-static ENode *CABI_InitVBasePtr1(ENode *expr, TypeClass *tclass1, TypeClass *tclass2, TypeClass *tclass3, SInt32 offset) {
- ClassList *base;
- SInt32 newOffset;
- OffsetList *list;
-
- for (base = tclass2->bases; base; base = base->next) {
- if (base->base == tclass3 && base->is_virtual) {
- newOffset = offset + base->offset;
-
- for (list = trans_vtboffsets; list; list = list->next) {
- if (newOffset == list->offset)
- break;
- }
-
- if (!list) {
- list = lalloc(sizeof(OffsetList));
- list->offset = newOffset;
- list->next = trans_vtboffsets;
- trans_vtboffsets = list;
-
- expr = makediadicnode(
- makemonadicnode(CABI_MakeThisExpr(NULL, newOffset), EINDIRECT),
- expr,
- EASS);
- }
- }
-
- if (base->is_virtual)
- newOffset = CClass_VirtualBaseOffset(tclass1, base->base);
- else
- newOffset = offset + base->offset;
-
- expr = CABI_InitVBasePtr1(expr, tclass1, base->base, tclass3, newOffset);
- }
-
- return expr;
-}
-
-static Statement *CABI_InitVBasePtrs(Statement *stmt, TypeClass *tclass) {
- ENode *expr;
- VClassList *vbase;
-
- for (vbase = tclass->vbases, trans_vtboffsets = NULL; vbase; vbase = vbase->next) {
- expr = CABI_InitVBasePtr1(CABI_MakeThisExpr(NULL, vbase->offset), tclass, tclass, vbase->base, 0);
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- }
-
- return stmt;
-}
-
-static OffsetList *CABI_GetVBasePath(TypeClass *tclass, TypeClass *baseclass) {
- ClassList *base;
- OffsetList *best;
- OffsetList *list;
- OffsetList *scan;
- short bestLength;
- short length;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == baseclass && base->is_virtual) {
- best = lalloc(sizeof(OffsetList));
- best->next = NULL;
- best->offset = base->offset;
- return best;
- }
- }
-
- best = NULL;
-
- for (base = tclass->bases; base; base = base->next) {
- if ((list = CABI_GetVBasePath(base->base, baseclass))) {
- for (scan = list->next, length = 1; scan; scan = scan->next)
- length++;
-
- if (base->is_virtual)
- length++;
-
- if (!best || length < bestLength) {
- if (base->is_virtual) {
- best = lalloc(sizeof(OffsetList));
- best->next = list;
- best->offset = base->offset;
- } else {
- best = list;
- best->offset += base->offset;
- }
- bestLength = length;
- }
- }
- }
-
- return best;
-}
-
-static ENode *CABI_GetVBasePtr(TypeClass *tclass, TypeClass *baseclass) {
- OffsetList *path;
- ENode *expr;
-
- CError_ASSERT(1127, path = CABI_GetVBasePath(tclass, baseclass));
-
- expr = makemonadicnode(CABI_MakeThisExpr(NULL, path->offset), EINDIRECT);
-
- while ((path = path->next)) {
- if (path->offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), path->offset), EADD);
- expr = makemonadicnode(expr, EINDIRECT);
- }
-
- return expr;
-}
-
-static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *baseclass, SInt32 offset) {
- ClassList *base;
- SInt32 tmp;
-
- if (tclass == baseclass)
- return offset;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual && (tmp = CABI_FindNVBase(base->base, baseclass, offset + base->offset)) >= 0)
- return tmp;
- }
-
- return -1;
-}
-
-SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *baseclass) {
- SInt32 baseSize;
- SInt32 size;
- char saveAlignMode;
-
- size = CABI_GetBaseSize(tclass);
- if (baseclass) {
- baseSize = CABI_FindNVBase(tclass, baseclass, 0);
- CError_ASSERT(1178, baseSize >= 0);
- size -= baseSize;
- }
-
- saveAlignMode = copts.structalignment;
- if (tclass->eflags & CLASS_EFLAGS_F0)
- copts.structalignment = ((tclass->eflags & CLASS_EFLAGS_F0) >> 4) - 1;
- size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size);
- copts.structalignment = saveAlignMode;
-
- return size;
-}
-
-static Statement *CABI_InitVBaseCtorOffsets(Statement *stmt, TypeClass *tclass) {
- VClassList *vbase;
- Object *tempObj;
- ENode *expr;
- ENode *vbaseptr;
- SInt32 vboffset;
- SInt32 ctorOffsetOffset;
-
- tempObj = NULL;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->has_override) {
- if (!tempObj)
- tempObj = create_temp_object(TYPE(&void_ptr));
-
- vboffset = CClass_VirtualBaseOffset(tclass, vbase->base);
- ctorOffsetOffset = CABI_GetCtorOffsetOffset(vbase->base, NULL);
- vbaseptr = CABI_GetVBasePtr(tclass, vbase->base);
- CError_ASSERT(1215, vbaseptr);
-
- expr = makediadicnode(create_objectnode(tempObj), vbaseptr, EASS);
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
-
- expr = makediadicnode(
- create_objectnode(tempObj),
- intconstnode(TYPE(&stunsignedlong), ctorOffsetOffset),
- EADD);
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TYPE(&stunsignedlong);
- expr = makediadicnode(
- expr,
- makediadicnode(
- CABI_MakeThisExpr(NULL, vboffset),
- create_objectnode(tempObj),
- ESUB),
- EASS);
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- }
- }
-
- return stmt;
-}
-
-static Statement *CABI_InitVTablePtrs(Statement *stmt, Object *vtableObj, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, SInt32 voffset) {
- ClassList *base;
- BClassList *orig_pathcur;
- SInt32 newOffset;
- SInt32 newVOffset;
- OffsetList *offsetList;
- SInt32 vtblOffset;
- ENode *vtblExpr;
- ENode *pathExpr;
- BClassList path;
-
- if (baseclass->vtable->owner == baseclass) {
- vtblOffset = offset + baseclass->vtable->offset;
- for (offsetList = trans_vtboffsets; offsetList; offsetList = offsetList->next) {
- if (vtblOffset == offsetList->offset)
- break;
- }
-
- if (!offsetList) {
- offsetList = lalloc(sizeof(OffsetList));
- offsetList->offset = vtblOffset;
- offsetList->next = trans_vtboffsets;
- trans_vtboffsets = offsetList;
-
- vtblExpr = create_objectrefnode(vtableObj);
- vtblExpr->rtype = TYPE(&void_ptr);
- if ((vtblOffset = voffset + CABI_GetVTableOffset(baseclass)))
- vtblExpr = makediadicnode(vtblExpr, intconstnode(TYPE(&stunsignedlong), vtblOffset), EADD);
-
- pathExpr = CClass_AccessPathCast(&cabi_pathroot, CABI_MakeThisExpr(tclass, 0), 0);
- if (baseclass->vtable->offset && !canadd(pathExpr, baseclass->vtable->offset)) {
- pathExpr = makediadicnode(pathExpr, intconstnode(TYPE(&stunsignedlong), baseclass->vtable->offset), EADD);
- optimizecomm(pathExpr);
- }
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = makediadicnode(makemonadicnode(pathExpr, EINDIRECT), vtblExpr, EASS);
- }
- }
-
- for (base = baseclass->bases; base; base = base->next) {
- if (base->base->vtable) {
- orig_pathcur = cabi_pathcur;
-
- cabi_pathcur->next = &path;
- path.next = NULL;
- path.type = TYPE(base->base);
- cabi_pathcur = &path;
-
- if (base->is_virtual) {
- newOffset = CClass_VirtualBaseOffset(tclass, base->base);
- newVOffset = CClass_VirtualBaseVTableOffset(tclass, base->base);
- } else {
- newOffset = offset + base->offset;
- newVOffset = voffset + base->voffset;
- }
-
- stmt = CABI_InitVTablePtrs(stmt, vtableObj, tclass, base->base, newOffset, newVOffset);
-
- cabi_pathcur = orig_pathcur;
- }
- }
-
- return stmt;
-}
-
-static Boolean CABI_IsOperatorNew(ObjBase *obj) {
- return
- obj->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(obj)->type) &&
- TYPE_FUNC(OBJECT(obj)->type)->args &&
- TYPE_FUNC(OBJECT(obj)->type)->args->type == CABI_GetSizeTType() &&
- !TYPE_FUNC(OBJECT(obj)->type)->args->next;
-}
-
-Object *CABI_ConstructorCallsNew(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- NameResult pr;
-
- if (!tclass->sominfo && (tclass->flags & CLASS_HANDLEOBJECT)) {
- if (CScope_FindClassMemberObject(tclass, &pr, CMangler_OperatorName(TK_NEW))) {
- if (pr.obj_10) {
- if (CABI_IsOperatorNew(pr.obj_10))
- return OBJECT(pr.obj_10);
- } else {
- for (nsol = pr.nsol_14; nsol; nsol = nsol->next) {
- if (CABI_IsOperatorNew(nsol->object))
- return OBJECT(nsol->object);
- }
- }
- }
-
- return newh_func;
- }
-
- return NULL;
-}
-
-void CABI_TransConstructor(Object *obj, Statement *firstStmt, TypeClass *tclass, TransConstructorCallback callback, Boolean has_try) {
- Statement *stmt;
- Object *tmpfunc;
- Object *tmpfunc2;
- CLabel *label;
- ENode *expr;
- ClassList *base;
- VClassList *vbase;
- ObjMemberVar *ivar;
- Type *type;
- CtorChain *chain;
- Boolean errorflag;
-
- stmt = firstStmt;
-
- if ((tmpfunc = CABI_ConstructorCallsNew(tclass))) {
- label = newlabel();
-
- stmt = CFunc_InsertStatement(ST_IFGOTO, firstStmt);
- stmt->expr = CABI_MakeThisExpr(NULL, 0);
- stmt->label = label;
-
- expr = makediadicnode(
- CABI_MakeThisExpr(NULL, 0),
- funccallexpr(tmpfunc, intconstnode(CABI_GetSizeTType(), tclass->size), NULL, NULL, NULL),
- EASS);
- stmt = CFunc_InsertStatement(ST_IFGOTO, stmt);
- stmt->expr = expr;
- stmt->label = label;
-
- stmt = CFunc_InsertStatement(ST_RETURN, stmt);
- stmt->expr = NULL;
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label;
- label->stmt = stmt;
- }
-
- if (has_try) {
- for (stmt = firstStmt; ; stmt = stmt->next) {
- CError_ASSERT(1408, stmt);
- if (stmt->type == ST_BEGINCATCH)
- break;
- }
- }
-
- if (!tclass->sominfo) {
- if (tclass->flags & CLASS_HAS_VBASES) {
- label = newlabel();
-
- stmt = CFunc_InsertStatement(ST_IFGOTO, stmt);
- stmt->expr = CExpr_New_EEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0));
- stmt->label = label;
-
- stmt = CABI_InitVBasePtrs(stmt, tclass);
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (!callback) {
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_VBase && chain->u.vbase == vbase)
- break;
- }
-
- if (chain) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = chain->objexpr;
- } else {
- expr = CClass_DefaultConstructorCall(
- vbase->base,
- tclass,
- CABI_MakeThisExpr(NULL, vbase->offset),
- 0, 1, 1, &errorflag);
- if (expr) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- } else if (errorflag) {
- CError_Error(CErrorStr213, tclass, 0, vbase->base, 0);
- }
- }
- } else {
- stmt = callback(stmt, tclass, vbase->base, vbase->offset, 1);
- }
-
- if ((tmpfunc = CClass_Destructor(vbase->base)))
- CExcept_RegisterMember(stmt, CABI_ThisArg(), vbase->offset, tmpfunc, CABI_VArg(), 0);
- }
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label;
- label->stmt = stmt;
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->is_virtual)
- continue;
-
- if (!callback) {
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_Base && chain->u.base == base)
- break;
- }
-
- if (chain) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = chain->objexpr;
- } else {
- expr = CClass_DefaultConstructorCall(
- base->base,
- tclass,
- CABI_MakeThisExpr(NULL, base->offset),
- 0, 1, 0, &errorflag);
- if (expr) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- } else if (errorflag) {
- CError_Error(CErrorStr213, tclass, 0, base->base, 0);
- }
- }
- } else {
- stmt = callback(stmt, tclass, base->base, base->offset, 1);
- }
-
- if ((tmpfunc = CClass_Destructor(base->base)))
- CExcept_RegisterMember(stmt, CABI_ThisArg(), base->offset, tmpfunc, NULL, 0);
- }
-
- if (tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) {
- cabi_pathroot.next = NULL;
- cabi_pathroot.type = TYPE(tclass);
- cabi_pathcur = &cabi_pathroot;
- trans_vtboffsets = NULL;
-
- stmt = CABI_InitVTablePtrs(stmt, tclass->vtable->object, tclass, tclass, 0, 0);
- }
- }
-
- if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000))
- stmt = CABI_InitVBaseCtorOffsets(stmt, tclass);
-
- if (!callback) {
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar) {
- if (IS_TYPE_ARRAY(ivar->type))
- chain = NULL;
- break;
- }
- }
-
- if (chain) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = chain->objexpr;
- type = ivar->type;
- switch (type->type) {
- case TYPEARRAY:
- do {
- type = TPTR_TARGET(type);
- } while (IS_TYPE_ARRAY(type));
- if (IS_TYPE_CLASS(type)) {
- if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) {
- CError_ASSERT(1560, type->size);
- CExcept_RegisterMemberArray(
- stmt,
- CABI_ThisArg(),
- ivar->offset,
- tmpfunc,
- ivar->type->size / type->size,
- type->size);
- }
- }
- break;
- case TYPECLASS:
- if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) {
- CExcept_RegisterMember(
- stmt,
- CABI_ThisArg(),
- ivar->offset,
- tmpfunc,
- NULL,
- 1);
- }
- break;
- }
- } else {
- type = ivar->type;
- switch (type->type) {
- case TYPEARRAY:
- do {
- type = TPTR_TARGET(type);
- } while (IS_TYPE_ARRAY(type));
- if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type))) {
- if (
- (tmpfunc = CClass_DefaultConstructor(TYPE_CLASS(type))) ||
- (tmpfunc = CClass_DummyDefaultConstructor(TYPE_CLASS(type)))
- )
- {
- tmpfunc2 = CClass_Destructor(TYPE_CLASS(type));
- if (tmpfunc2)
- tmpfunc2 = CABI_GetDestructorObject(tmpfunc2, 1);
-
- stmt = CInit_ConstructClassArray(
- stmt,
- TYPE_CLASS(type),
- tmpfunc,
- tmpfunc2,
- CABI_MakeThisExpr(tclass, ivar->offset),
- ivar->type->size / type->size);
-
- if (tmpfunc2)
- CExcept_RegisterMemberArray(
- stmt,
- CABI_ThisArg(),
- ivar->offset,
- tmpfunc2,
- ivar->type->size / type->size,
- type->size);
- } else {
- CError_Error(CErrorStr214, tclass, 0, ivar->name->name);
- }
- }
- break;
- case TYPECLASS:
- expr = CClass_DefaultConstructorCall(
- TYPE_CLASS(type),
- NULL,
- CABI_MakeThisExpr(tclass, ivar->offset),
- 1, 1, 0, &errorflag);
- if (expr) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- } else if (errorflag) {
- CError_Error(CErrorStr214, tclass, 0, ivar->name->name);
- }
-
- if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) {
- if (!expr) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = nullnode();
- }
- CExcept_RegisterMember(
- stmt,
- CABI_ThisArg(),
- ivar->offset,
- tmpfunc,
- NULL,
- 1);
- }
- break;
- }
- }
- }
- } else {
- stmt = callback(stmt, tclass, NULL, 0, 1);
- }
-
- if (!tclass->sominfo) {
- for (stmt = firstStmt->next; stmt; stmt = stmt->next) {
- if (stmt->type == ST_RETURN) {
- CError_ASSERT(1661, !stmt->expr);
- stmt->expr = CABI_MakeThisExpr(NULL, 0);
- }
- }
- }
-}
-
-void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *func) {
- Boolean saveDebugInfo;
- CScopeSave savedScope;
- Statement firstStmt;
- Statement returnStmt;
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- CABI_ApplyClassFlags(func, tclass->eflags, 0);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- ctor_chain = NULL;
- if (tclass->flags & CLASS_HAS_VBASES)
- arguments->next->object->name = CParser_GetUniqueName();
-
- firstStmt.next = &returnStmt;
-
- memclrw(&returnStmt, sizeof(Statement));
- returnStmt.type = ST_RETURN;
-
- CABI_TransConstructor(func, &firstStmt, tclass, NULL, 0);
-
- CFunc_CodeCleanup(&firstStmt);
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-}
-
-static ENode *CABI_AssignObject(TypeClass *tclass, ENode *expr1, ENode *expr2) {
- Object *assignfunc;
- FuncArg *arg;
-
- assignfunc = CClass_AssignmentOperator(tclass);
- if (!assignfunc) {
- expr1 = makemonadicnode(expr1, EINDIRECT);
- expr1->rtype = TYPE(tclass);
- return makediadicnode(expr1, expr2, EASS);
- }
-
- CError_ASSERT(1731,
- IS_TYPE_FUNC(assignfunc->type) &&
- (arg = TYPE_FUNC(assignfunc->type)->args) &&
- (arg = arg->next));
-
- expr2 = argumentpromotion(expr2, arg->type, arg->qual, 1);
- return funccallexpr(assignfunc, expr1, expr2, NULL, NULL);
-}
-
-static Type *CABI_FindIntegralSizeType(SInt32 size) {
- if (stunsignedchar.size == size)
- return TYPE(&stunsignedchar);
- if (stunsignedshort.size == size)
- return TYPE(&stunsignedshort);
- if (stunsignedint.size == size)
- return TYPE(&stunsignedint);
- if (stunsignedlong.size == size)
- return TYPE(&stunsignedlong);
- if (stunsignedlonglong.size == size)
- return TYPE(&stunsignedlonglong);
-
- CError_FATAL(1756);
- return NULL;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct CopyRegion {
- struct CopyRegion *next;
- Type *type;
- SInt32 start;
- SInt32 end;
- Boolean flag;
-} CopyRegion;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static CopyRegion *CABI_AppendCopyRegion(CopyRegion *regions, Type *type, SInt32 start, Boolean flag) {
- CopyRegion *region;
- SInt32 end;
-
- if (IS_TYPE_BITFIELD(type))
- type = TYPE_BITFIELD(type)->bitfieldtype;
-
- end = start + type->size;
-
- if (flag) {
- for (region = regions; region; region = region->next) {
- if (region->flag) {
- if (region->start <= start && region->end >= end)
- return regions;
-
- if (region->start >= start && region->end <= end) {
- region->type = type;
- region->start = start;
- region->end = end;
- for (region = region->next; region; region = region->next) {
- if (region->start >= start && region->end <= end)
- region->end = region->start;
- }
- return regions;
- }
- }
- }
- }
-
- if (regions) {
- region = regions;
- while (region->next)
- region = region->next;
-
- region->next = lalloc(sizeof(CopyRegion));
- region = region->next;
- } else {
- regions = lalloc(sizeof(CopyRegion));
- region = regions;
- }
-
- region->next = NULL;
- region->type = type;
- region->start = start;
- region->end = end;
- region->flag = flag;
-
- return regions;
-}
-
-static ENode *CABI_ClassInitLoopCallBack(ENode *var1, ENode *var2) {
- ENodeList *list;
-
- var2 = makemonadicnode(var2, EINDIRECT);
- var2->rtype = TYPE(cabi_loop_class);
-
- if (cabi_loop_construct) {
- list = lalloc(sizeof(ENodeList));
- memclrw(list, sizeof(ENodeList));
- list->node = var2;
- return CExpr_ConstructObject(cabi_loop_class, var1, list, 1, 1, 0, 1, 1);
- } else {
- return CABI_AssignObject(cabi_loop_class, var1, var2);
- }
-}
-
-static Statement *CABI_CopyConAssignCB(Statement *stmt, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, Boolean flag) {
- ENode *expr;
- ENode *expr2;
- ENode *startExpr;
- ENode *endExpr;
- ENodeList *list;
- ObjMemberVar *ivar;
- CopyRegion *regions;
- Type *type;
- SInt32 i;
- SInt32 count;
- Boolean isFlagNotSet;
- Object *tmpfunc;
-
- if (baseclass) {
- if (baseclass->flags & CLASS_EMPTY) {
- if (
- (flag && !CClass_CopyConstructor(baseclass)) ||
- (!flag && !CClass_AssignmentOperator(baseclass))
- )
- return stmt;
- }
-
- expr = CABI_MakeCopyConArgExpr(tclass, flag);
- expr->rtype = TYPE(baseclass);
- expr->data.monadic = CClass_DirectBasePointerCast(expr->data.monadic, tclass, baseclass);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- if (flag) {
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- list->node = expr;
-
- stmt->expr = CExpr_ConstructObject(
- baseclass,
- CABI_MakeThisExpr(NULL, offset),
- list,
- 1, 0, 0, 0, 1);
- } else {
- stmt->expr = CABI_AssignObject(
- baseclass,
- CClass_DirectBasePointerCast(CABI_MakeThisExpr(NULL, 0), tclass, baseclass),
- expr);
- }
- } else {
- isFlagNotSet = !flag;
- for (ivar = tclass->ivars, regions = NULL; ivar; ivar = ivar->next) {
- if (ivar->name == vptr_name_node)
- continue;
-
- type = ivar->type;
- if (isFlagNotSet) {
- if (CParser_IsConst(type, ivar->qual) || IS_TYPE_REFERENCE(type) != 0) {
- CError_Error(CErrorStr387, tclass, 0);
- isFlagNotSet = 0;
- }
- }
-
- switch (type->type) {
- case TYPEARRAY:
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
- if (!IS_TYPE_CLASS(type)) {
- regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1);
- break;
- }
- case TYPECLASS:
- if (flag) {
- if (CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_CopyConstructor(TYPE_CLASS(type))) {
- regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0);
- break;
- }
- } else {
- if (CClass_AssignmentOperator(TYPE_CLASS(type))) {
- regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0);
- break;
- }
- }
- default:
- regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1);
- }
- }
-
- for (; regions; regions = regions->next) {
- if (regions->start >= regions->end)
- continue;
-
- type = regions->type;
- expr = CABI_MakeCopyConArgExpr(tclass, flag);
- expr->rtype = type;
-
- if (!canadd(expr->data.monadic, regions->start)) {
- expr->data.monadic = makediadicnode(
- expr->data.monadic,
- intconstnode(TYPE(&stunsignedlong), regions->start),
- EADD);
- optimizecomm(expr->data.monadic);
- }
-
- if (!regions->flag) {
- if (IS_TYPE_ARRAY(type)) {
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- CError_ASSERT(1966, IS_TYPE_CLASS(type));
-
- if (type->size) {
- count = regions->type->size / type->size;
- if (count > 4) {
- startExpr = CABI_MakeThisExpr(tclass, regions->start);
- endExpr = CABI_MakeThisExpr(tclass, regions->start + regions->type->size);
- expr = CABI_MakeCopyConArgExpr(tclass, flag)->data.monadic;
- if (!canadd(expr, regions->start)) {
- expr = makediadicnode(
- expr,
- intconstnode(TYPE(&stunsignedlong), regions->start),
- EADD);
- optimizecomm(expr);
- }
-
- cabi_loop_class = TYPE_CLASS(type);
- cabi_loop_construct = flag;
- stmt = CFunc_GenerateLoop(
- stmt,
- CDecl_NewPointerType(type),
- startExpr,
- endExpr,
- intconstnode(TYPE(&stunsignedlong), type->size),
- expr,
- CABI_ClassInitLoopCallBack);
- } else {
- for (i = 0, offset = regions->start; i < count; i++, offset += type->size) {
- expr = CABI_MakeCopyConArgExpr(tclass, flag);
- expr->rtype = type;
-
- if (!canadd(expr->data.monadic, offset)) {
- expr->data.monadic = makediadicnode(
- expr->data.monadic,
- intconstnode(TYPE(&stunsignedlong), offset),
- EADD);
- optimizecomm(expr->data.monadic);
- }
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- if (flag) {
- list = lalloc(sizeof(ENodeList));
- memclrw(list, sizeof(ENodeList));
- list->node = expr;
- stmt->expr = CExpr_ConstructObject(
- TYPE_CLASS(type),
- CABI_MakeThisExpr(tclass, offset),
- list,
- 1, 1, 0, 1, 1);
- } else {
- stmt->expr = CABI_AssignObject(
- TYPE_CLASS(type),
- CABI_MakeThisExpr(tclass, offset),
- expr);
- }
- }
- }
-
- if (flag && (tmpfunc = CClass_Destructor(TYPE_CLASS(type))))
- CExcept_RegisterMemberArray(stmt, CABI_ThisArg(), regions->start, tmpfunc, count, type->size);
- }
- } else {
- CError_ASSERT(2027, IS_TYPE_CLASS(type));
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
-
- if (flag) {
- list = lalloc(sizeof(ENodeList));
- memclrw(list, sizeof(ENodeList));
- list->node = expr;
- stmt->expr = CExpr_ConstructObject(
- TYPE_CLASS(type),
- CABI_MakeThisExpr(tclass, regions->start),
- list,
- 1, 1, 0, 1, 1);
-
- if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type))))
- CExcept_RegisterMember(stmt, CABI_ThisArg(), regions->start, tmpfunc, NULL, 1);
- } else {
- stmt->expr = CABI_AssignObject(
- TYPE_CLASS(type),
- CABI_MakeThisExpr(tclass, regions->start),
- expr);
- }
- }
- } else {
- if (IS_TYPE_ARRAY(type)) {
- if (type->size > 1 && ((regions->start & 1) || (type->size & 1))) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = funccallexpr(
- copy_func,
- CABI_MakeThisExpr(tclass, regions->start),
- getnodeaddress(expr, 0),
- intconstnode(CABI_GetSizeTType(), type->size),
- NULL);
- continue;
- }
-
- type = CDecl_NewStructType(type->size, CMach_GetTypeAlign(type));
- expr->rtype = type;
- }
-
- expr2 = makemonadicnode(CABI_MakeThisExpr(tclass, regions->start), EINDIRECT);
- expr2->rtype = type;
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = makediadicnode(expr2, expr, EASS);
- }
- }
- }
-
- return stmt;
-}
-
-void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *func) {
- Boolean saveDebugInfo;
- CScopeSave savedScope;
- Statement firstStmt;
- Statement returnStmt;
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- CABI_ApplyClassFlags(func, tclass->eflags, 0);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- ctor_chain = NULL;
- if (tclass->flags & CLASS_HAS_VBASES)
- arguments->next->object->name = CParser_GetUniqueName();
-
- firstStmt.next = &returnStmt;
-
- memclrw(&returnStmt, sizeof(Statement));
- returnStmt.type = ST_RETURN;
-
- CABI_TransConstructor(func, &firstStmt, tclass, CABI_CopyConAssignCB, 0);
-
- CFunc_CodeCleanup(&firstStmt);
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-}
-
-void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *func) {
- Boolean saveDebugInfo;
- Statement *stmt;
- ClassList *base;
- VClassList *vbase;
- ENode *expr1;
- ENode *expr2;
- CScopeSave savedScope;
- Statement firstStmt;
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- CABI_ApplyClassFlags(func, tclass->eflags, 0);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- stmt = curstmt;
-
- if (tclass->mode == CLASS_MODE_UNION) {
- expr1 = makemonadicnode(CABI_MakeThisExpr(tclass, 0), EINDIRECT);
- expr1->rtype = TYPE(tclass);
-
- expr2 = CABI_MakeCopyConArgExpr(tclass, 0);
- expr2->rtype = TYPE(tclass);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = makediadicnode(expr1, expr2, EASS);
- } else {
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- stmt = CABI_CopyConAssignCB(stmt, tclass, vbase->base, vbase->offset, 0);
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->is_virtual)
- stmt = CABI_CopyConAssignCB(stmt, tclass, base->base, base->offset, 0);
- }
-
- stmt = CABI_CopyConAssignCB(stmt, tclass, NULL, 0, 0);
- }
-
- stmt = CFunc_InsertStatement(ST_RETURN, stmt);
- stmt->expr = CABI_MakeThisExpr(NULL, 0);
-
- CFunc_CodeCleanup(&firstStmt);
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-}
-
-static Statement *CABI_DestroyMembers(Statement *stmt, ObjMemberVar *ivars, TypeClass *tclass) {
- Type *type;
- Object *dtor;
- ENode *expr;
-
- for (; ivars; ivars = ivars->next) {
- type = ivars->type;
-
- if (IS_TYPE_ARRAY(type)) {
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) {
- dtor = CABI_GetDestructorObject(dtor, 1);
- stmt = CABI_DestroyMembers(stmt, ivars->next, tclass);
- expr = create_objectrefnode(dtor);
- expr->flags = expr->flags | ENODE_FLAG_80;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = funccallexpr(
- darr_func,
- CABI_MakeThisExpr(tclass, ivars->offset),
- expr,
- intconstnode(TYPE(&stsignedlong), type->size),
- intconstnode(TYPE(&stsignedlong), ivars->type->size / type->size)
- );
- return stmt;
- }
- } else {
- if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) {
- stmt = CABI_DestroyMembers(stmt, ivars->next, tclass);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = CABI_DestroyObject(
- dtor,
- CABI_MakeThisExpr(tclass, ivars->offset),
- CABIDestroy1,
- 1,
- 0
- );
- return stmt;
- }
- }
- }
-
- return stmt;
-}
-
-static Statement *CABI_DestroyBases(Statement *stmt, ClassList *bases) {
- ClassList *base;
- Object *dtor;
- SInt32 count;
- SInt32 i;
-
- base = bases;
- count = 0;
- while (base) {
- base = base->next;
- count++;
- }
-
- while (count > 0) {
- base = bases;
- i = count;
- while (i-- > 1)
- base = base->next;
-
- if (!base->is_virtual && (dtor = CClass_Destructor(base->base))) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = CABI_DestroyObject(
- dtor,
- CABI_MakeThisExpr(NULL, base->offset),
- CABIDestroy0,
- 1,
- 0);
- }
-
- count--;
- }
-
- return stmt;
-}
-
-static Statement *CABI_DestroyVBases(Statement *stmt, VClassList *vbases) {
- Object *dtor;
-
- for (; vbases; vbases = vbases->next) {
- if ((dtor = CClass_Destructor(vbases->base))) {
- stmt = CABI_DestroyVBases(stmt, vbases->next);
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = CABI_DestroyObject(
- dtor,
- CABI_MakeThisExpr(NULL, vbases->offset),
- CABIDestroy0,
- 1,
- 0);
- break;
- }
- }
-
- return stmt;
-}
-
-void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass, CABIDestroyMode mode) {
- CLabel *label2;
- Boolean flag29;
- CLabel *label;
- Statement *scan;
- Boolean flag25;
- Boolean flag24;
- Boolean flag23;
- CLabel *label3;
- Object *dealloc;
- Boolean deallocFlag;
-
- if (tclass->sominfo) {
- flag24 = 0;
- flag25 = 0;
- flag29 = 0;
- flag23 = 1;
- } else {
- flag24 = 1;
- flag23 = 1;
- flag25 = 1;
- flag29 = 1;
- }
-
- label = newlabel();
-
- for (scan = stmt; scan; scan = scan->next) {
- if (scan->type == ST_RETURN) {
- CError_ASSERT(2329, !scan->expr);
- scan->type = ST_GOTO;
- scan->label = label;
- }
-
- if (scan->next && scan->next->type == ST_RETURN && !scan->next->next) {
- CError_ASSERT(2334, !scan->next->expr);
- scan->next = NULL;
- break;
- }
- }
-
- scan = stmt;
-
- if (flag29) {
- label2 = newlabel();
- scan = CFunc_InsertStatement(ST_IFNGOTO, scan);
- scan->expr = CABI_MakeThisExpr(NULL, 0);
- scan->label = label2;
- }
-
- if (flag25 && tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) {
- cabi_pathroot.next = NULL;
- cabi_pathroot.type = TYPE(tclass);
- cabi_pathcur = &cabi_pathroot;
- trans_vtboffsets = NULL;
- scan = CABI_InitVTablePtrs(scan, tclass->vtable->object, tclass, tclass, 0, 0);
- }
-
- if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000))
- CABI_InitVBaseCtorOffsets(scan, tclass);
-
- scan = stmt;
- while (scan->next)
- scan = scan->next;
-
- scan = CFunc_InsertStatement(ST_LABEL, scan);
- scan->label = label;
- scan->dobjstack = NULL;
- label->stmt = scan;
-
- if (flag23 && !(tclass->flags & CLASS_HANDLEOBJECT))
- scan = CABI_DestroyMembers(scan, tclass->ivars, tclass);
-
- if (flag25 && tclass->bases)
- scan = CABI_DestroyBases(scan, tclass->bases);
-
- if (flag24 && (tclass->flags & CLASS_HAS_VBASES)) {
- label3 = newlabel();
- scan = CFunc_InsertStatement(ST_IFNGOTO, scan);
- scan->expr = CABI_MakeVArgExpr();
- scan->label = label3;
-
- scan = CABI_DestroyVBases(scan, tclass->vbases);
-
- scan = CFunc_InsertStatement(ST_LABEL, scan);
- scan->label = label3;
- label3->stmt = scan;
- }
-
- if (flag29) {
- scan = CFunc_InsertStatement(ST_IFGOTO, scan);
- scan->expr = CExpr_New_ELESSEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0));
- scan->label = label2;
-
- scan = CFunc_InsertStatement(ST_EXPRESSION, scan);
- dealloc = CParser_FindDeallocationObject(TYPE(tclass), NULL, 0, 0, &deallocFlag);
- if (deallocFlag) {
- scan->expr = funccallexpr(
- dealloc,
- CABI_MakeThisExpr(NULL, 0),
- intconstnode(CABI_GetSizeTType(), tclass->size),
- NULL,
- NULL);
- } else {
- scan->expr = funccallexpr(dealloc, CABI_MakeThisExpr(NULL, 0), NULL, NULL, NULL);
- }
-
- scan = CFunc_InsertStatement(ST_LABEL, scan);
- scan->label = label2;
- label2->stmt = scan;
- }
-
- scan = CFunc_InsertStatement(ST_RETURN, scan);
- if (tclass->sominfo)
- scan->expr = NULL;
- else
- scan->expr = CABI_MakeThisExpr(NULL, 0);
-}
-
-void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *func) {
- Boolean saveDebugInfo;
- CScopeSave savedScope;
- Statement firstStmt;
- Statement returnStmt;
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- CABI_ApplyClassFlags(func, tclass->eflags, 0);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- firstStmt.next = &returnStmt;
-
- memclrw(&returnStmt, sizeof(Statement));
- returnStmt.type = ST_RETURN;
-
- CFunc_CodeCleanup(&firstStmt);
-
- CABI_TransDestructor(func, func, &firstStmt, tclass, CABIDestroy0);
-
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-}
-
-static void CABI_CreateLayeredDestructor(TypeClass *tclass, Object *obj1, Object *func, CABIDestroyMode mode) {
- Boolean saveDebugInfo;
- CScopeSave savedScope;
- Statement firstStmt;
- Statement returnStmt;
-
- CError_FATAL(2524);
-
- CScope_SetFunctionScope(func, &savedScope);
-
- CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- firstStmt.next = &returnStmt;
-
- memclrw(&returnStmt, sizeof(Statement));
- returnStmt.type = ST_RETURN;
-
- CFunc_CodeCleanup(&firstStmt);
-
- CABI_TransDestructor(obj1, func, &firstStmt, tclass, mode);
-
- CFunc_Gen(&firstStmt, func, 0);
-
- CScope_RestoreScope(&savedScope);
- copts.filesyminfo = saveDebugInfo;
-}
-
-void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *func) {
- Object *dtor;
- CABIDestroyMode mode;
-
- CError_FATAL(2557);
-
- if (anyerrors || func->access == ACCESSNONE)
- return;
-
- if ((dtor = CClass_Destructor(tclass))) {
- if (CABI_GetDestructorObject(dtor, CABIDestroy0) == func)
- mode = CABIDestroy0;
- else if (CABI_GetDestructorObject(dtor, CABIDestroy2) == func)
- mode = CABIDestroy2;
- else if (CABI_GetDestructorObject(dtor, CABIDestroy3) == func)
- mode = CABIDestroy3;
- else if (CABI_GetDestructorObject(dtor, CABIDestroy1) == func)
- mode = CABIDestroy1;
- else
- CError_FATAL(2567);
- }
-
- CABI_CreateLayeredDestructor(tclass, dtor, func, mode);
-}
-
-Object *CABI_GetDestructorObject(Object *obj, CABIDestroyMode mode) {
- return obj;
-}
-
-static void CABI_AddLayeredDestructor(TypeClass *tclass, Object *dtor, HashNameNode *name, Boolean is_virtual) {
- Object *func;
-
- CError_FATAL(2667);
-
- func = CParser_NewFunctionObject(NULL);
- func->nspace = dtor->nspace;
- func->name = name;
- func->type = TYPE(CDecl_MakeDefaultDtorType(tclass, is_virtual));
- func->qual = Q_20000 | Q_MANGLE_NAME;
- func->qual |= Q_INLINE;
- CABI_ApplyClassFlags(func, tclass->eflags, 1);
-
- CError_ASSERT(2678, IS_TYPE_FUNC(func->type));
- TYPE_FUNC(func->type)->flags |= FUNC_AUTO_GENERATED;
-
- if (dtor->datatype == DVFUNC) {
- func->datatype = DVFUNC;
- CMangler_GetLinkName(func);
- func->datatype = DFUNC;
- }
-
- CScope_AddObject(func->nspace, func->name, OBJ_BASE(func));
-}
-
-void CABI_AddLayeredDestructors(TypeClass *tclass) {
- Object *dtor;
-
- CError_FATAL(2707);
-
- if ((dtor = CClass_Destructor(tclass))) {
- CABI_AddLayeredDestructor(tclass, dtor, CMangler_DeleteDtorName(), 1);
- CABI_AddLayeredDestructor(tclass, dtor, CMangler_SDeleteDtorName(), 1);
- if (tclass->vbases)
- CABI_AddLayeredDestructor(tclass, dtor, CMangler_VBaseDtorName(), 0);
- }
-}
-
-ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, CABIDestroyMode mode, Boolean flag1, Boolean flag2) {
- ENode *expr;
- short arg;
- ENodeList *list;
-
- switch (mode) {
- case CABIDestroy2:
- case CABIDestroy3:
- if (flag2)
- arg = 1;
- else
- arg = -1;
- break;
- case CABIDestroy1:
- arg = -1;
- break;
- case CABIDestroy0:
- arg = 0;
- break;
- default:
- CError_FATAL(2786);
- }
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 200;
- expr->flags = 0;
- expr->rtype = &stvoid;
- expr->data.funccall.funcref = create_objectrefnode(dtor);
- if (flag1)
- expr->data.funccall.funcref->flags = expr->data.funccall.funcref->flags | ENODE_FLAG_80;
- expr->data.funccall.functype = TYPE_FUNC(dtor->type);
- dtor->flags = dtor->flags | OBJECT_USED;
-
- list = lalloc(sizeof(ENodeList));
- list->node = objexpr;
- expr->data.funccall.args = list;
-
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = intconstnode(TYPE(&stsignedshort), arg);
-
- return expr;
-}
diff --git a/compiler_and_linker/unsorted/CBrowse.c b/compiler_and_linker/unsorted/CBrowse.c
deleted file mode 100644
index 12ea4c8..0000000
--- a/compiler_and_linker/unsorted/CBrowse.c
+++ /dev/null
@@ -1,737 +0,0 @@
-#include "compiler/CBrowse.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Unmangle.h"
-#include "compiler/objects.h"
-#include "compiler/templates.h"
-#include "cos.h"
-#include "plugin.h"
-
-Boolean gUseTokenStreamSource;
-Boolean gForceSourceLoc;
-Boolean gUseNameTable;
-static GList gBrowseData;
-static GList gClassData;
-static GList gMemberFuncList;
-static int gNextMemberFuncID;
-
-enum ELanguage {
- langUnknown,
- langC,
- langCPlus,
- langPascal,
- langObjectPascal,
- langJava,
- langAssembler,
- langFortran,
- langRez
-};
-
-enum EBrowserItem {
- browseFunction,
- browseGlobal,
- browseClass,
- browseMacro,
- browseEnum,
- browseTypedef,
- browseConstant,
- browseTemplate,
- browsePackage,
- browseCompSymbolStart = 0x70,
- browseEnd = 0xFF
-};
-
-enum {
- kAbstract = 1,
- kStatic = 2,
- kFinal = 4,
- kMember = 8,
-
- kInterface = 0x80,
- kPublic = 0x100,
-
- kInline = 0x80,
- kPascal = 0x100,
- kAsm = 0x200,
- kVirtual = 0x400,
- kCtor = 0x800,
- kDtor = 0x1000,
- kNative = 0x2000,
- kSynch = 0x4000,
- kIntrinsic = 0x8000,
- kConst = 0x10000,
-
- kTransient = 0x80,
- kVolatile = 0x100
-};
-
-enum EAccess {
- accessNone = 0,
- accessPrivate = 1,
- accessProtected = 2,
- accessPublic = 4
-};
-
-enum EMember {
- memberFunction,
- memberData,
- memberEnd = 0xFF
-};
-
-enum ETemplateType {
- templateClass,
- templateFunction
-};
-
-static enum EAccess gFromAccessType[] = {
- accessPublic,
- accessPrivate,
- accessProtected,
- accessNone
-};
-
-typedef struct BrowseHeader {
- SInt32 browse_header;
- SInt32 browse_version;
- SInt16 browse_language;
- SInt16 uses_name_table;
- SInt32 earliest_compatible_version;
- SInt32 reserved[15];
-} BrowseHeader;
-
-// forward decls
-static void RecordUndefinedMemberFunctions(void);
-
-void CBrowse_Setup(CompilerLinkerParamBlk *params) {
- BrowseHeader hdr;
-
- CError_ASSERT(123, params != NULL);
-
- params->object.browsedata = NULL;
-
- InitGList(&gBrowseData, 0x10000);
- InitGList(&gMemberFuncList, 1024);
-
- gNextMemberFuncID = 1;
- gForceSourceLoc = 0;
- gUseNameTable = 0;
-
- memclrw(&hdr, sizeof(hdr));
- hdr.browse_header = 0xBEABBAEB;
- hdr.browse_version = 2;
- hdr.earliest_compatible_version = 2;
- hdr.browse_language = copts.cplusplus ? langCPlus : langC;
- hdr.uses_name_table = gUseNameTable;
-
- AppendGListData(&gBrowseData, &hdr, sizeof(hdr));
-}
-
-void CBrowse_Finish(CompilerLinkerParamBlk *params) {
- CWMemHandle hnd;
-
- CError_ASSERT(151, params != NULL);
-
- if (gBrowseData.size >= sizeof(BrowseHeader)) {
- RecordUndefinedMemberFunctions();
- AppendGListByte(&gBrowseData, -1);
-
- COS_ResizeHandle(gBrowseData.data, gBrowseData.size);
-
- if (CWSecretAttachHandle(params->context, gBrowseData.data, &hnd) == cwNoErr) {
- params->object.browsedata = hnd;
- gBrowseData.data = NULL;
- }
- }
-}
-
-void CBrowse_Cleanup(CompilerLinkerParamBlk *params) {
- FreeGList(&gBrowseData);
- FreeGList(&gClassData);
- FreeGList(&gMemberFuncList);
-}
-
-static void AppendGList(GList *dst, GList *src) {
- SInt32 offset = dst->size;
-
- AppendGListNoData(dst, src->size);
- memcpy(*dst->data + offset, *src->data, src->size);
-}
-
-static void RecordName(GList *gl, const char *str, SInt32 id) {
- HashNameNode *name;
-
- CError_ASSERT(190, gl && str && *str);
-
- if (id < 0 && gUseNameTable) {
- for (name = name_hash_nodes[CHash(str)]; name; name = name->next) {
- if (!strcmp(str, name->name)) {
- id = name->id;
- break;
- }
- }
- }
-
- if (id >= 0 && gUseNameTable) {
- AppendGListWord(gl, -1);
- AppendGListLong(gl, id);
- } else {
- int len = strlen(str);
- AppendGListWord(gl, len);
- if (len)
- AppendGListData(gl, str, len + 1);
- }
-}
-
-void CBrowse_BeginClass(DeclInfo *di, GList *gl) {
- char *buf;
- ClassList *base;
- SInt32 i;
- TypeClass *tclass;
-
- CError_ASSERT(227, di && di->thetype && gl);
-
- *gl = gClassData;
-
- if (
- !di->file ||
- !di->file->fileID ||
- !di->file->recordbrowseinfo ||
- !di->file2 ||
- !di->file2->fileID ||
- di->sourceoffset <= 0
- )
- {
- memclrw(&gClassData, sizeof(gClassData));
- return;
- }
-
- if (IsTempName(TYPE_CLASS(di->thetype)->classname)) {
- memclrw(&gClassData, sizeof(gClassData));
- return;
- }
-
- InitGList(&gClassData, 0x4000);
- AppendGListByte(&gClassData, browseClass);
- AppendGListWord(&gClassData, di->file->fileID);
- AppendGListWord(&gClassData, di->file2->fileID);
- AppendGListLong(&gClassData, di->sourceoffset - 1);
- CError_ASSERT(270, gClassData.size == 9);
- AppendGListLong(&gClassData, di->sourceoffset - 1);
- AppendGListLong(&gClassData, 0);
- RecordName(&gClassData, TYPE_CLASS(di->thetype)->classname->name, TYPE_CLASS(di->thetype)->classname->id);
-
- CMangler_MangleType(di->thetype, 0);
- AppendGListByte(&name_mangle_list, 0);
-
- buf = lalloc(name_mangle_list.size + 1);
- strcpy(buf, *name_mangle_list.data);
-
- while (*buf && *buf >= '0' && *buf <= '9')
- buf++;
-
- if (strcmp(TYPE_CLASS(di->thetype)->classname->name, buf))
- RecordName(&gClassData, buf, -1);
- else
- AppendGListWord(&gClassData, 0);
-
- AppendGListLong(&gClassData, 0);
-
- i = 0;
- base = TYPE_CLASS(di->thetype)->bases;
- while (base) {
- base = base->next;
- i++;
- }
-
- AppendGListByte(&gClassData, i);
-
- for (base = TYPE_CLASS(di->thetype)->bases; base; base = base->next) {
- AppendGListByte(&gClassData, gFromAccessType[base->access]);
- AppendGListByte(&gClassData, base->is_virtual);
-
- tclass = base->base;
- if ((tclass->flags & CLASS_IS_TEMPL_INST) && !TEMPL_CLASS_INST(tclass)->is_specialized)
- tclass = TYPE_CLASS(TEMPL_CLASS_INST(tclass)->templ);
-
- CMangler_MangleType(TYPE(tclass), 0);
- AppendGListByte(&name_mangle_list, 0);
-
- buf = lalloc(name_mangle_list.size + 1);
- strcpy(buf, *name_mangle_list.data);
-
- while (*buf && *buf >= '0' && *buf <= '9')
- buf++;
-
- i = base->base->classname->id;
- while (*buf && *buf >= '0' && *buf <= '9') {
- i = -1;
- buf++;
- }
-
- RecordName(&gClassData, buf, i);
- }
-}
-
-void CBrowse_AddClassMemberVar(ObjMemberVar *ivar, SInt32 startOffset, SInt32 endOffset) {
- short len;
-
- CError_ASSERT(360, ivar);
-
- if (gClassData.data && startOffset > 0 && endOffset >= startOffset) {
- if (tk == ';')
- endOffset++;
-
- AppendGListByte(&gClassData, memberData);
- AppendGListByte(&gClassData, gFromAccessType[ivar->access]);
- AppendGListLong(&gClassData, 0);
- AppendGListLong(&gClassData, startOffset - 1);
- AppendGListLong(&gClassData, endOffset - 1);
-
- len = strlen(ivar->name->name);
- AppendGListWord(&gClassData, len);
- AppendGListData(&gClassData, ivar->name->name, len + 1);
- }
-}
-
-void CBrowse_AddClassMemberFunction(Object *object, SInt32 startOffset, SInt32 endOffset) {
- SInt32 flags;
- SInt32 id;
- TypeMemberFunc *tfunc;
-
- CError_ASSERT(380, object);
-
- if (
- !IsTempName(object->name) &&
- gClassData.data &&
- startOffset > 0 &&
- endOffset >= startOffset
- )
- {
- flags = 0;
- CError_ASSERT(391, object->type && IS_TYPE_FUNC(object->type));
- tfunc = TYPE_METHOD(object->type);
-
- if (tfunc->flags & FUNC_AUTO_GENERATED)
- return;
-
- if (object->datatype == DVFUNC)
- flags |= kVirtual;
- if (tfunc->flags & FUNC_PURE)
- flags |= kAbstract;
- if (tfunc->is_static)
- flags |= kStatic;
- if (tfunc->flags & FUNC_IS_CTOR)
- flags |= kCtor;
- if (tfunc->flags & FUNC_IS_DTOR)
- flags |= kDtor;
-
- AppendGListByte(&gClassData, memberFunction);
- AppendGListByte(&gClassData, gFromAccessType[object->access]);
- AppendGListLong(&gClassData, flags);
-
- id = tfunc->funcid;
- if (id <= 0) {
- // TODO: this is not 64-bit safe
- if (!(tfunc->flags & FUNC_DEFINED) || id == -1)
- AppendGListLong(&gMemberFuncList, (SInt32) object);
- tfunc->funcid = id = gNextMemberFuncID++;
- }
-
- AppendGListLong(&gClassData, id);
- AppendGListLong(&gClassData, startOffset - 1);
- AppendGListLong(&gClassData, endOffset);
- }
-}
-
-void CBrowse_AddClassMemberData(Object *object, SInt32 startOffset, SInt32 endOffset) {
- short len;
-
- CError_ASSERT(435, object);
-
- if (gClassData.data && startOffset > 0 && endOffset >= startOffset && object->datatype == DDATA) {
- if (tk == ';')
- endOffset++;
-
- AppendGListByte(&gClassData, memberData);
- AppendGListByte(&gClassData, gFromAccessType[object->access]);
- AppendGListLong(&gClassData, kStatic);
- AppendGListLong(&gClassData, startOffset - 1);
- AppendGListLong(&gClassData, endOffset - 1);
-
- len = strlen(object->name->name);
- AppendGListWord(&gClassData, len);
- AppendGListData(&gClassData, object->name->name, len + 1);
- }
-}
-
-void CBrowse_EndClass(SInt32 offset, GList *gl) {
- CError_ASSERT(453, gl);
-
- if (gClassData.data) {
- if (gClassData.size > 0) {
- if (tk == ';')
- offset++;
- memcpy(*gClassData.data + 9, &offset, 4);
- AppendGList(&gBrowseData, &gClassData);
- AppendGListByte(&gBrowseData, memberEnd);
- }
- FreeGList(&gClassData);
- }
-
- gClassData = *gl;
-}
-
-void CBrowse_BeginStruct(DeclInfo *di, TypeStruct *tstruct, GList *gl) {
- HashNameNode *name;
-
- CError_ASSERT(480, di && gl);
-
- *gl = gClassData;
-
- if (
- !di->file ||
- !di->file->fileID ||
- !di->file->recordbrowseinfo ||
- !di->file2 ||
- !di->file2->fileID ||
- di->sourceoffset <= 0
- )
- {
- memclrw(&gClassData, sizeof(gClassData));
- return;
- }
-
- name = tstruct->name;
- if (!name || IsTempName(name)) {
- memclrw(&gClassData, sizeof(gClassData));
- return;
- }
-
- InitGList(&gClassData, 0x4000);
- AppendGListByte(&gClassData, browseClass);
- AppendGListWord(&gClassData, di->file->fileID);
- AppendGListWord(&gClassData, di->file2->fileID);
- AppendGListLong(&gClassData, di->sourceoffset - 1);
- CError_ASSERT(521, gClassData.size == 9);
- AppendGListLong(&gClassData, di->sourceoffset - 1);
- AppendGListLong(&gClassData, 0);
- RecordName(&gClassData, name->name, name->id);
- AppendGListWord(&gClassData, 0);
- AppendGListLong(&gClassData, 0);
- AppendGListByte(&gClassData, 0);
-}
-
-void CBrowse_AddStructMember(StructMember *member, SInt32 startOffset, SInt32 endOffset) {
- short len;
-
- if (tk == ';')
- endOffset++;
-
- if (gClassData.data && member && startOffset > 0 && endOffset >= startOffset) {
- AppendGListByte(&gClassData, memberData);
- AppendGListByte(&gClassData, accessPublic);
- AppendGListLong(&gClassData, 0);
- AppendGListLong(&gClassData, startOffset - 1);
- AppendGListLong(&gClassData, endOffset - 1);
-
- len = strlen(member->name->name);
- AppendGListWord(&gClassData, len);
- AppendGListData(&gClassData, member->name->name, len + 1);
- }
-}
-
-void CBrowse_EndStruct(SInt32 offset, GList *gl) {
- CError_ASSERT(558, gl);
-
- if (gClassData.data) {
- if (offset > 0 && gClassData.size > 0) {
- memcpy(*gClassData.data + 9, &offset, 4);
- AppendGList(&gBrowseData, &gClassData);
- AppendGListByte(&gBrowseData, memberEnd);
- }
- FreeGList(&gClassData);
- }
-
- gClassData = *gl;
-}
-
-static void EmitStandardData(int item, int fileID1, int fileID2, SInt32 startOffset, SInt32 endOffset, const char *str, SInt32 id, const char *str2, SInt32 id2) {
- CError_ASSERT(584, str);
-
- AppendGListByte(&gBrowseData, item);
- AppendGListWord(&gBrowseData, fileID1);
- AppendGListWord(&gBrowseData, fileID2);
- AppendGListLong(&gBrowseData, startOffset - 1);
- AppendGListLong(&gBrowseData, endOffset - 1);
- AppendGListLong(&gBrowseData, 0);
-
- RecordName(&gBrowseData, str, id);
- if (str2 && str2 != str)
- RecordName(&gBrowseData, str2, id2);
- else
- AppendGListWord(&gBrowseData, 0);
-}
-
-void CBrowse_NewTypedef(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(618, file1 && file1->recordbrowseinfo);
-
- if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
- EmitStandardData(browseTypedef,
- file1->fileID, file2->fileID,
- startOffset, endOffset,
- name->name, name->id,
- CError_GetQualifiedName(nspace, name), -1);
- }
-}
-
-void CBrowse_NewEnum(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(632, file1 && file1->recordbrowseinfo);
-
- if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
- EmitStandardData(browseEnum,
- file1->fileID, file2->fileID,
- startOffset, endOffset,
- name->name, name->id,
- CError_GetQualifiedName(nspace, name), -1);
- }
-}
-
-void CBrowse_NewEnumConstant(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(646, file1 && file1->recordbrowseinfo);
-
- if (tk == ',')
- endOffset++;
-
- if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
- EmitStandardData(browseConstant,
- file1->fileID, file2->fileID,
- startOffset, endOffset,
- name->name, name->id,
- CError_GetQualifiedName(nspace, name), -1);
- }
-}
-
-static HashNameNode *CBrowse_GetLinkName(Object *object) {
- return CMangler_GetLinkName(object);
-}
-
-static void RecordFunction(Object *object, int fileID1, int fileID2, SInt32 startOffset, SInt32 endOffset) {
- TypeFunc *tfunc;
- char *tmp;
- Boolean flag;
- char *str29;
- HashNameNode *linkname;
- SInt32 flags;
- char *namestr;
- SInt32 nameid;
- char *namestr2;
- SInt32 nameid2;
- int funcid;
- char buf[2048];
- char buf2[256];
-
- CError_ASSERT(740, object->type && IS_TYPE_FUNC(object->type));
-
- if (IsTempName(object->name))
- return;
-
- tfunc = TYPE_FUNC(object->type);
- if ((tfunc->flags & (FUNC_AUTO_GENERATED | FUNC_INTRINSIC)) && (!fileID2 || startOffset < 0))
- return;
-
- linkname = object->name;
- tmp = linkname->name;
- if (!(linkname->name[0] == '_' && linkname->name[1] == '_')) {
- namestr = tmp;
- nameid = linkname->id;
- switch (tmp[0]) {
- case '.':
- nameid = -1;
- namestr += 1;
- break;
- case '_':
- switch (tmp[1]) {
- case '#':
- case '%':
- case '@':
- nameid = -1;
- namestr += 2;
- break;
- }
- break;
- }
- } else {
- flag = 1;
- if (tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) {
- tmp = TYPE_METHOD(tfunc)->theclass->classname->name;
- while (*tmp >= '0' && *tmp <= '9')
- tmp++;
- MWUnmangleClassName(tmp, buf, sizeof(buf));
-
- str29 = buf;
- if ((tmp = strrchr(str29, ':')))
- str29 = tmp + 1;
-
- if (tfunc->flags & FUNC_IS_DTOR) {
- buf2[0] = '~';
- strncpy(&buf2[1], str29, sizeof(buf2) - 1);
- namestr = buf2;
- } else {
- namestr = str29;
- }
-
- flag = 0;
- }
-
- if (flag) {
- MWUnmangle(object->name->name, buf, sizeof(buf));
- namestr = buf;
- }
-
- nameid = -1;
- }
-
- while (*namestr >= '0' && *namestr <= '9') {
- nameid = -1;
- namestr++;
- }
-
- namestr2 = NULL;
- nameid2 = -1;
-
- linkname = CBrowse_GetLinkName(object);
- if (object->name != linkname) {
- namestr2 = linkname->name;
- if (linkname->name[0] == '.')
- namestr2++;
- else
- nameid2 = linkname->id;
- }
-
- EmitStandardData(browseFunction, fileID1, fileID2, startOffset, endOffset, namestr, nameid, namestr2, nameid2);
-
- flags = 0;
- if (object->qual & Q_INLINE)
- flags |= kInline;
- if (object->qual & Q_PASCAL)
- flags |= kPascal;
- if (object->qual & Q_ASM)
- flags |= kAsm;
- if (object->sclass == TK_STATIC)
- flags |= kStatic;
- if (tfunc->flags & FUNC_METHOD)
- flags |= kMember;
- AppendGListLong(&gBrowseData, flags);
-
- funcid = 0;
- if (tfunc->flags & FUNC_METHOD) {
- funcid = TYPE_METHOD(tfunc)->funcid;
- if (funcid <= 0) {
- TYPE_METHOD(tfunc)->funcid = funcid = gNextMemberFuncID++;
- }
- }
- AppendGListLong(&gBrowseData, funcid);
-}
-
-void CBrowse_NewFunction(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(890, file1 && file1->recordbrowseinfo);
-
- if (file2 && file2->fileID && startOffset > 0 && (endOffset + 1) >= startOffset)
- RecordFunction(object, file1->fileID, file2->fileID, startOffset, endOffset + 1);
-}
-
-void CBrowse_NewData(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
- char *namestr = NULL;
- SInt32 flags = 0;
- Boolean is_const = is_const_object(object);
-
- CError_ASSERT(912, file1 && file1->recordbrowseinfo);
- CError_ASSERT(913, object);
-
- if (tk == ';')
- endOffset++;
-
- if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
- HashNameNode *name = CBrowse_GetLinkName(object);
- if (object->name != name)
- namestr = name->name;
-
- EmitStandardData(
- is_const ? browseConstant : browseGlobal,
- file1->fileID, file2->fileID,
- startOffset, endOffset,
- object->name->name, object->name->id,
- namestr, name->id
- );
-
- if (!is_const) {
- if (object->sclass == TK_STATIC)
- flags |= kStatic;
- AppendGListLong(&gBrowseData, flags);
- }
- }
-}
-
-void CBrowse_NewMacro(Macro *macro, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(951, !file || (file->recordbrowseinfo && !macro->is_special));
-
- if (file && file->fileID && startOffset > 0 && endOffset >= startOffset)
- EmitStandardData(
- browseMacro,
- file->fileID, file->fileID,
- startOffset, endOffset,
- macro->name->name, macro->name->id,
- NULL, -1
- );
-}
-
-void CBrowse_NewTemplateClass(TemplClass *tmclass, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset) {
- CError_ASSERT(965, !file || file->recordbrowseinfo);
-
- if (file && file->fileID && startOffset > 0 && endOffset >= startOffset) {
- EmitStandardData(
- browseTemplate,
- file->fileID, file->fileID,
- startOffset, endOffset,
- tmclass->theclass.classname->name, tmclass->theclass.classname->id,
- NULL, -1
- );
- AppendGListByte(&gBrowseData, templateClass);
- }
-}
-
-void CBrowse_NewTemplateFunc(TemplateFunction *tmfunc) {
- CError_ASSERT(979, !tmfunc->srcfile || tmfunc->srcfile->recordbrowseinfo);
-
- if (tmfunc->srcfile && tmfunc->srcfile->fileID && tmfunc->startoffset > 0 && tmfunc->endoffset >= tmfunc->startoffset) {
- EmitStandardData(
- browseTemplate,
- tmfunc->srcfile->fileID, tmfunc->srcfile->fileID,
- tmfunc->startoffset, tmfunc->endoffset,
- tmfunc->name->name, tmfunc->name->id,
- NULL, -1
- );
- AppendGListByte(&gBrowseData, templateFunction);
- }
-}
-
-static void RecordUndefinedMemberFunctions(void) {
- int i;
- int count;
- Object **array;
-
- COS_LockHandleHi(gMemberFuncList.data);
-
- count = gMemberFuncList.size / sizeof(Object *);
- array = (Object **) *gMemberFuncList.data;
- for (i = 0; i < count; i++, array++) {
- if (IS_TYPE_FUNC((*array)->type) && !(TYPE_FUNC((*array)->type)->flags & FUNC_DEFINED))
- RecordFunction(*array, 0, 0, -1, -1);
- }
-
- COS_UnlockHandle(gMemberFuncList.data);
-}
diff --git a/compiler_and_linker/unsorted/CClass.c b/compiler_and_linker/unsorted/CClass.c
deleted file mode 100644
index fad276e..0000000
--- a/compiler_and_linker/unsorted/CClass.c
+++ /dev/null
@@ -1,2312 +0,0 @@
-#include "compiler/CClass.h"
-#include "compiler/CABI.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CParser.h"
-#include "compiler/CRTTI.h"
-#include "compiler/CSOM.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct OVClassBase {
- struct OVClassBase *next;
- struct OVClass *ovclass;
- Boolean is_virtual;
-} OVClassBase;
-
-typedef struct OVFunc {
- struct OVFunc *next;
- Object *obj;
- struct OVClass *ovc8;
- struct OVFunc *ovfC;
- struct OVFunc *ovf10;
-} OVFunc;
-
-typedef struct OVClass {
- TypeClass *tclass;
- OVFunc *vfuncs;
- OVClassBase *bases;
- SInt32 offset;
- SInt32 voffset;
- Boolean alloced_vtable;
-} OVClass;
-
-typedef struct ThunkList {
- struct ThunkList *next;
- Object *thunkobj;
- Object *obj;
- SInt32 a;
- SInt32 b;
- SInt32 c;
-} ThunkList;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static TypeClass *main_class;
-static ThunkList *cclass_thunklist;
-static TypeClass *cclass_isbase_mostderived;
-static SInt32 cclass_isbase_foundoffset;
-static Boolean cclass_isambigbase;
-static short cclass_founddepth;
-static char *vtable_object_data;
-static SInt32 vtable_data_size;
-static OLinkList *vtable_object_links;
-static TypeClass *cclass_vbase;
-static OVClass *cclass_ovbase;
-static OVClass *cclass_root;
-static Object *found_pure;
-static Boolean check_pures;
-static Object *cclass_dominator_vobject;
-static SInt32 cclass_dominator_voffset;
-static Object *cclass_dominator_oobject;
-static TypeClass *cclass_dominator_oclass;
-static SInt32 cclass_dominator_ooffset;
-static Object *cclass_dominator_eobject;
-
-void CClass_Init(void) {
- cclass_thunklist = NULL;
-}
-
-void CClass_GenThunks(void) {
- ThunkList *list;
-
- for (list = cclass_thunklist; list; list = list->next) {
- list->thunkobj->flags |= OBJECT_DEFINED;
- CodeGen_GenVDispatchThunk(list->thunkobj, list->obj, list->a, list->b, list->c);
- }
-}
-
-static Object *CClass_ThunkObject(Object *obj, SInt32 a, SInt32 b, SInt32 c) {
- Object *thunkobj;
- ThunkList *list;
-
- CInline_ObjectAddrRef(obj);
- for (list = cclass_thunklist; list; list = list->next) {
- if (obj == list->obj && a == list->a && b == list->b && c == list->c)
- return list->thunkobj;
- }
-
- thunkobj = CParser_NewCompilerDefFunctionObject();
- thunkobj->name = CMangler_ThunkName(obj, a, b, c);
- thunkobj->type = TYPE(&rt_func);
- thunkobj->sclass = TK_EXTERN;
- thunkobj->qual = Q_20000;
- thunkobj->u.func.linkname = thunkobj->name;
-
- list = galloc(sizeof(ThunkList));
- list->thunkobj = thunkobj;
- list->obj = obj;
- list->a = a;
- list->b = b;
- list->c = c;
- list->next = cclass_thunklist;
- cclass_thunklist = list;
-
- return thunkobj;
-}
-
-static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) {
- while (1) {
- if (a == b)
- return 1;
-
- if (!a->bases || a->bases->is_virtual)
- return 0;
-
- a = a->bases->base;
- }
-}
-
-static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB, Boolean errorflag) {
- TypeClass *tclassA;
- TypeClass *tclassB;
-
- if (
- IS_TYPE_POINTER_ONLY(a) &&
- IS_TYPE_POINTER_ONLY(b) &&
- TPTR_QUAL(a) == TPTR_QUAL(b) &&
- !CParser_IsMoreCVQualified(qualB, qualA) &&
- IS_TYPE_CLASS(TPTR_TARGET(a)) &&
- IS_TYPE_CLASS(TPTR_TARGET(b))
- )
- {
- tclassA = TYPE_CLASS(TPTR_TARGET(a));
- tclassB = TYPE_CLASS(TPTR_TARGET(b));
- if (tclassA == tclassB || CClass_IsBaseClass(tclassB, tclassA, NULL, errorflag, errorflag)) {
- if (!CClass_IsZeroOffsetClass(tclassB, tclassA))
- return 2;
- else
- return 1;
- }
- }
-
- return 0;
-}
-
-UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) {
- if (!a->args || !b->args)
- return 0;
-
- if (
- (a->flags & FUNC_CALL_CONV_MASK) != (b->flags & FUNC_CALL_CONV_MASK) ||
- !is_arglistsame(a->args->next, b->args->next) ||
- a->args->qual != b->args->qual
- )
- return 0;
-
- if (!is_typesame(a->functype, b->functype)) {
- switch (CClass_IsCovariantResult(a->functype, a->qual, b->functype, b->qual, errorflag)) {
- case 0:
- if (errorflag)
- CError_Error(CErrorStr227);
- return 0;
- case 1:
- return 1;
- case 2:
- return 2;
- default:
- CError_FATAL(225);
- }
- }
-
- return 1;
-}
-
-Boolean CClass_IsEmpty(TypeClass *tclass) {
- ClassList *base;
-
- if (tclass->ivars)
- return 0;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!CClass_IsEmpty(base->base))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_IsNonStaticMemberFunc(TypeFunc *tfunc) {
- return IS_TYPEFUNC_NONSTATIC_METHOD(tfunc) || (tfunc->flags & FUNC_FLAGS_80);
-}
-
-Object *CClass_DefaultConstructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- if (TYPE_FUNC(object->type)->args->next && !TYPE_FUNC(object->type)->args->next->next)
- return object;
- } else {
- if (!TYPE_FUNC(object->type)->args->next)
- return object;
- }
- }
- }
-
- return NULL;
-}
-
-Object *CClass_DummyDefaultConstructor(TypeClass *tclass) {
- Object *ctor;
- FuncArg *args;
- NameSpaceObjectList *nsol;
- HashNameNode *name;
- TypeMemberFunc *tmethod;
- Object *object;
- ObjectList list;
-
- ctor = NULL;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(305, args = TYPE_FUNC(object->type)->args);
- args = args->next;
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- CError_ASSERT(309, args);
- args = args->next;
- }
- CError_ASSERT(312, args);
-
- if (args->dexpr) {
- if (ctor) {
- list.next = NULL;
- list.object = object;
- CError_OverloadedFunctionError(ctor, &list);
- break;
- }
- ctor = object;
- }
- }
- }
-
- if (!ctor) {
- CError_Error(CErrorStr203);
- return NULL;
- }
-
- name = GetHashNameNodeExport("__defctor");
- if ((nsol = CScope_FindName(tclass->nspace, name))) {
- CError_ASSERT(339, nsol->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(nsol->object)->type));
- return OBJECT(nsol->object);
- }
-
- tmethod = galloc(sizeof(TypeMemberFunc));
- memclrw(tmethod, sizeof(TypeMemberFunc));
-
- tmethod->type = TYPEFUNC;
- tmethod->functype = TYPE(&void_ptr);
- tmethod->flags = FUNC_METHOD;
- tmethod->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmethod), 0);
-
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo)
- CDecl_AddArgument(TYPE_FUNC(tmethod), TYPE(&stsignedshort));
-
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmethod), tclass);
-
- object = CParser_NewCompilerDefFunctionObject();
- object->type = TYPE(tmethod);
- object->qual = Q_INLINE | Q_MANGLE_NAME;
- object->nspace = tclass->nspace;
- object->name = name;
-
- CScope_AddObject(tclass->nspace, name, OBJ_BASE(object));
- CParser_RegisterDummyCtorFunction(object, ctor);
- return object;
-}
-
-ENode *CClass_DefaultConstructorCall(TypeClass *tclass, TypeClass *b, ENode *objexpr, SInt32 varg, Boolean flag1, Boolean flag2, Boolean *errorflag) {
- NameSpaceObjectList *nsol;
- Object *ctor;
- Object *object;
- FuncArg *args;
- ENodeList *argexprs;
- ENode *expr;
- BClassList *path;
- BClassList list1;
- ObjectList objlist;
- BClassList list2;
- short founddepth;
- Boolean isambigbase;
-
- *errorflag = 0;
-
- if (!(nsol = CScope_FindName(tclass->nspace, constructor_name_node)))
- return NULL;
-
- ctor = NULL;
- do {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(397, args = TYPE_FUNC(object->type)->args);
-
- args = args->next;
-
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- CError_ASSERT(401, args);
- args = args->next;
- }
-
- if (!args || args->dexpr) {
- if (ctor) {
- objlist.next = NULL;
- objlist.object = object;
- CError_OverloadedFunctionError(ctor, &objlist);
- break;
- }
- ctor = object;
- }
- }
- } while ((nsol = nsol->next));
-
- if (!ctor) {
- *errorflag = 1;
- return NULL;
- }
-
- if (flag1) {
- if (b) {
- if (flag2) {
- if ((path = CClass_GetBasePath(b, tclass, &founddepth, &isambigbase)))
- list1 = *path;
- else
- goto skipCheck;
- } else {
- list1.next = &list2;
- list1.type = TYPE(b);
- list2.next = NULL;
- list2.type = TYPE(tclass);
- }
- } else {
- list1.next = NULL;
- list1.type = TYPE(tclass);
- }
- CClass_CheckPathAccess(&list1, ctor, ctor->access);
- }
-
-skipCheck:
- if ((tclass->flags & CLASS_HAS_VBASES) && !tclass->sominfo) {
- argexprs = lalloc(sizeof(ENodeList));
- argexprs->next = NULL;
- argexprs->node = intconstnode(TYPE(&stsignedshort), varg);
- } else {
- argexprs = NULL;
- }
-
- CError_ASSERT(471, IS_TYPE_POINTER_ONLY(objexpr->rtype));
-
- objexpr = makemonadicnode(objexpr, EINDIRECT);
- objexpr->rtype = TYPE(tclass);
-
- list1.next = NULL;
- list1.type = TYPE(tclass);
-
- expr = CExpr_GenericFuncCall(
- &list1,
- objexpr,
- 0,
- ctor,
- NULL,
- NULL,
- argexprs,
- 0,
- 0,
- 0
- );
-
- if (ENODE_IS2(expr, EFUNCCALL, EFUNCCALLP))
- expr->rtype = CDecl_NewPointerType(TYPE(tclass));
-
- return expr;
-}
-
-Object *CClass_AssignmentOperator(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
-
- for (nsol = CScope_FindName(tclass->nspace, asop_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (
- object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(object->type) &&
- TYPE_FUNC(object->type)->args &&
- TYPE_FUNC(object->type)->args->next &&
- !TYPE_FUNC(object->type)->args->next->next
- )
- {
- if (
- IS_TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) &&
- TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) == tclass
- )
- return object;
-
- if (
- IS_TYPE_REFERENCE(TYPE_FUNC(object->type)->args->next->type) &&
- TPTR_TARGET(TYPE_FUNC(object->type)->args->next->type) == TYPE(tclass)
- )
- return object;
- }
- }
-
- return NULL;
-}
-
-Object *CClass_CopyConstructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
- FuncArg *args;
-
- if (tclass->sominfo)
- return NULL;
-
- for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- CError_ASSERT(532, args = TYPE_FUNC(object->type)->args);
-
- args = args->next;
-
- if (tclass->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(536, args);
- args = args->next;
- }
-
- if (
- args &&
- args != &elipsis &&
- (!args->next || args->next->dexpr) &&
- IS_TYPE_REFERENCE(args->type) &&
- TPTR_TARGET(args->type) == TYPE(tclass)
- )
- return object;
- }
- }
-
- return NULL;
-}
-
-NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) {
- NameSpaceObjectList *nsol;
-
- if ((nsol = CScope_FindName(tclass->nspace, name)) && nsol->object->otype == OT_OBJECT)
- return nsol;
-
- return NULL;
-}
-
-NameSpaceObjectList *CClass_Constructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
-
- if (
- (nsol = CScope_FindName(tclass->nspace, constructor_name_node)) &&
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type)
- )
- return nsol;
-
- return NULL;
-}
-
-Object *CClass_Destructor(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
-
- for (nsol = CScope_FindName(tclass->nspace, destructor_name_node); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type)
- )
- return OBJECT(nsol->object);
- }
-
- return NULL;
-}
-
-Boolean CClass_IsConstructor(Object *obj) {
- return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_CTOR);
-}
-
-Boolean CClass_IsDestructor(Object *obj) {
- return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_DTOR);
-}
-
-Boolean CClass_IsPODClass(TypeClass *tclass) {
- NameSpaceObjectList *nsol;
- Object *object;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->bases || CClass_Destructor(tclass))
- return 0;
-
- for (nsol = CClass_Constructor(tclass); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(OBJECT(nsol->object)->type) &&
- !(TYPE_FUNC(OBJECT(nsol->object)->type)->flags & FUNC_AUTO_GENERATED)
- )
- return 0;
- }
-
- object = CClass_AssignmentOperator(tclass);
- if (object && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->access != ACCESSPUBLIC)
- return 0;
-
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- switch (type->type) {
- case TYPECLASS:
- if (!CClass_IsPODClass(TYPE_CLASS(type)))
- return 0;
- break;
- case TYPEMEMBERPOINTER:
- return 0;
- case TYPEPOINTER:
- if (TPTR_QUAL(type) & Q_REFERENCE)
- return 0;
- break;
- }
- }
-
- return 1;
-}
-
-Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) {
- Object *object;
- ClassList *base;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->vbases || CClass_Destructor(tclass))
- return 0;
-
- object = CClass_CopyConstructor(tclass);
- if (object && IS_TYPE_FUNC(object->type) && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!CClass_IsTrivialCopyClass(base->base))
- return 0;
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyClass(TYPE_CLASS(type)))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) {
- Object *object;
- ObjMemberVar *ivar;
- Type *type;
-
- if (tclass->vtable || tclass->bases || CClass_Destructor(tclass))
- return 0;
-
- object = CClass_AssignmentOperator(tclass);
- if (object && !(TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED))
- return 0;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_REFERENCE(type))
- return 0;
- if (CParser_IsConst(type, ivar->qual))
- return 0;
- if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyAssignClass(TYPE_CLASS(type)))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CClass_ReferenceArgument(TypeClass *tclass) {
- if ((tclass->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(tclass));
-
- if (copts.simple_class_byval)
- return !CClass_IsTrivialCopyClass(tclass);
-
- return CClass_Destructor(tclass) || CClass_CopyConstructor(tclass);
-}
-
-BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) {
- BClassList *last;
- BClassList *copy;
-
- if (!path)
- return NULL;
-
- copy = last = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList));
- last->next = path->next;
- last->type = path->type;
-
- while ((path = path->next)) {
- last->next = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList));
- last = last->next;
- last->next = path->next;
- last->type = path->type;
- }
-
- return copy;
-}
-
-BClassList *CClass_AppendPath(BClassList *dest, BClassList *src) {
- BClassList *last;
-
- if (!(last = dest))
- return src;
-
- while (last->next)
- last = last->next;
-
- while (src && src->type == last->type)
- src = src->next;
-
- last->next = src;
- return dest;
-}
-
-static AccessType CClass_GetPathAccess(BClassList *path) {
- AccessType result;
- ClassList *base;
- TypeClass *tclass;
-
- CError_ASSERT(930, path);
-
- result = ACCESSPUBLIC;
-
- while (1) {
- tclass = TYPE_CLASS(path->type);
- if (!(path = path->next))
- break;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->type))
- break;
- }
-
- CError_ASSERT(939, base);
-
- switch (base->access) {
- case ACCESSPUBLIC:
- break;
- case ACCESSPROTECTED:
- if (result == ACCESSPUBLIC)
- result = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (result == ACCESSPUBLIC || result == ACCESSPROTECTED)
- result = ACCESSPRIVATE;
- else
- return ACCESSNONE;
- break;
- case ACCESSNONE:
- return ACCESSNONE;
- default:
- CError_FATAL(960);
- }
- }
-
- return result;
-}
-
-Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) {
- switch (CClass_GetPathAccess(path2)) {
- case ACCESSPUBLIC:
- return 0;
- case ACCESSNONE:
- return 1;
- default:
- CError_FATAL(978);
- case ACCESSPROTECTED:
- switch (CClass_GetPathAccess(path1)) {
- case ACCESSPUBLIC:
- return 1;
- case ACCESSPRIVATE:
- case ACCESSPROTECTED:
- case ACCESSNONE:
- return 0;
- default:
- CError_FATAL(987);
- }
- case ACCESSPRIVATE:
- switch (CClass_GetPathAccess(path1)) {
- case ACCESSPUBLIC:
- case ACCESSPROTECTED:
- return 1;
- case ACCESSPRIVATE:
- case ACCESSNONE:
- return 0;
- default:
- CError_FATAL(997);
- }
- }
-
- return 0;
-}
-
-static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) {
- ClassList *base;
- BClassList *checkpath;
- BClassList *bestpath;
- BClassList *newpath;
- SInt32 newOffset;
-
- for (base = a->bases, bestpath = NULL; base; base = base->next) {
- if (base->is_virtual)
- newOffset = CClass_VirtualBaseOffset(cclass_isbase_mostderived, base->base);
- else
- newOffset = offset + base->offset;
-
- if (base->base == b) {
- if (cclass_founddepth && newOffset != cclass_isbase_foundoffset) {
- cclass_isambigbase = 1;
- return NULL;
- }
-
- cclass_isbase_foundoffset = newOffset;
- cclass_founddepth = depth;
-
- bestpath = lalloc(sizeof(BClassList));
- bestpath->next = NULL;
- bestpath->type = TYPE(b);
- } else if ((checkpath = CClass_GetBasePathRec(base->base, b, newOffset, depth + 1))) {
- newpath = lalloc(sizeof(BClassList));
- newpath->next = checkpath;
- newpath->type = TYPE(base->base);
- if (!bestpath || CClass_IsMoreAccessiblePath(newpath, bestpath))
- bestpath = newpath;
- }
- }
-
- return bestpath;
-}
-
-BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) {
- BClassList *path;
- BClassList *result;
-
- if ((a->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(a));
- if ((b->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CDecl_CompleteType(TYPE(b));
-
- cclass_founddepth = 0;
- cclass_isbase_mostderived = a;
- cclass_isbase_foundoffset = -1;
- cclass_isambigbase = 0;
-
- if ((path = CClass_GetBasePathRec(a, b, 0, 1))) {
- *founddepth = cclass_founddepth;
- *isambigbase = cclass_isambigbase;
-
- result = lalloc(sizeof(BClassList));
- result->next = path;
- result->type = TYPE(a);
- return result;
- } else {
- *isambigbase = 0;
- return NULL;
- }
-}
-
-Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) {
- BClassList *path;
- short depth;
- Boolean isambigbase;
-
- if ((path = CClass_GetBasePath(a, b, &depth, &isambigbase))) {
- if (isambigbase && ambigerrorflag)
- CError_Error(CErrorStr188);
-
- if (pathcheckflag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
-
- if (founddepth)
- *founddepth = depth;
-
- return 1;
- }
-
- return 0;
-}
-
-TypeClass *CClass_GetQualifiedClass(void) {
- DeclInfo di;
-
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (IS_TYPE_CLASS(di.thetype))
- return TYPE_CLASS(di.thetype);
-
- return NULL;
-}
-
-ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean reverse) {
- ClassList *base;
- SInt32 offset;
-
- while (path && path->next) {
- base = TYPE_CLASS(path->type)->bases;
- while (1) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- CError_ASSERT(1157, base = base->next);
- }
-
- if (base->is_virtual) {
- if (reverse) {
- CError_Error(CErrorStr164);
- break;
- }
-
- if (!base->base->sominfo) {
- offset = base->offset;
- if (offset && !canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
-
- expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(TYPE(base->base)));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = expr->data.monadic->rtype;
- }
- } else {
- offset = base->offset;
- if (offset) {
- if (reverse)
- offset = -offset;
- if (!canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
- }
- }
-
- path = path->next;
- }
-
- return expr;
-}
-
-ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) {
- BClassList *path;
- Boolean reverse;
- short depth;
- Boolean isambigbase;
-
- reverse = 0;
-
- if (a != b) {
- if (!(path = CClass_GetBasePath(a, b, &depth, &isambigbase))) {
- CError_ASSERT(1216, typconflag);
- if ((path = CClass_GetBasePath(b, a, &depth, &isambigbase))) {
- reverse = 1;
- goto doCast;
- }
- } else {
- doCast:
- if (isambigbase && ambigerrorflag)
- CError_Error(CErrorStr188);
- if (pathcheckflag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
- if (!(a->flags & CLASS_SINGLE_OBJECT) && !b->sominfo)
- expr = CClass_AccessPathCast(path, expr, reverse);
- }
- }
-
- if (typconflag && ENODE_IS(expr, EINDIRECT) && IS_TYPE_POINTER_ONLY(expr->rtype))
- expr = makemonadicnode(expr, ETYPCON);
-
- return expr;
-}
-
-ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) {
- ClassList *base;
- VClassList *vbase;
- BClassList *path;
- BClassList list1;
- BClassList list2;
- short depth;
- Boolean isambigbase;
-
- for (base = a->bases; base; base = base->next) {
- if (base->base == b) {
- list1.next = &list2;
- list1.type = TYPE(a);
- list2.next = NULL;
- list2.type = TYPE(b);
- return CClass_AccessPathCast(&list1, expr, 0);
- }
- }
-
- for (vbase = a->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == b) {
- CError_ASSERT(1273, path = CClass_GetBasePath(a, b, &depth, &isambigbase));
- return CClass_AccessPathCast(path, expr, 0);
- }
- }
-
- CError_FATAL(1277);
- return expr;
-}
-
-SInt32 CClass_GetPathOffset(BClassList *path) {
- SInt32 offset;
- ClassList *base;
-
- offset = 0;
-
- while (path->next) {
- if (path->type != path->next->type) {
- for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- }
-
- if (!base) {
- CError_Error(CErrorStr221);
- return offset;
- }
- }
-
- if (base->is_virtual)
- return -1;
- offset += base->offset;
-
- path = path->next;
- }
-
- return offset;
-}
-
-Boolean CClass_ClassDominates(TypeClass *tclass, TypeClass *baseclass) {
- ClassList *base;
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == baseclass || CClass_ClassDominates(base->base, baseclass))
- return 1;
- }
-
- return 0;
-}
-
-SInt32 CClass_VirtualBaseOffset(TypeClass *tclass, TypeClass *baseclass) {
- VClassList *vbase;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == baseclass)
- return vbase->offset;
- }
-
- CError_FATAL(1342);
- return 0;
-}
-
-SInt32 CClass_VirtualBaseVTableOffset(TypeClass *tclass, TypeClass *baseclass) {
- VClassList *vbase;
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == baseclass)
- return vbase->voffset;
- }
-
- CError_FATAL(1359);
- return 0;
-}
-
-SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **resultIvar) {
- ObjMemberVar *ivar;
- ClassList *base;
- SInt32 offset;
- SInt32 tmp;
- Boolean foundflag;
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->name == name) {
- if (resultIvar)
- *resultIvar = ivar;
- return ivar->offset;
- }
- }
-
- for (base = tclass->bases, foundflag = 0; base; base = base->next) {
- switch ((tmp = CClass_GetMemberOffset(base->base, name, resultIvar))) {
- case -3:
- case -2:
- return tmp;
- case -1:
- break;
- default:
- if (base->is_virtual)
- return -3;
- if (foundflag)
- return -2;
- foundflag = 1;
- offset = base->offset + tmp;
- }
- }
-
- return foundflag ? offset : -1;
-}
-
-Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) {
- NameSpaceObjectList *nsol;
- ClassList *base;
- Boolean result;
-
- result = 0;
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable) {
- for (nsol = CScope_FindName(base->base->nspace, name); nsol; nsol = nsol->next) {
- if (
- nsol->object->otype == OT_OBJECT &&
- OBJECT(nsol->object)->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(OBJECT(nsol->object)->type), TYPE_FUNC(obj->type), 1)
- )
- result = 1;
- }
-
- if (CClass_OverridesBaseMember(base->base, name, obj))
- result = 1;
- }
- }
-
- return result;
-}
-
-static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) {
- OVClassBase *ovbase;
-
- if (ovclass->tclass == tclass && ovclass->offset == offset)
- return ovclass;
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) {
- if ((ovclass = CClass_FindOVClass(ovbase->ovclass, tclass, offset)))
- return ovclass;
- }
-
- return NULL;
-}
-
-static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) {
- ClassList *base;
- Object *object;
- OVClass *tree;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
- SInt32 vboffset;
- SInt32 vbvoffset;
- CScopeObjectIterator iter;
-
- tree = lalloc(sizeof(OVClass));
- memclrw(tree, sizeof(OVClass));
-
- tree->tclass = tclass;
- tree->offset = offset;
- tree->voffset = voffset;
- if (!root)
- root = tree;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- ovfunc = lalloc(sizeof(OVFunc));
- memclrw(ovfunc, sizeof(OVFunc));
-
- ovfunc->next = tree->vfuncs;
- ovfunc->obj = object;
- tree->vfuncs = ovfunc;
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable || base->base->sominfo) {
- ovbase = lalloc(sizeof(OVClassBase));
- memclrw(ovbase, sizeof(OVClassBase));
-
- if (base->is_virtual) {
- vboffset = CClass_VirtualBaseOffset(main_class, base->base);
- if (!(ovbase->ovclass = CClass_FindOVClass(root, base->base, vboffset))) {
- vbvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base);
- ovbase->ovclass = CClass_BuildOVClassTree(root, base->base, vboffset, vbvoffset);
- }
- ovbase->is_virtual = 1;
- } else {
- ovbase->ovclass = CClass_BuildOVClassTree(
- root,
- base->base,
- offset + base->offset,
- voffset + base->voffset);
- ovbase->is_virtual = 0;
- }
-
- ovbase->next = tree->bases;
- tree->bases = ovbase;
- }
- }
-
- return tree;
-}
-
-static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) {
- OVClassBase *ovbase;
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next) {
- if (
- (ovbase->ovclass->tclass == a->tclass && ovbase->ovclass->offset == a->offset) ||
- CClass_IsBaseOf(a, ovbase->ovclass)
- )
- {
- if (!cclass_ovbase && ovbase->is_virtual)
- cclass_ovbase = ovbase->ovclass;
- return 1;
- }
- }
-
- return 0;
-}
-
-static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) {
- OVFunc *scan;
- OVClassBase *ovbase;
- UInt8 overrideKind;
-
- if (CClass_IsBaseOf(b, a)) {
- for (scan = a->vfuncs; scan; scan = scan->next) {
- if (
- (func->obj->name == scan->obj->name) &&
- (overrideKind = CClass_GetOverrideKind(TYPE_FUNC(func->obj->type), TYPE_FUNC(scan->obj->type), 0))
- )
- {
- if (func->ovc8) {
- if (func->ovc8->tclass == a->tclass || CClass_ClassDominates(func->ovc8->tclass, a->tclass))
- return;
- if (!CClass_ClassDominates(a->tclass, func->ovc8->tclass)) {
- func->ovf10 = scan;
- return;
- }
- }
-
- if (a == cclass_root) {
- TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_20;
- if (overrideKind == 2)
- TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_400000;
- }
-
- func->ovc8 = a;
- func->ovfC = scan;
- func->ovf10 = NULL;
- return;
- }
- }
-
- for (ovbase = a->bases; ovbase; ovbase = ovbase->next)
- CClass_FindOVFunc(ovbase->ovclass, b, func);
- }
-}
-
-static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) {
- Object *object;
- TypeList *scan;
- Type *type;
- ClassList *base;
- CScopeObjectIterator iter;
-
- if (!flag) {
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- object->name == func->name &&
- object->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(object->type), TYPE_FUNC(func->type), 0) == 2
- )
- {
- CError_ASSERT(1686,
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->functype) &&
- IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(object->type)->functype)));
-
- type = TPTR_TARGET(TYPE_FUNC(object->type)->functype);
- for (scan = list; scan; scan = scan->next) {
- if (scan->type == type)
- break;
- }
-
- if (!scan) {
- scan = lalloc(sizeof(TypeList));
- scan->type = type;
- scan->next = list;
- list = scan;
- }
- }
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable)
- list = CClass_GetCoVariantClassList(list, base->base, func, 0);
- }
-
- return list;
-}
-
-static TypeMemberFunc *CClass_GetCovariantType(TypeMemberFunc *tmethod, Type *type) {
- TypePointer *tptr;
- TypeMemberFunc *result;
-
- CError_ASSERT(1724,
- IS_TYPE_METHOD(tmethod) &&
- IS_TYPE_POINTER_ONLY(tmethod->functype));
-
- tptr = galloc(sizeof(TypePointer));
- *tptr = *TYPE_POINTER(tmethod->functype);
- tptr->target = type;
-
- result = galloc(sizeof(TypeMemberFunc));
- *result = *tmethod;
- result->flags &= ~(FUNC_FLAGS_20 | FUNC_FLAGS_400000);
- result->functype = TYPE(tptr);
- return result;
-}
-
-static Object *CClass_FindCovariantFunction(Object *func, Type *type) {
- NameSpaceObjectList *nsol;
-
- nsol = CScope_FindName(
- TYPE_METHOD(func->type)->theclass->nspace,
- CMangler_GetCovariantFunctionName(func, TYPE_CLASS(type)));
-
- CError_ASSERT(1754, nsol && !nsol->next && nsol->object->otype == OT_OBJECT);
-
- return OBJECT(nsol->object);
-}
-
-static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) {
- Object *newfunc;
- HashNameNode *name;
- TypeList *types;
- ObjectList *newlist;
-
- for (types = CClass_GetCoVariantClassList(NULL, tclass, func, 1); types; types = types->next) {
- name = CMangler_GetCovariantFunctionName(func, TYPE_CLASS(types->type));
-
- newfunc = galloc(sizeof(Object));
- memclrw(newfunc, sizeof(Object));
-
- newfunc->otype = OT_OBJECT;
- newfunc->datatype = DFUNC;
- newfunc->section = func->section;
- newfunc->nspace = func->nspace;
- newfunc->name = name;
- newfunc->type = TYPE(CClass_GetCovariantType(TYPE_METHOD(func->type), types->type));
- newfunc->qual = func->qual & ~Q_INLINE;
- newfunc->sclass = func->sclass;
- newfunc->u.func.linkname = name;
-
- newlist = lalloc(sizeof(ObjectList));
- newlist->object = newfunc;
- newlist->next = list;
- list = newlist;
- }
-
- return list;
-}
-
-void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) {
- NameSpace *nspace;
- TypeList *types;
- Object *covariantFunc;
- Statement *stmt;
- Type *tptr;
- Statement firstStmt;
-
- for (types = CClass_GetCoVariantClassList(NULL, TYPE_METHOD(method->type)->theclass, method, 1); types; types = types->next) {
- covariantFunc = CClass_FindCovariantFunction(method, types->type);
- tptr = CDecl_NewPointerType(types->type);
-
- nspace = CFunc_FuncGenSetup(&firstStmt, covariantFunc);
- CInline_UnpackIFunctionData(covariantFunc, ifuncdata, &firstStmt);
-
- for (stmt = &firstStmt; stmt; stmt = stmt->next) {
- if (stmt->type == ST_RETURN && stmt->expr)
- stmt->expr = CExpr_AssignmentPromotion(stmt->expr, tptr, ENODE_QUALS(stmt->expr), 0);
- }
-
- CFunc_Gen(&firstStmt, covariantFunc, 0);
- cscope_current = nspace->parent;
- }
-}
-
-static void CClass_OverrideOVClassTree(OVClass *ovclass) {
- OVClassBase *ovbase;
- OVFunc *ovfunc;
-
- if (cclass_root != ovclass) {
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next)
- CClass_FindOVFunc(cclass_root, ovclass, ovfunc);
- }
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next)
- CClass_OverrideOVClassTree(ovbase->ovclass);
-}
-
-static void CClass_AllocVTableRec(OVClass *ovclass) {
- OVFunc *ovfunc;
- Object *object;
- SInt32 offset27;
- SInt32 offset26;
- SInt32 offset23;
- OVClassBase *ovbase;
- OLinkList *link;
-
- if (ovclass->alloced_vtable)
- return;
-
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- offset27 = ovclass->voffset + TYPE_METHOD(ovfunc->obj->type)->vtbl_index + CABI_GetVTableOffset(ovclass->tclass);
- CError_ASSERT(1867, offset27 < vtable_data_size);
-
- if (!(vtable_object_data[offset27])) {
- if (ovfunc->ovfC) {
- object = ovfunc->ovfC->obj;
- if (
- (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000) &&
- CClass_GetOverrideKind(TYPE_FUNC(ovfunc->obj->type), TYPE_FUNC(object->type), 0) == 2
- )
- {
- CError_ASSERT(1887,
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(ovfunc->obj->type)->functype) &&
- IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype)));
- object = CClass_FindCovariantFunction(
- object,
- TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype));
- }
-
- if ((offset26 = ovfunc->ovc8->offset - ovclass->offset)) {
- if (!(TYPE_FUNC(object->type)->flags & FUNC_PURE)) {
- cclass_ovbase = NULL;
- CError_ASSERT(1899, CClass_IsBaseOf(ovclass, ovfunc->ovc8));
-
- if (cclass_ovbase && (main_class->flags & CLASS_FLAGS_8000)) {
- offset23 = ovclass->offset - cclass_ovbase->offset;
- offset23 = CABI_GetCtorOffsetOffset(cclass_ovbase->tclass, NULL) - offset23;
- CError_ASSERT(1906, offset23 > 0);
- object = CClass_ThunkObject(object, offset26, 0, offset23);
- } else {
- object = CClass_ThunkObject(object, offset26, 0, -1);
- }
- }
- }
- } else {
- object = ovfunc->obj;
- }
-
- if (!(TYPE_FUNC(object->type)->flags & FUNC_PURE)) {
- link = lalloc(sizeof(OLinkList));
- link->next = vtable_object_links;
- link->obj = object;
- link->offset = offset27;
- link->somevalue = 0;
- vtable_object_links = link;
- vtable_object_data[offset27] = 1;
- }
- }
- }
-
- ovclass->alloced_vtable = 1;
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next)
- CClass_AllocVTableRec(ovbase->ovclass);
-}
-
-static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) {
- Object *object;
- Object *check;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
-
- object = NULL;
-
- for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovf10 && errorflag)
- CError_Error(CErrorStr251, main_class, 0, ovfunc->obj, ovfunc->ovfC->obj, ovfunc->ovf10->obj);
-
- if (!object) {
- check = ovfunc->ovfC ? ovfunc->ovfC->obj : ovfunc->obj;
- if (TYPE_FUNC(check->type)->flags & FUNC_PURE)
- object = check;
- }
- }
-
- for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) {
- if (object)
- CClass_CheckClass(ovbase->ovclass, errorflag);
- else
- object = CClass_CheckClass(ovbase->ovclass, errorflag);
- }
-
- return object;
-}
-
-static void CClass_AllocVTable(TypeClass *tclass) {
- OVClass *ovclass;
-
- main_class = tclass;
- ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = ovclass;
- CClass_OverrideOVClassTree(ovclass);
- CClass_CheckClass(ovclass, 1);
- CClass_AllocVTableRec(ovclass);
-}
-
-static Object *CClass_CheckVirtuals(TypeClass *tclass) {
- OVClass *ovclass;
-
- main_class = tclass;
- ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = ovclass;
- CClass_OverrideOVClassTree(ovclass);
- return CClass_CheckClass(ovclass, 0);
-}
-
-static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) {
- VClassList *vbase;
- OVFunc *ovfunc;
- OVClassBase *ovbase;
-
- if (flag) {
- for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovfC) {
- cclass_ovbase = NULL;
- CError_ASSERT(2040, CClass_IsBaseOf(b, ovfunc->ovc8));
-
- if (cclass_ovbase) {
- for (vbase = a->tclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == cclass_ovbase->tclass)
- break;
- }
-
- CError_ASSERT(2047, vbase);
- vbase->has_override = 1;
- }
- }
- }
- }
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next) {
- CClass_CheckVirtualBaseOverrides(a, ovbase->ovclass, flag || ovbase->is_virtual);
- }
-}
-
-static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) {
- OVClassBase *ovbase;
- OVFunc *ovfunc;
- Object *foundObject;
- Boolean isAlias;
- Object *object;
- CScopeObjectIterator iter;
-
- if (a != b) {
- for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) {
- if (ovfunc->ovc8 != a) {
- foundObject = NULL;
- isAlias = 0;
- CScope_InitObjectIterator(&iter, a->tclass->nspace);
-
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->name == ovfunc->obj->name && IS_TYPE_FUNC(object->type)) {
- if (object->datatype != DALIAS) {
- if (!(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20))
- foundObject = object;
- } else {
- if (object->u.alias.object == ovfunc->obj) {
- // don't show a warning if this is just an alias to the base function
- isAlias = 1;
- break;
- }
- }
- }
- }
-
- if (foundObject && !isAlias)
- CError_Warning(CErrorStr225, foundObject, ovfunc->obj);
- }
- }
- }
-
- for (ovbase = b->bases; ovbase; ovbase = ovbase->next)
- CClass_CheckHideVirtual(a, ovbase->ovclass);
-}
-
-void CClass_CheckOverrides(TypeClass *tclass) {
- OVClass *tree;
- Object *object;
- ObjectList *objlist;
- ClassList *base;
- VClassList *vbase;
- int i;
- CScopeObjectIterator iter;
-
- i = 0;
- for (base = tclass->bases; base; base = base->next) {
- base->offset = i;
- base->voffset = i;
- i++;
- }
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- vbase->offset = i;
- vbase->voffset = i;
- i++;
- }
-
- main_class = tclass;
- tree = CClass_BuildOVClassTree(NULL, tclass, 0, 0);
- cclass_root = tree;
-
- CClass_OverrideOVClassTree(tree);
- if (CClass_CheckClass(tree, 0))
- tclass->flags |= CLASS_ABSTRACT;
-
- if (copts.warn_hidevirtual)
- CClass_CheckHideVirtual(tree, tree);
-
- if (tclass->flags & CLASS_FLAGS_8000)
- CClass_CheckVirtualBaseOverrides(tree, tree, 0);
-
- objlist = NULL;
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- CError_ASSERT(2175, IS_TYPE_FUNC(object->type));
- if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000)
- objlist = CClass_DeclareCovariantFuncs(objlist, object, tclass);
- }
- }
-
- while (objlist) {
- CScope_AddObject(tclass->nspace, objlist->object->name, OBJ_BASE(objlist->object));
- objlist = objlist->next;
- }
-
- for (base = tclass->bases; base; base = base->next) {
- base->offset = 0;
- base->voffset = 0;
- }
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- vbase->offset = 0;
- vbase->voffset = 0;
- }
-}
-
-static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *tclass3) {
- Object *object;
- ClassList *base;
- CScopeObjectIterator iter;
-
- CScope_InitObjectIterator(&iter, tclass1->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- object->name == cclass_dominator_vobject->name &&
- object->datatype == DVFUNC &&
- CClass_GetOverrideKind(TYPE_FUNC(cclass_dominator_vobject->type), TYPE_FUNC(object->type), 0)
- )
- {
- if (object == cclass_dominator_vobject && offset1 == cclass_dominator_voffset) {
- if (object1) {
- if (cclass_dominator_oobject && cclass_dominator_ooffset != offset2) {
- if (CClass_ClassDominates(cclass_dominator_oclass, tclass2))
- return;
- if (!CClass_ClassDominates(tclass2, cclass_dominator_oclass)) {
- cclass_dominator_eobject = object1;
- cclass_vbase = tclass3;
- return;
- }
- }
-
- cclass_dominator_oobject = object1;
- cclass_dominator_ooffset = offset2;
- cclass_dominator_oclass = tclass2;
- cclass_dominator_eobject = NULL;
- cclass_vbase = tclass3;
- }
- return;
- } else {
- if (!object1) {
- object1 = object;
- tclass2 = tclass1;
- offset2 = offset1;
- }
- break;
- }
- }
- }
-
- for (base = tclass1->bases; base; base = base->next) {
- if (base->base->vtable) {
- if (!base->is_virtual) {
- CClass_FindDominator(base->base, offset1 + base->offset, object1, tclass2, offset2, tclass3);
- } else {
- SInt32 vboffset = CClass_VirtualBaseOffset(main_class, base->base);
- CClass_FindDominator(base->base, vboffset, object1, tclass2, offset2, base->base);
- }
- }
- }
-}
-
-static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *baseclass) {
- Object *object;
- Object *thunkobject;
- SInt32 newoffset;
- SInt32 newvoffset;
- ClassList *base;
- SInt32 thunkoffset;
- OLinkList *olink;
- CScopeObjectIterator iter;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (object->datatype == DVFUNC) {
- newoffset = voffset + TYPE_METHOD(object->type)->vtbl_index + CABI_GetVTableOffset(tclass);
- CError_ASSERT(2288, newoffset < vtable_data_size);
-
- if (!vtable_object_data[newoffset]) {
- cclass_dominator_vobject = object;
- cclass_dominator_voffset = offset;
- cclass_dominator_oobject = NULL;
- cclass_dominator_ooffset = offset;
- CClass_FindDominator(main_class, 0, NULL, NULL, 0, NULL);
-
- if (cclass_dominator_oobject) {
- if (cclass_dominator_eobject)
- CError_Error(CErrorStr251, main_class, 0, cclass_dominator_vobject, cclass_dominator_oobject, cclass_dominator_eobject);
- } else {
- cclass_dominator_oobject = object;
- cclass_vbase = NULL;
- }
-
- vtable_object_data[newoffset] = 1;
-
- if (!(TYPE_FUNC(cclass_dominator_oobject->type)->flags & FUNC_PURE)) {
- if (!check_pures) {
- thunkobject = cclass_dominator_oobject;
- if ((thunkoffset = cclass_dominator_ooffset - offset)) {
- if (cclass_vbase && (main_class->flags & CLASS_FLAGS_8000)) {
- thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0,
- CABI_GetCtorOffsetOffset(cclass_vbase, tclass));
- } else {
- thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0, -1);
- }
- }
-
- olink = lalloc(sizeof(OLinkList));
- olink->next = vtable_object_links;
- olink->obj = thunkobject;
- olink->offset = newoffset;
- olink->somevalue = 0;
- vtable_object_links = olink;
- }
- } else {
- found_pure = cclass_dominator_oobject;
- }
- }
- }
- }
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable) {
- if (base->is_virtual) {
- newoffset = CClass_VirtualBaseOffset(main_class, base->base);
- newvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base);
- CClass_ConstructVTable(
- base->base,
- newvoffset,
- newoffset,
- base->base
- );
- } else {
- CClass_ConstructVTable(
- base->base,
- voffset + base->voffset,
- offset + base->offset,
- baseclass
- );
- }
- }
- }
-}
-
-void CClass_ClassDefaultFuncAction(TypeClass *tclass) {
-}
-
-void CClass_ClassAction(TypeClass *tclass) {
- if (tclass->sominfo) {
- CSOM_GenerateClassStructures(tclass);
- } else if (tclass->vtable) {
- vtable_data_size = tclass->vtable->size;
- vtable_object_data = lalloc(vtable_data_size);
- memclrw(vtable_object_data, vtable_data_size);
-
- main_class = tclass;
- vtable_object_links = NULL;
- found_pure = NULL;
- check_pures = 0;
-
- CClass_AllocVTable(tclass);
-
- memclrw(vtable_object_data, vtable_data_size);
- if (copts.RTTI && !(tclass->flags & (CLASS_SINGLE_OBJECT | CLASS_COM_OBJECT)))
- vtable_object_links = CRTTI_ConstructVTableHeaders(tclass, vtable_object_data, vtable_object_links);
-
- CError_ASSERT(2492, tclass->vtable->object->type->size == tclass->vtable->size);
- CInit_DeclareData(tclass->vtable->object, vtable_object_data, vtable_object_links, tclass->vtable->size);
- }
-}
-
-void CClass_MakeStaticActionClass(TypeClass *tclass) {
- if (tclass->vtable) {
- tclass->vtable->object->sclass = TK_STATIC;
- tclass->vtable->object->qual |= Q_20000;
- if (!(tclass->vtable->object->flags & OBJECT_FLAGS_2)) {
- CParser_NewCallBackAction(tclass->vtable->object, tclass);
- } else if (cparamblkptr->precompile != 1) {
- CParser_NewClassAction(tclass);
- }
- }
-}
-
-Object *CClass_CheckPures(TypeClass *tclass) {
- return CClass_CheckVirtuals(tclass);
-}
-
-void CClass_MemberDef(Object *obj, TypeClass *tclass) {
- switch (tclass->action) {
- case CLASS_ACTION_0:
- break;
- case CLASS_ACTION_1:
- if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_4)) {
- if (obj->qual & Q_INLINE) {
- if (tclass->sominfo)
- CError_Error(CErrorStr280);
- tclass->action = CLASS_ACTION_0;
- CClass_MakeStaticActionClass(tclass);
- } else if (cparamblkptr->precompile != 1) {
- CParser_NewClassAction(tclass);
- }
- }
- break;
- case CLASS_ACTION_2:
- CError_FATAL(2682);
- break;
- case CLASS_ACTION_3:
- break;
- default:
- CError_FATAL(2701);
- }
-}
-
-Object *CClass_ThisSelfObject(void) {
- ObjectList *list;
-
- if (cscope_currentfunc && cscope_currentclass) {
- if (cscope_currentclass->objcinfo) {
- for (list = arguments; list; list = list->next) {
- if (list->object->name == self_name_node)
- return list->object;
- }
- CError_Error(CErrorStr301);
- } else {
- if (cscope_is_member_func) {
- for (list = arguments; list; list = list->next) {
- if (list->object->name == this_name_node)
- return list->object;
- }
- }
- CError_Error(CErrorStr189);
- }
- }
-
- CError_Error(copts.cplusplus ? CErrorStr189 : CErrorStr301);
- return NULL;
-}
-
-ENode *CClass_CreateThisSelfExpr(void) {
- Object *object;
- ENode *expr;
-
- if (!(object = CClass_ThisSelfObject()))
- return NULL;
-
- expr = create_objectrefnode(object);
- expr->rtype = CDecl_NewPointerType(TYPE(cscope_currentclass));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
-
- return expr;
-}
-
-static AccessType CClass_BaseMemberAccess(BClassList *path, AccessType access) {
- ClassList *base;
-
- if (path->next) {
- access = CClass_BaseMemberAccess(path->next, access);
- switch (access) {
- case ACCESSPRIVATE:
- case ACCESSNONE:
- return ACCESSNONE;
- }
-
- for (base = TYPE_CLASS(path->type)->bases; ; base = base->next) {
- if (!base)
- return ACCESSNONE;
-
- if (base->base == TYPE_CLASS(path->next->type)) {
- switch (base->access) {
- case ACCESSNONE:
- access = ACCESSNONE;
- break;
- case ACCESSPROTECTED:
- if (access == ACCESSPUBLIC)
- access = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (access == ACCESSPRIVATE)
- access = ACCESSNONE;
- else
- access = ACCESSPRIVATE;
- break;
- case ACCESSPUBLIC:
- break;
- }
- break;
- }
- }
- }
-
- return access;
-}
-
-static Boolean CClass_CanAccess(BClassList *path, AccessType access) {
- AccessType access2;
- BClassList *scan;
- BClassList *next;
- TypeClass *prevclass;
- TypeClass *tclass;
- ClassList *base;
- ClassFriend *cfriend;
-
- tclass = TYPE_CLASS(path->type);
- access2 = access;
- if ((scan = path->next)) {
- if (access2 != ACCESSPRIVATE) {
- prevclass = tclass;
- while (scan) {
- for (base = prevclass->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(scan->type))
- break;
- }
-
- if (!base)
- return 0;
-
- switch (base->access) {
- case ACCESSNONE:
- access2 = ACCESSNONE;
- break;
- case ACCESSPROTECTED:
- if (access2 == ACCESSPUBLIC)
- access2 = ACCESSPROTECTED;
- break;
- case ACCESSPRIVATE:
- if (access2 == ACCESSPRIVATE)
- access2 = ACCESSNONE;
- else
- access2 = ACCESSPRIVATE;
- break;
- case ACCESSPUBLIC:
- break;
- }
-
- prevclass = TYPE_CLASS(scan->type);
- scan = scan->next;
- }
- } else {
- access2 = ACCESSNONE;
- }
- }
-
- if (access2 == ACCESSPUBLIC)
- return 1;
-
- if (access2 != ACCESSNONE) {
- if (cscope_currentclass == tclass)
- return 1;
- if (cobjc_currentclass == tclass)
- return 1;
-
- for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) {
- if (cfriend->isclass) {
- if (cfriend->u.theclass == cscope_currentclass)
- return 1;
- } else {
- if (cfriend->u.obj == cscope_currentfunc)
- return 1;
- }
- }
- }
-
- for (scan = path; scan->next; scan = scan->next) {
- if (CClass_CanAccess(scan->next, access)) {
- if ((next = scan->next->next) || access != ACCESSPUBLIC) {
- scan->next->next = NULL;
- if (CClass_CanAccess(path, ACCESSPUBLIC)) {
- scan->next->next = next;
- return 1;
- }
- scan->next->next = next;
- }
- }
- }
-
- return 0;
-}
-
-void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) {
- if (!CClass_CanAccess(path, access)) {
- if (path && obj)
- CError_Error(CErrorStr381, path->type, 0, obj);
- else
- CError_Error(CErrorStr187);
- }
-}
-
-static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) {
- BClassList *first;
- ClassList *base;
-
- first = path;
-
- while (1) {
- if (!path->next) {
- if (!tclass)
- return first;
- if (path->type == TYPE(tclass))
- return first;
- return NULL;
- }
-
- if (path->type != path->next->type) {
- for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(path->next->type))
- break;
- }
-
- if (base) {
- path = path->next;
- } else {
- first = path = path->next;
- }
- } else {
- path->next = path->next->next;
- }
- }
-}
-
-void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) {
- ClassFriend *cfriend;
-
- if (path) {
- path = CClass_PathCleanup(path, tclass);
- if (path && path->next) {
- if (!CClass_CanAccess(path, access))
- CError_Error(CErrorStr187);
- return;
- }
- }
-
- switch (access) {
- case ACCESSPUBLIC:
- return;
- case ACCESSPRIVATE:
- case ACCESSPROTECTED:
- if (tclass == cscope_currentclass)
- return;
-
- for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) {
- if (cfriend->isclass) {
- if (cfriend->u.theclass == cscope_currentclass)
- return;
- } else {
- if (cfriend->u.obj == cscope_currentfunc)
- return;
- }
- }
- case ACCESSNONE:
- CError_Warning(CErrorStr187);
- return;
- default:
- CError_FATAL(3013);
- }
-}
-
-void CClass_CheckObjectAccess(BClassList *path, Object *obj) {
- short depth;
- Boolean isambigbase;
-
- if (obj->nspace && obj->nspace->theclass) {
- if (!path && cscope_currentclass)
- path = CClass_GetBasePath(cscope_currentclass, obj->nspace->theclass, &depth, &isambigbase);
-
- CClass_CheckStaticAccess(path, obj->nspace->theclass, obj->access);
- }
-}
-
-void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) {
- if (path) {
- if ((path = CClass_PathCleanup(path, NULL))) {
- if (!CClass_CanAccess(path, objec->access))
- CError_Error(CErrorStr187);
- return;
- }
- }
-
- if (
- objec->access != ACCESSPUBLIC &&
- IS_TYPE_ENUM(objec->type) &&
- TYPE_ENUM(objec->type)->nspace &&
- TYPE_ENUM(objec->type)->nspace->theclass
- )
- CClass_CheckStaticAccess(NULL, TYPE_ENUM(objec->type)->nspace->theclass, objec->access);
-}
-
-static Type *CClass_PointerTypeCopy(Type *type) {
- Type *copy;
-
- switch (type->type) {
- case TYPEPOINTER:
- case TYPEARRAY:
- copy = galloc(sizeof(TypePointer));
- *TYPE_POINTER(copy) = *TYPE_POINTER(type);
- TPTR_TARGET(copy) = CClass_PointerTypeCopy(TPTR_TARGET(copy));
- return copy;
- case TYPEMEMBERPOINTER:
- copy = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(copy) = *TYPE_MEMBER_POINTER(type);
- return copy;
- default:
- return type;
- }
-}
-
-Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) {
- Type *inner;
-
- qual2 = qual2 & (Q_CONST | Q_VOLATILE);
- if (qual1 & Q_MUTABLE)
- qual2 &= ~Q_CONST;
- qual1 = qual1 & (Q_CONST | Q_VOLATILE);
-
- inner = type;
- while (IS_TYPE_ARRAY(inner))
- inner = TPTR_TARGET(inner);
-
- switch (inner->type) {
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- if (qual2) {
- type = CClass_PointerTypeCopy(type);
- inner = type;
- while (IS_TYPE_ARRAY(inner))
- inner = TPTR_TARGET(inner);
-
- switch (inner->type) {
- case TYPEPOINTER:
- TPTR_QUAL(inner) |= qual2;
- break;
- case TYPEMEMBERPOINTER:
- TYPE_MEMBER_POINTER(inner)->qual |= qual2;
- break;
- default:
- CError_FATAL(3125);
- }
- }
- break;
- default:
- qual1 |= qual2;
- }
-
- *outflags = qual1;
- return type;
-}
-
-static void CClass_OptimizeBitFieldAccess(Type **ptype, SInt32 *poffset) {
- Type *innertype;
- TypeBitfield *newtype;
- short i;
-
- innertype = TYPE_BITFIELD(*ptype)->bitfieldtype;
- if (TYPE_BITFIELD(*ptype)->bitlength == 8) {
- switch (TYPE_BITFIELD(*ptype)->offset) {
- case 0:
- i = 0;
- break;
- case 8:
- i = 1;
- break;
- case 16:
- i = 2;
- break;
- case 24:
- i = 3;
- break;
- default:
- i = -1;
- break;
- }
-
- if (i >= 0) {
- if (innertype->size != 1) {
- if (is_unsigned(TYPE_BITFIELD(*ptype)->bitfieldtype))
- *ptype = TYPE(&stunsignedchar);
- else
- *ptype = TYPE(&stsignedchar);
- } else {
- *ptype = innertype;
- }
- *poffset += i;
- return;
- }
- }
-
- if (TYPE_BITFIELD(*ptype)->bitlength == 16) {
- switch (TYPE_BITFIELD(*ptype)->offset) {
- case 0:
- i = 0;
- break;
- case 16:
- i = 2;
- break;
- default:
- i = -1;
- break;
- }
-
- if (i >= 0) {
- if (innertype->size != stsignedshort.size) {
- if (is_unsigned(innertype))
- *ptype = TYPE(&stunsignedshort);
- else
- *ptype = TYPE(&stsignedshort);
- } else {
- *ptype = innertype;
- }
- *poffset += i;
- return;
- }
- }
-
- if (TYPE_BITFIELD(*ptype)->bitlength == 32 && TYPE_BITFIELD(*ptype)->offset == 0) {
- if (innertype->size != stsignedlong.size) {
- if (is_unsigned(innertype))
- *ptype = TYPE(&stunsignedlong);
- else
- *ptype = TYPE(&stsignedlong);
- } else {
- *ptype = innertype;
- }
- return;
- }
-
- if ((*ptype)->size != stsignedchar.size) {
- i = TYPE_BITFIELD(*ptype)->offset + TYPE_BITFIELD(*ptype)->bitlength - 1;
-
- if (TYPE_BITFIELD(*ptype)->bitlength < 8 && (TYPE_BITFIELD(*ptype)->offset & 0xFFF8) == (i & 0xFFF8)) {
- newtype = galloc(sizeof(TypeBitfield));
- *newtype = *TYPE_BITFIELD(*ptype);
- *ptype = TYPE(newtype);
-
- i = 0;
- if (newtype->offset >= 8)
- i = 1;
- if (newtype->offset >= 16)
- i = 2;
- if (newtype->offset >= 24)
- i = 3;
- *poffset += i;
- newtype->offset -= 8 * i;
-
- newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedchar) : TYPE(&stsignedchar);
- newtype->size = newtype->bitfieldtype->size;
- return;
- }
-
- if ((*ptype)->size != stsignedshort.size) {
- if (TYPE_BITFIELD(*ptype)->bitlength < 16 && (TYPE_BITFIELD(*ptype)->offset & 0xFFF0) == (i & 0xFFF0)) {
- newtype = galloc(sizeof(TypeBitfield));
- *newtype = *TYPE_BITFIELD(*ptype);
- *ptype = TYPE(newtype);
-
- i = 0;
- if (newtype->offset >= 16)
- i = stsignedshort.size;
- *poffset += i;
- newtype->offset -= 8 * i;
-
- newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedshort) : TYPE(&stsignedshort);
- newtype->size = newtype->bitfieldtype->size;
- return;
- }
- }
- }
-}
-
-ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) {
- Type *innertype;
- UInt32 flags;
-
- innertype = NULL;
-
- if (IS_TYPE_CLASS(classexpr->rtype) && (TYPE_CLASS(classexpr->rtype)->flags & CLASS_HANDLEOBJECT)) {
- classexpr = makemonadicnode(classexpr, EINDIRECT);
- classexpr->data.monadic->rtype = CDecl_NewPointerType(classexpr->rtype);
- }
-
- if (IS_TYPE_BITFIELD(type)) {
- innertype = TYPE_BITFIELD(type)->bitfieldtype;
- CClass_OptimizeBitFieldAccess(&type, &offset);
- }
-
- if (offset && !canadd(classexpr->data.monadic, offset)) {
- classexpr->data.monadic = makediadicnode(
- classexpr->data.monadic,
- intconstnode(TYPE(&stunsignedlong), offset),
- EADD);
- optimizecomm(classexpr->data.monadic);
- }
-
- if (innertype) {
- if (IS_TYPE_BITFIELD(type)) {
- classexpr->data.monadic = makemonadicnode(classexpr->data.monadic, EBITFIELD);
- classexpr->data.monadic->rtype = type;
- classexpr->rtype = TYPE_BITFIELD(type)->bitfieldtype;
- } else {
- classexpr->rtype = type;
- }
- } else {
- classexpr->rtype = type;
- }
-
- classexpr->rtype = CClass_CombineClassAccessQualifiers(classexpr->rtype, qual, ENODE_QUALS(classexpr), &flags);
- classexpr->flags = flags;
- return classexpr;
-}
diff --git a/compiler_and_linker/unsorted/CCompiler.c b/compiler_and_linker/unsorted/CCompiler.c
index 1eb6cd0..ed57c25 100644
--- a/compiler_and_linker/unsorted/CCompiler.c
+++ b/compiler_and_linker/unsorted/CCompiler.c
@@ -4,7 +4,7 @@
#include "compiler/CompilerTools.h"
#include "compiler/CodeGen.h"
#include "compiler/CodeGenOptPPC.h"
-#include "compiler/IrOptimizer.h"
+#include "../FrontEnd/Optimizer/IrOptimizer.h"
#include "compiler/types.h"
#include "pref_structs.h"
diff --git a/compiler_and_linker/unsorted/CDecl.c b/compiler_and_linker/unsorted/CDecl.c
deleted file mode 100644
index 43ca92e..0000000
--- a/compiler_and_linker/unsorted/CDecl.c
+++ /dev/null
@@ -1,4845 +0,0 @@
-#include "compiler/CDecl.h"
-#include "compiler/CABI.h"
-#include "compiler/CBrowse.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateClass.h"
-#include "compiler/CTemplateFunc.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/tokens.h"
-
-AccessType global_access;
-FileOffsetInfo member_fileoffset;
-
-// forward declarations
-static void scandirectdecl1(DeclInfo *declinfo);
-
-Type *CDecl_NewStructType(SInt32 size, SInt16 align) {
- TypeStruct *tstruct = galloc(sizeof(TypeStruct));
- memclrw(tstruct, sizeof(TypeStruct));
-
- tstruct->type = TYPESTRUCT;
- tstruct->size = size;
- tstruct->align = align;
- tstruct->stype = STRUCT_TYPE_STRUCT;
-
- return (Type *) tstruct;
-}
-
-Type *CDecl_NewArrayType(Type *type, SInt32 size) {
- TypePointer *tarray = galloc(sizeof(TypePointer));
- memclrw(tarray, sizeof(TypePointer));
-
- tarray->type = TYPEARRAY;
- tarray->size = size;
- tarray->target = type;
- tarray->qual = 0;
-
- return (Type *) tarray;
-}
-
-Type *CDecl_NewPointerType(Type *type) {
- TypePointer *tptr = galloc(sizeof(TypePointer));
- memclrw(tptr, sizeof(TypePointer));
-
- tptr->type = TYPEPOINTER;
- tptr->size = 4;
- tptr->target = type;
-
- return (Type *) tptr;
-}
-
-Type *CDecl_NewRefPointerType(Type *type) {
- TypePointer *tptr = galloc(sizeof(TypePointer));
- memclrw(tptr, sizeof(TypePointer));
-
- tptr->type = TYPEPOINTER;
- tptr->size = 4;
- tptr->target = type;
- tptr->qual = Q_REFERENCE;
-
- return (Type *) tptr;
-}
-
-Type *CDecl_NewTemplDepType(TypeTemplDepType tdt) {
- TypeTemplDep *t = galloc(sizeof(TypeTemplDep));
- memclrw(t, sizeof(TypeTemplDep));
-
- t->type = TYPETEMPLATE;
- t->size = 1;
- t->dtype = tdt;
-
- return (Type *) t;
-}
-
-void CDecl_SetResultReg(TypeFunc *tfunc) {
-}
-
-static void CDecl_SetFuncResultReg(TypeFunc *tfunc) {
-}
-
-void CDecl_SetFuncFlags(TypeFunc *tfunc, UInt32 flags) {
- CDecl_SetResultReg(tfunc);
-}
-
-static void CDecl_ParseCPPFuncDecl(TypeFunc *tfunc) {
- for (;;) {
- if (tk == TK_CONST) {
- if (tfunc->flags & FUNC_CONST)
- CError_Warning(CErrorStr313, "const");
- tfunc->flags |= FUNC_CONST;
- tk = lex();
- } else if (tk == TK_VOLATILE) {
- if (tfunc->flags & FUNC_VOLATILE)
- CError_Warning(CErrorStr313, "volatile");
- tfunc->flags |= FUNC_VOLATILE;
- tk = lex();
- } else {
- break;
- }
- }
-
- if (tk == TK_THROW)
- CExcept_ScanExceptionSpecification(tfunc);
-}
-
-void CDecl_NewConvFuncType(DeclInfo *declinfo) {
- TypeFunc *tfunc;
-
- if (tk != '(')
- CError_Error(CErrorStr114);
- else
- tk = lex();
-
- if (tk == TK_VOID)
- tk = lex();
-
- if (tk != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- declinfo->name = CMangler_ConversionFuncName(declinfo->thetype, declinfo->qual);
- tfunc->type = TYPEFUNC;
- tfunc->functype = declinfo->thetype;
- tfunc->qual = declinfo->qual & (Q_CONST | Q_VOLATILE);
- tfunc->flags = FUNC_CONVERSION;
- declinfo->x49 = 0;
- CDecl_SetFuncFlags(tfunc, 1);
- CDecl_ParseCPPFuncDecl(tfunc);
-
- declinfo->thetype = (Type *) tfunc;
- declinfo->qual &= ~(Q_CONST | Q_VOLATILE);
- declinfo->storageclass = 0;
-}
-
-void CDecl_CompleteType(Type *type) {
- switch (type->type) {
- case TYPEPOINTER:
- if ((TYPE_POINTER(type)->qual & Q_REFERENCE) && IS_TYPE_CLASS(TYPE_POINTER(type)->target)) {
- type = TYPE_POINTER(type)->target;
- break;
- }
- return;
- case TYPEARRAY:
- do {
- type = TYPE_POINTER(type)->target;
- } while (IS_TYPE_ARRAY(type));
- if (IS_TYPE_CLASS(type))
- break;
- return;
- case TYPECLASS:
- break;
- default:
- return;
- }
-
- if ((TYPE_CLASS(type)->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CTempl_InstantiateTemplateClass(TYPE_CLASS(type));
-}
-
-Boolean IsCompleteType(Type *type) {
- switch (type->type) {
- case TYPEVOID:
- CError_Error(CErrorStr126);
- return 0;
- case TYPEFUNC:
- CError_Error(CErrorStr146);
- return 0;
- case TYPESTRUCT:
- if (!type->size) {
- CError_Error(CErrorStr136, type, 0);
- return 0;
- }
- return 1;
- case TYPECLASS:
- if (
- !(TYPE_CLASS(type)->flags & CLASS_COMPLETED) &&
- (
- !(TYPE_CLASS(type)->flags & CLASS_IS_TEMPL_INST) ||
- !CTempl_InstantiateTemplateClass(TYPE_CLASS(type))
- )
- )
- {
- CError_Error(CErrorStr136, type, 0);
- return 0;
- }
- return 1;
- default:
- if (!type->size) {
- CError_Error(CErrorStr145);
- return 0;
- }
- return 1;
- }
-}
-
-Boolean CanAllocObject(Type *type) {
- switch (type->type) {
- case TYPEVOID:
- CError_Error(CErrorStr126);
- return 0;
- case TYPEFUNC:
- CError_Error(CErrorStr146);
- return 0;
- case TYPECLASS:
- if (TYPE_CLASS(type)->flags & CLASS_ABSTRACT) {
- CError_AbstractClassError(TYPE_CLASS(type));
- return 0;
- }
- default:
- return 1;
- }
-}
-
-Boolean CanCreateObject(Type *type) {
- if (!CanAllocObject(type))
- return 0;
-
- if (IS_TYPE_CLASS(type)) {
- if (TYPE_CLASS(type)->flags & CLASS_HANDLEOBJECT) {
- CError_Error(CErrorStr191);
- return 0;
- }
- if (TYPE_CLASS(type)->objcinfo) {
- CError_Error(CErrorStr307);
- return 0;
- }
- }
-
- return 1;
-}
-
-static Boolean CanCreateHandleMemberObject(Type *type) {
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
-
- if (!CanCreateObject(type))
- return 0;
-
- if (IS_TYPE_CLASS(type)) {
- if (CClass_Destructor(TYPE_CLASS(type)) || CClass_Constructor(TYPE_CLASS(type))) {
- CError_Error(CErrorStr191);
- return 0;
- }
- }
-
- return 1;
-}
-
-void makethetypepointer(DeclInfo *declinfo, UInt32 qual) {
- declinfo->thetype = CDecl_NewPointerType(declinfo->thetype);
- TYPE_POINTER(declinfo->thetype)->qual = qual;
-}
-
-void CDecl_AddThisPointerArgument(TypeFunc *tfunc, TypeClass *tclass) {
- Type *ptype;
- FuncArg *arg;
-
- ptype = CDecl_NewPointerType(!tclass->sominfo ? (Type *) tclass : &stvoid);
- TYPE_POINTER(ptype)->qual = Q_CONST;
-
- arg = CParser_NewFuncArg();
- arg->name = this_name_node;
- arg->type = ptype;
- if (tfunc->flags & FUNC_CONST)
- arg->qual |= Q_CONST;
- if (tfunc->flags & FUNC_VOLATILE)
- arg->qual |= Q_VOLATILE;
- arg->next = tfunc->args;
- tfunc->args = arg;
-}
-
-void CDecl_MakePTMFuncType(TypeFunc *tfunc) {
- Type *cvoidp;
- FuncArg *arg1;
- FuncArg *arg2;
-
- cvoidp = CDecl_NewPointerType(&stvoid);
- TYPE_POINTER(cvoidp)->qual = Q_CONST;
-
- arg1 = CParser_NewFuncArg();
- arg1->name = this_name_node;
- arg1->type = cvoidp;
- if (tfunc->flags & FUNC_CONST)
- arg1->qual |= Q_CONST;
- if (tfunc->flags & FUNC_VOLATILE)
- arg1->qual |= Q_VOLATILE;
-
- arg2 = CParser_NewFuncArg();
- arg2->name = this_name_node;
- arg2->type = cvoidp;
- arg2->qual = Q_CONST;
-
- arg1->next = tfunc->args;
- arg2->next = arg1;
- tfunc->args = arg2;
- tfunc->flags |= FUNC_FLAGS_80;
-}
-
-void CDecl_AddArgument(TypeFunc *tfunc, Type *argtype) {
- FuncArg *arg = CParser_NewFuncArg();
- arg->type = argtype;
-
- arg->next = tfunc->args;
- tfunc->args = arg;
-
- if (arg->next && arg->next->type == &stvoid)
- arg->next = NULL;
-}
-
-Boolean CDecl_CheckArrayIntegr(Type *type) {
- if (!IsCompleteType(type))
- return 0;
-
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo) {
- CError_Error(CErrorStr289);
- return 0;
- }
-
- if (IS_TYPE_REFERENCE(type)) {
- CError_Error(CErrorStr196);
- return 0;
- }
-
- return CanCreateObject(type);
-}
-
-static Boolean checkfuncintegr(Type *type) {
- if (IS_TYPE_VOID(type))
- return 1;
-
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo) {
- CError_Error(CErrorStr283);
- return 0;
- }
-
- return CanCreateObject(type);
-}
-
-void CDecl_ParseDirectFuncDecl(DeclInfo *declinfo) {
- FuncArg *list;
- TypeFunc *tfunc;
-
- if (tk == ')') {
- if (copts.cplusplus)
- list = NULL;
- else
- list = &oldstyle;
- tk = lex();
- } else {
- list = parameter_type_list(declinfo);
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
- }
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->args = list;
- if (declinfo->qual & Q_PASCAL) {
- declinfo->qual &= ~Q_PASCAL;
- tfunc->flags = FUNC_PASCAL;
- }
-
- if (copts.cplusplus) {
- CDecl_ParseCPPFuncDecl(tfunc);
- if (declinfo->storageclass == TK_TYPEDEF && tfunc->exspecs)
- CError_Error(CErrorStr264);
- }
-
- scandirectdecl1(declinfo);
- if (!checkfuncintegr(declinfo->thetype))
- declinfo->thetype = &stvoid;
-
- tfunc->functype = declinfo->thetype;
- tfunc->qual = declinfo->qual & (Q_CONST | Q_VOLATILE);
- declinfo->thetype = (Type *) tfunc;
- declinfo->qual &= ~(Q_CONST | Q_VOLATILE);
- declinfo->x49 = 0;
-}
-
-static void scandirectdecl1(DeclInfo *declinfo) {
- Boolean flag;
- CInt64 len;
- ENode *expr;
- TypeTemplDep *ttempl;
-
- flag = 0;
- if (tk == '[') {
- if ((tk = lex()) == ']') {
- len = cint64_zero;
- tk = lex();
- flag = 1;
- } else {
- if (!declinfo->x46 || declinfo->x47) {
- expr = CExpr_IntegralConstOrDepExpr();
- if (!ENODE_IS(expr, EINTCONST)) {
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- declinfo->x47 = 1;
- scandirectdecl1(declinfo);
- if (!CDecl_CheckArrayIntegr(declinfo->thetype))
- declinfo->thetype = (Type *) &stsignedchar;
- ttempl = (TypeTemplDep *) CDecl_NewTemplDepType(TEMPLDEP_ARRAY);
- ttempl->u.array.type = declinfo->thetype;
- ttempl->u.array.index = CInline_CopyExpression(expr, CopyMode1);
- declinfo->thetype = (Type *) ttempl;
- return;
- }
- len = expr->data.intval;
- if (CInt64_IsNegative(&len)) {
- CError_Error(CErrorStr124);
- len = cint64_one;
- } else if (CInt64_IsZero(&len)) {
- if (!copts.ANSIstrict && declinfo->x50) {
- flag = 1;
- } else {
- CError_Error(CErrorStr124);
- len = cint64_one;
- }
- }
- } else {
- len = cint64_one;
- expr = expression();
- if (IS_TYPE_INT(expr->rtype)) {
- if (!ENODE_IS(expr, EINTCONST))
- declinfo->x24 = expr;
- else
- len = expr->data.intval;
- } else {
- CError_Error(CErrorStr124);
- }
- }
-
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- }
-
- declinfo->x47 = 1;
- scandirectdecl1(declinfo);
-
- if (!flag && !CDecl_CheckArrayIntegr(declinfo->thetype))
- declinfo->thetype = (Type *) &stsignedchar;
-
- if (!declinfo->thetype->size && CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) {
- ttempl = (TypeTemplDep *) CDecl_NewTemplDepType(TEMPLDEP_ARRAY);
- ttempl->u.array.type = declinfo->thetype;
- ttempl->u.array.index = CInline_CopyExpression(intconstnode((Type *) &stsignedint, CInt64_GetULong(&len)), CopyMode1);
- declinfo->thetype = (Type *) ttempl;
- } else {
- declinfo->thetype = CDecl_NewArrayType(declinfo->thetype, declinfo->thetype->size * CInt64_GetULong(&len));
- }
- } else if (tk == '(') {
- if (!copts.cplusplus || !declinfo->name || IS_TYPE_VOID(declinfo->thetype) || CParser_TryParamList(!IS_TYPE_CLASS(declinfo->thetype))) {
- tk = lex();
- CDecl_ParseDirectFuncDecl(declinfo);
- }
- }
-}
-
-static void substitute_type(Type *type1, Type *type2) {
- SInt32 oldsize;
-
- while (1) {
- switch (type1->type) {
- case TYPEPOINTER:
- if (TYPE_POINTER(type1)->target == &stillegal) {
- TYPE_POINTER(type1)->target = type2;
- type1->size = 4;
- return;
- }
- type1 = TYPE_POINTER(type1)->target;
- break;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(type1)->ty1 == &stillegal) {
- TYPE_MEMBER_POINTER(type1)->ty1 = type2;
- if (IS_TYPE_FUNC(type2)) {
- CDecl_MakePTMFuncType(TYPE_FUNC(type2));
- type1->size = 12;
- } else {
- type1->size = 4;
- }
- return;
- }
- type1 = TYPE_MEMBER_POINTER(type1)->ty1;
- break;
- case TYPEARRAY:
- if (TYPE_POINTER(type1)->target == &stillegal) {
- if (!CDecl_CheckArrayIntegr(type2))
- type2 = (Type *) &stsignedchar;
- type1->size *= type2->size;
- TYPE_POINTER(type1)->target = type2;
- return;
- }
- oldsize = TYPE_POINTER(type1)->target->size;
- substitute_type(TYPE_POINTER(type1)->target, type2);
- if (oldsize != TYPE_POINTER(type1)->target->size && oldsize != 0)
- type1->size = TYPE_POINTER(type1)->target->size * (type1->size / oldsize);
- return;
- case TYPEFUNC:
- if (TYPE_FUNC(type1)->functype == &stillegal) {
- if (!checkfuncintegr(type2))
- type2 = &stvoid;
- TYPE_FUNC(type1)->functype = type2;
- CDecl_SetFuncResultReg((TypeFunc *) type1);
- return;
- }
- type1 = TYPE_FUNC(type1)->functype;
- break;
- case TYPETEMPLATE:
- if (TYPE_TEMPLATE(type1)->dtype == TEMPLDEP_ARRAY) {
- if (TYPE_TEMPLATE(type1)->u.array.type == &stillegal) {
- if (!CDecl_CheckArrayIntegr(type2))
- type2 = (Type *) &stsignedchar;
- TYPE_TEMPLATE(type1)->u.array.type = type2;
- return;
- }
- type1 = TYPE_TEMPLATE(type1)->u.array.type;
- } else {
- CError_Error(CErrorStr146);
- return;
- }
- break;
- default:
- CError_Error(CErrorStr121);
- return;
- }
- }
-}
-
-static void scandecl(DeclInfo *declinfo) {
- Type *oldtype;
- Type *newtype;
-
- oldtype = declinfo->thetype;
- declinfo->thetype = &stillegal;
- scandeclarator(declinfo);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- newtype = declinfo->thetype;
- if (newtype == &stillegal) {
- declinfo->thetype = oldtype;
- scandirectdecl1(declinfo);
- } else {
- declinfo->thetype = oldtype;
- scandirectdecl1(declinfo);
- substitute_type(newtype, declinfo->thetype);
- declinfo->thetype = newtype;
- }
-}
-
-static Boolean CDecl_ParseOperatorDecl(DeclInfo *declinfo) {
- if (declinfo->operator_token) {
- CError_Error(CErrorStr121);
- return 0;
- }
-
- declinfo->operator_token = 0;
- if (!CParser_ParseOperatorName(&declinfo->operator_token, declinfo->x4A && cscope_current->theclass, 0))
- return 0;
-
- if (!declinfo->operator_token) {
- conversion_type_name(declinfo);
- tkidentifier = CMangler_ConversionFuncName(declinfo->thetype, declinfo->qual);
- declinfo->x54 = 1;
- }
- return 1;
-}
-
-static Boolean CDecl_IsEnumClassTypeOrRef(Type *type) {
- if (IS_TYPE_CLASS(type) || IS_TYPE_ENUM(type))
- return 1;
- if (!IS_TYPE_REFERENCE(type))
- return 0;
- type = TYPE_POINTER(type)->target;
- return IS_TYPE_CLASS(type) || IS_TYPE_ENUM(type);
-}
-
-static Boolean CDecl_CheckOperatorType(DeclInfo *declinfo, Boolean flag) {
- FuncArg *args;
- FuncArg *secondarg;
- Type *functype;
- short argCount;
- Boolean isMethod;
-
- if (!IS_TYPE_FUNC(declinfo->thetype)) {
- CError_Error(CErrorStr193);
- return 0;
- }
-
- functype = TYPE_FUNC(declinfo->thetype)->functype;
- args = TYPE_FUNC(declinfo->thetype)->args;
- if (args) {
- if (args != &elipsis && args != &oldstyle) {
- argCount = 1;
- if (args->dexpr) {
- switch (declinfo->operator_token) {
- case TK_NEW:
- case TK_DELETE:
- case TK_NEW_ARRAY:
- case TK_DELETE_ARRAY:
- break;
- default:
- CError_Error(CErrorStr205);
- }
- }
-
- secondarg = args->next;
- if (secondarg) {
- argCount = ((secondarg != &elipsis && !secondarg->next) != 0) ? 2 : 3;
- if (secondarg->dexpr) {
- switch (declinfo->operator_token) {
- case '(':
- case TK_NEW:
- case TK_DELETE:
- case TK_NEW_ARRAY:
- case TK_DELETE_ARRAY:
- break;
- default:
- CError_Error(CErrorStr205);
- }
- }
- }
- } else {
- argCount = 3;
- }
- } else {
- CError_Error(CErrorStr193);
- return 0;
- }
-
- isMethod = flag &&
- IS_TYPEFUNC_METHOD(TYPE_FUNC(declinfo->thetype)) &&
- !TYPE_METHOD(declinfo->thetype)->is_static;
-
- switch (declinfo->operator_token) {
- case TK_NEW:
- case TK_NEW_ARRAY:
- if (isMethod || !is_typesame(functype, TYPE(&void_ptr)) || argCount < 1 || args->type != CABI_GetSizeTType()) {
- CError_Error(CErrorStr193);
- return 0;
- }
- return 1;
- case TK_DELETE:
- case TK_DELETE_ARRAY:
- if (isMethod || !IS_TYPE_VOID(functype) || argCount < 1 || !is_typesame(args->type, TYPE(&void_ptr))) {
- CError_Error(CErrorStr193);
- return 0;
- }
- return 1;
- case '=':
- if (!isMethod) {
- CError_Error(CErrorStr193);
- return 0;
- }
- break;
- case '(':
- if (!isMethod) {
- CError_Error(CErrorStr193);
- return 0;
- }
- return 1;
- case '[':
- if (!isMethod) {
- CError_Error(CErrorStr193);
- return 0;
- }
- break;
- case TK_ARROW:
- if (argCount != 1 || isMethod == 0) {
- CError_Error(CErrorStr193);
- return 0;
- }
- return 1;
- case TK_INCREMENT:
- case TK_DECREMENT:
- if (argCount == 2 && secondarg->type != TYPE(&stsignedint)) {
- CError_Error(CErrorStr193);
- return 0;
- }
- break;
- }
-
- if (flag && !isMethod) {
- CError_Error(CErrorStr193);
- return 0;
- }
-
- switch (declinfo->operator_token) {
- case '&':
- case '*':
- case '+':
- case '-':
- case TK_INCREMENT:
- case TK_DECREMENT:
- if (argCount != 1)
- goto whatever;
- case '!':
- case '~':
- if (argCount == 1) {
- if (flag || CDecl_IsEnumClassTypeOrRef(args->type))
- return 1;
- }
- break;
- case '%':
- case ',':
- case '/':
- case '<':
- case '=':
- case '>':
- case '[':
- case '^':
- case '|':
- case TK_MULT_ASSIGN:
- case TK_DIV_ASSIGN:
- case TK_MOD_ASSIGN:
- case TK_ADD_ASSIGN:
- case TK_SUB_ASSIGN:
- case TK_SHL_ASSIGN:
- case TK_SHR_ASSIGN:
- case TK_AND_ASSIGN:
- case TK_XOR_ASSIGN:
- case TK_OR_ASSIGN:
- case TK_LOGICAL_OR:
- case TK_LOGICAL_AND:
- case TK_LOGICAL_EQ:
- case TK_LOGICAL_NE:
- case TK_LESS_EQUAL:
- case TK_GREATER_EQUAL:
- case TK_SHL:
- case TK_SHR:
- case TK_ARROW:
- case TK_DOT_STAR:
- case TK_ARROW_STAR:
- whatever:
- if (argCount == 2) {
- if (flag || CDecl_IsEnumClassTypeOrRef(args->type) || CDecl_IsEnumClassTypeOrRef(secondarg->type))
- return 1;
- }
- break;
- }
-
- CError_Error(CErrorStr193);
- return 0;
-}
-
-static void scandirectdeclarator(DeclInfo *declinfo, NameSpace *nspace) {
- HashNameNode *saveident;
- CScopeSave scopesave;
- Boolean flag;
-
- if (nspace)
- CScope_SetNameSpaceScope(nspace, &scopesave);
-
- if (tk == '(') {
- if ((tk = lex()) == ')') {
- if (declinfo->x55) {
- CDecl_ParseDirectFuncDecl(declinfo);
- if (nspace)
- CScope_RestoreScope(&scopesave);
- return;
- } else {
- CError_Error(CErrorStr121);
- if (nspace)
- CScope_RestoreScope(&scopesave);
- return;
- }
- }
-
- if (!(tk >= TK_AUTO && tk <= TK_BYREF)) {
- if (!(tk == TK_IDENTIFIER && CScope_PossibleTypeName(tkidentifier))) {
- scandecl(declinfo);
- if (nspace)
- CScope_RestoreScope(&scopesave);
- return;
- } else {
- saveident = tkidentifier;
- switch (lookahead()) {
- case ')':
- case ',':
- break;
- default:
- tkidentifier = saveident;
- scandecl(declinfo);
- if (nspace)
- CScope_RestoreScope(&scopesave);
- return;
- }
- }
- }
-
- if (declinfo->name)
- CError_Error(CErrorStr121);
-
- CDecl_ParseDirectFuncDecl(declinfo);
- if (nspace)
- CScope_RestoreScope(&scopesave);
- return;
- }
-
- if (nspace) {
- if (tk == TK_OPERATOR) {
- if (!CDecl_ParseOperatorDecl(declinfo)) {
- CScope_RestoreScope(&scopesave);
- return;
- }
-
- if (declinfo->x54) {
- declinfo->nspace = nspace;
- declinfo->name = tkidentifier;
- if (nspace)
- CScope_RestoreScope(&scopesave);
-
- if (tk == '(') {
- tk = lex();
- CDecl_ParseDirectFuncDecl(declinfo);
- if (IS_TYPE_FUNC(declinfo->thetype))
- TYPE_FUNC(declinfo->thetype)->flags |= FUNC_CONVERSION;
- else
- CError_Error(CErrorStr121);
- } else {
- CError_Error(CErrorStr114);
- }
- return;
- }
-
- flag = 1;
- } else if (tk != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- CScope_RestoreScope(&scopesave);
- return;
- } else {
- flag = 0;
- }
-
- if (declinfo->name) {
- CError_Error(CErrorStr121);
- CScope_RestoreScope(&scopesave);
- return;
- }
-
- declinfo->nspace = nspace;
- declinfo->name = tkidentifier;
- if (!flag)
- tk = lex();
- } else if (tk == TK_IDENTIFIER) {
- if (declinfo->name)
- CError_Error(CErrorStr121);
- declinfo->name = tkidentifier;
- tk = lex();
- } else if (tk == TK_OPERATOR) {
- if (!CDecl_ParseOperatorDecl(declinfo))
- return;
- declinfo->name = tkidentifier;
- }
-
- if (tk == '<' && declinfo->x51) {
- declinfo->expltargs = CTempl_ParseUncheckTemplArgs(NULL, 0);
- declinfo->has_expltargs = 1;
- declinfo->x51 = 0;
- tk = lex();
- }
-
- scandirectdecl1(declinfo);
-
- if (nspace)
- CScope_RestoreScope(&scopesave);
-}
-
-void makememberpointertype(DeclInfo *declinfo, TypeClass *tclass, UInt32 qual) {
- TypeMemberPointer *tmemp;
- TypeFunc *tfunc;
-
- if (tclass->flags & CLASS_HANDLEOBJECT) {
- CError_Error(CErrorStr191);
- declinfo->thetype = (Type *) &stsignedint;
- return;
- }
- if (tclass->sominfo) {
- CError_Error(CErrorStr290);
- declinfo->thetype = (Type *) &stsignedint;
- return;
- }
-
- tmemp = galloc(sizeof(TypeMemberPointer));
- memclrw(tmemp, sizeof(TypeMemberPointer));
- tmemp->type = TYPEMEMBERPOINTER;
- tmemp->ty2 = (Type *) tclass;
- tmemp->qual = qual;
-
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- tfunc = galloc(sizeof(TypeFunc));
- *tfunc = *TYPE_FUNC(declinfo->thetype);
- tmemp->ty1 = (Type *) tfunc;
- tmemp->size = 12;
- CDecl_MakePTMFuncType(tfunc);
- } else {
- tmemp->size = 4;
- tmemp->ty1 = declinfo->thetype;
- }
- declinfo->thetype = (Type *) tmemp;
-}
-
-void CDecl_ScanPointer(DeclInfo *declinfo, NameSpace *nspace, Boolean flag) {
- NameResult pr;
- UInt32 qual;
-
- while (1) {
- qual = (tk == '&') ? Q_REFERENCE : 0;
-
- for (tk = lex(); ; tk = lex()) {
- switch (tk) {
- case TK_CONST:
- if (qual & Q_CONST)
- CError_Error(CErrorStr121);
- qual |= Q_CONST;
- continue;
- case TK_VOLATILE:
- if (qual & Q_VOLATILE)
- CError_Error(CErrorStr121);
- qual |= Q_VOLATILE;
- continue;
- case TK_RESTRICT:
- if (qual & Q_RESTRICT)
- CError_Error(CErrorStr121);
- qual |= Q_RESTRICT;
- continue;
- default:
- break;
- }
- break;
- }
-
- if (IS_TYPE_REFERENCE(declinfo->thetype) || ((qual & Q_REFERENCE) && IS_TYPE_VOID(declinfo->thetype))) {
- CError_Error(CErrorStr196);
- return;
- }
-
- if (nspace) {
- makememberpointertype(declinfo, nspace->theclass, qual);
- nspace = NULL;
- } else {
- makethetypepointer(declinfo, qual);
- }
-
- switch (tk) {
- case '*':
- continue;
- case '&':
- if (!copts.cplusplus) {
- if (flag)
- scandirectdeclarator(declinfo, NULL);
- return;
- }
- continue;
- case TK_IDENTIFIER:
- if (!copts.cplusplus)
- break;
- if (copts.cpp_extensions && cscope_current->theclass && cscope_current->theclass->classname == tkidentifier && lookahead() == TK_COLON_COLON) {
- tk = lex();
- tk = lex();
- break;
- }
- case TK_COLON_COLON:
- if (CScope_ParseQualifiedNameSpace(&pr, 1, 0)) {
- if ((nspace = pr.nspace_0)) {
- if (nspace->theclass && tk == '*')
- continue;
- } else {
- if (pr.type && IS_TYPE_TEMPLATE(pr.type) && declinfo->x30) {
- if (CTempl_IsQualifiedMember(declinfo, pr.type, &nspace))
- scandirectdeclarator(declinfo, nspace);
- else
- declinfo->x20 = pr.type;
- return;
- }
- CError_Error(CErrorStr121);
- }
- }
- break;
- }
- break;
- }
-
- if (flag)
- scandirectdeclarator(declinfo, nspace);
-}
-
-static void CDecl_TemplatePTM(DeclInfo *declinfo, Type *type) {
- TypeMemberPointer *tmemp = galloc(sizeof(TypeMemberPointer));
- tmemp->type = TYPEMEMBERPOINTER;
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- CDecl_MakePTMFuncType((TypeFunc *) declinfo->thetype);
- tmemp->size = 12;
- } else {
- tmemp->size = 4;
- }
-
- tmemp->ty1 = declinfo->thetype;
- tmemp->ty2 = type;
- tmemp->qual = 0;
- declinfo->thetype = (Type *) tmemp;
-}
-
-void scandeclarator(DeclInfo *declinfo) {
- NameResult pr;
- NameSpace *nspace;
-
- switch (tk) {
- case '&':
- if (!copts.cplusplus)
- break;
- case '*':
- CDecl_ScanPointer(declinfo, NULL, 1);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(NULL, declinfo);
- return;
- case TK_IDENTIFIER:
- if (!copts.cplusplus)
- break;
- case TK_COLON_COLON:
- if (CScope_ParseQualifiedNameSpace(&pr, 1, 0)) {
- nspace = pr.nspace_0;
- if (nspace) {
- if (nspace->theclass && tk == '*')
- CDecl_ScanPointer(declinfo, nspace, 1);
- else
- scandirectdeclarator(declinfo, nspace);
- return;
- }
- if (pr.type && IS_TYPE_TEMPLATE(pr.type)) {
- if (declinfo->x30 && CTempl_IsQualifiedMember(declinfo, pr.type, &nspace)) {
- scandirectdeclarator(declinfo, nspace);
- return;
- } else if (declinfo->x30 && tk == TK_OPERATOR) {
- declinfo->x20 = pr.type;
- return;
- } else if ((tk = lex()) == TK_COLON_COLON && (tk = lex()) == '*') {
- CDecl_TemplatePTM(declinfo, pr.type);
- tk = lex();
- break;
- } else if (declinfo->x30) {
- declinfo->x20 = pr.type;
- return;
- }
- }
- CError_Error(CErrorStr121);
- }
- break;
- }
-
- scandirectdeclarator(declinfo, NULL);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(NULL, declinfo);
-}
-
-void conversion_type_name(DeclInfo *declinfo) {
- NameResult pr;
- DeclInfo subdeclinfo;
-
- memclrw(&subdeclinfo, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&subdeclinfo, 0);
-
- switch (tk) {
- case '&':
- case '*':
- CDecl_ScanPointer(&subdeclinfo, NULL, 0);
- break;
- case TK_IDENTIFIER:
- case TK_COLON_COLON:
- if (CScope_ParseQualifiedNameSpace(&pr, 0, 0)) {
- if (pr.nspace_0 && pr.nspace_0->theclass && tk == '*')
- CDecl_ScanPointer(&subdeclinfo, pr.nspace_0, 0);
- else
- CError_Error(CErrorStr121);
- }
- break;
- }
-
- declinfo->name = subdeclinfo.name;
- declinfo->thetype = subdeclinfo.thetype;
- declinfo->qual |= subdeclinfo.qual;
-}
-
-static void scaninlinefunc(Object *obj) {
- short array[256];
- short r29;
- CInt64 val;
-
- if (tk == '{') {
- tk = lex();
- r29 = 0;
- while (1) {
- if (r29 >= 256) {
- CError_Error(CErrorStr127);
- r29 = 255;
- }
- val = CExpr_IntegralConstExpr();
- array[r29++] = CInt64_GetULong(&val);
- if (tk != '}') {
- if (tk != ',')
- CError_Error(CErrorStr116);
- tk = lex();
- } else {
- tk = lex();
- break;
- }
- }
- } else {
- val = CExpr_IntegralConstExpr();
- array[0] = CInt64_GetULong(&val);
- r29 = 1;
- }
-
- obj->datatype = DINLINEFUNC;
- obj->u.ifunc.size = r29 * 2;
- obj->u.ifunc.data = galloc(obj->u.ifunc.size);
- obj->u.ifunc.xrefs = NULL;
- memcpy(obj->u.ifunc.data, array, obj->u.ifunc.size);
-
- if (tk != ';')
- CError_Error(CErrorStr123);
-}
-
-typedef enum {
- OverloadMode0,
- OverloadMode1,
- OverloadMode2,
- OverloadMode3
-} OverloadMode;
-
-static Object *CDecl_OverloadFunctionObject(NameSpaceObjectList *list, DeclInfo *declinfo, Boolean *outflag, OverloadMode mode, Boolean flag2) {
- TypeFunc *scanfunc;
- NameSpaceObjectList *scan;
- TypeFunc *tfunc;
- FuncArg *args;
- FuncArg *scanargs;
- Object *obj;
- Boolean r24;
- short compareresult;
-
- if (outflag)
- *outflag = 0;
-
- tfunc = (TypeFunc *) declinfo->thetype;
- args = tfunc->args;
- r24 = 0;
- for (scan = list; scan; scan = scan->next) {
- obj = OBJECT(scan->object);
- if (obj->otype != OT_OBJECT)
- continue;
-
- scanfunc = TYPE_FUNC(obj->type);
- if (!IS_TYPE_FUNC(scanfunc))
- continue;
-
- scanargs = scanfunc->args;
- if (scanfunc->flags & FUNC_IS_TEMPL)
- r24 = 1;
-
- if (IS_TYPEFUNC_METHOD(scanfunc)) {
- switch (mode) {
- case OverloadMode0:
- CError_Error(CErrorStr197);
- break;
- case OverloadMode1:
- if (!TYPE_METHOD(scanfunc)->is_static)
- continue;
- break;
- case OverloadMode2:
- if (TYPE_METHOD(scanfunc)->is_static)
- continue;
- break;
- case OverloadMode3:
- if (!TYPE_METHOD(scanfunc)->is_static) {
- if (scanargs->qual & Q_CV)
- continue;
- scanargs = scanargs->next;
- }
- break;
- }
- } else {
- if (mode)
- CError_Error(CErrorStr197);
- }
-
- compareresult = CParser_CompareArgLists(args, scanargs);
- if (compareresult == 1) {
- if (scanfunc->flags & FUNC_CONVERSION) {
- if (!(tfunc->flags & FUNC_CONVERSION)) {
- CError_Error(CErrorStr197);
- break;
- }
- if (!is_typesame(tfunc->functype, scanfunc->functype))
- continue;
- if ((tfunc->qual & Q_CV) != (scanfunc->qual & Q_CV))
- continue;
- if ((tfunc->flags & FUNC_CALL_CONV_MASK) != (scanfunc->flags & FUNC_CALL_CONV_MASK)) {
- CError_Error(CErrorStr197);
- break;
- }
- if (tfunc->exspecs || scanfunc->exspecs)
- CExcept_CompareSpecifications(tfunc->exspecs, scanfunc->exspecs);
- return obj;
- }
-
- if (tfunc->flags & FUNC_CONVERSION) {
- CError_Error(CErrorStr197);
- break;
- }
-
- if (
- !is_typesame(tfunc->functype, scanfunc->functype) ||
- ((tfunc->qual & (Q_CONST | Q_PASCAL)) != (scanfunc->qual & (Q_CONST | Q_PASCAL))) ||
- ((tfunc->flags & FUNC_CALL_CONV_MASK) != (scanfunc->flags & FUNC_CALL_CONV_MASK))
- )
- {
- CError_Error(CErrorStr197);
- break;
- }
-
- if (tfunc->exspecs || scanfunc->exspecs) {
- if (obj->name != newp_fobj->name && obj->name != newa_fobj->name && obj->name != delp_fobj->name && obj->name != dela_fobj->name)
- CExcept_CompareSpecifications(tfunc->exspecs, scanfunc->exspecs);
- }
-
- return obj;
- } else if (compareresult == 2) {
- CError_Error(CErrorStr197);
- break;
- }
- }
-
- if (r24 && (flag2 || declinfo->x3C)) {
- if ((obj = CTempl_TemplateFunctionCheck(declinfo, list)))
- return obj;
- }
-
- if (!outflag) {
- CError_Error(CErrorStr197);
- return NULL;
- }
-
- if (declinfo->nspace)
- CError_Error(CErrorStr336);
-
- *outflag = 1;
- obj = CParser_NewFunctionObject(declinfo);
- CheckDefaultArgs(TYPE_FUNC(obj->type)->args);
-
- if (tfunc->flags & FUNC_PASCAL) {
- for (scan = list; scan; scan = scan->next) {
- if (scan->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(scan->object)->type)) {
- if (TYPE_FUNC(OBJECT(scan->object)->type)->flags & FUNC_PASCAL)
- CError_Error(CErrorStr226);
- }
- }
- }
-
- if (copts.cplusplus && declinfo->is_extern_c) {
- for (scan = list; scan; scan = scan->next) {
- if (scan->object->otype == OT_OBJECT && !(OBJECT(scan->object)->qual & Q_MANGLE_NAME))
- CError_Error(CErrorStr197);
- }
- }
-
- CScope_AddObject(cscope_current, declinfo->name, OBJ_BASE(obj));
- if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL) &&
- CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype))
- CTemplClass_RegisterObjectDef(TEMPL_CLASS(cscope_current->theclass), OBJ_BASE(obj));
-
- return obj;
-}
-
-void MergeDefaultArgs(FuncArg *a, FuncArg *b) {
- FuncArg *scan_a;
- FuncArg *scan_b;
-
- if (a == &oldstyle || b == &oldstyle)
- return;
-
- scan_a = a;
- scan_b = b;
- while (scan_a && scan_b) {
- if (scan_a->dexpr) {
- while (scan_b) {
- if (scan_b->dexpr) {
- while (a) {
- a->dexpr = NULL;
- a = a->next;
- }
- while (b) {
- b->dexpr = NULL;
- b = b->next;
- }
- CError_Error(CErrorStr205);
- return;
- }
- scan_b = scan_b->next;
- }
- break;
- } else if (scan_b->dexpr) {
- do {
- scan_a = scan_a->next;
- scan_b = scan_b->next;
- if (!scan_a) goto secondpart;
- if (scan_a == &elipsis) goto secondpart;
- if (scan_a->dexpr && scan_b->dexpr) break;
- } while (scan_a->dexpr || scan_b->dexpr);
-
- while (a) {
- a->dexpr = NULL;
- a = a->next;
- }
- while (b) {
- b->dexpr = NULL;
- b = b->next;
- }
- CError_Error(CErrorStr205);
- return;
- } else {
- scan_a = scan_a->next;
- scan_b = scan_b->next;
- }
- }
-
-secondpart:
- while (a && b) {
- if (b->dexpr)
- a->dexpr = b->dexpr;
- else
- b->dexpr = a->dexpr;
- a = a->next;
- b = b->next;
- }
-}
-
-void CheckDefaultArgs(FuncArg *args) {
- FuncArg *scan;
-
- scan = args;
- while (scan && !scan->dexpr)
- scan = scan->next;
-
- while (scan && scan != &elipsis && scan != &oldstyle) {
- if (!scan->dexpr) {
- while (args) {
- args->dexpr = NULL;
- args = args->next;
- }
- CError_Error(CErrorStr205);
- return;
- }
- scan = scan->next;
- }
-}
-
-static void CDecl_FuncRedeclCheck(Object *obj, DeclInfo *declinfo, Boolean flag) {
- if (declinfo->storageclass == TK_STATIC && obj->sclass != TK_STATIC) {
- if (copts.cplusplus)
- CError_Error(CErrorStr260);
- else
- obj->sclass = TK_STATIC;
- }
-
- obj->qual |= declinfo->qual;
- if (flag)
- CheckDefaultArgs(TYPE_FUNC(obj->type)->args);
- else
- MergeDefaultArgs(TYPE_FUNC(obj->type)->args, TYPE_FUNC(declinfo->thetype)->args);
-
- if (!declinfo->x45)
- TYPE_FUNC(obj->type)->args = TYPE_FUNC(declinfo->thetype)->args;
-}
-
-Object *CDecl_GetFunctionObject(DeclInfo *declinfo, NameSpace *nspace, Boolean *pflag, Boolean someotherflag) {
- NameSpace *nspace2;
- Type *type;
- Object *obj;
- NameSpaceObjectList *list;
- TypeMemberFunc tmp;
- Boolean r27;
- Boolean outflag;
-
- r27 = 0;
- if (pflag)
- *pflag = 0;
-
- nspace2 = declinfo->nspace;
- if (!nspace2)
- nspace2 = cscope_current;
-
- CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_INLINE | Q_PASCAL | Q_ASM | Q_VOLATILE | Q_CONST));
- switch (TYPE_FUNC(declinfo->thetype)->functype->type) {
- case TYPEFUNC:
- case TYPEARRAY:
- CError_Error(CErrorStr128);
- TYPE_FUNC(declinfo->thetype)->functype = TYPE(&stsignedint);
- break;
- }
-
- if (nspace2->theclass) {
- CError_ASSERT(1969, declinfo->name);
- if (!nspace2->theclass->size)
- CDecl_CompleteType(TYPE(nspace2->theclass));
- if (!(list = CScope_GetLocalObject(nspace2, declinfo->name))) {
- CError_Error(CErrorStr140, declinfo->name->name);
- return NULL;
- }
-
- obj = OBJECT(list->object);
- type = obj->type;
- if (!IS_TYPE_FUNC(type)) {
- CError_Error(CErrorStr249, CError_GetObjectName(obj), type, obj->qual, declinfo->thetype, declinfo->qual);
- return NULL;
- }
-
- if (declinfo->has_expltargs)
- return CTempl_TemplateFunctionCheck(declinfo, list);
-
- if (declinfo->x3C || (list->next && list->next->object->otype == OT_OBJECT)) {
- if (TYPE_FUNC(declinfo->thetype)->flags & (FUNC_CONST | FUNC_VOLATILE)) {
- CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass);
- obj = CDecl_OverloadFunctionObject(list, declinfo, NULL, OverloadMode2, someotherflag);
- if (!obj)
- return NULL;
- } else {
- obj = CDecl_OverloadFunctionObject(list, declinfo, NULL, OverloadMode3, someotherflag);
- if (!obj)
- return NULL;
- if (!TYPE_METHOD(obj->type)->is_static)
- CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass);
- }
- } else {
- if (TYPE_METHOD(type)->is_static) {
- if (nspace2->theclass->sominfo)
- CSOM_FixNewDeleteFunctype(TYPE_FUNC(declinfo->thetype));
- } else {
- CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass);
- }
-
- if (copts.cpp_extensions) {
- declinfo->qual |= obj->qual & (Q_PASCAL | Q_CONST);
- TYPE_FUNC(declinfo->thetype)->qual |= TYPE_FUNC(obj->type)->qual & (Q_PASCAL | Q_CONST);
- TYPE_FUNC(declinfo->thetype)->flags |= TYPE_FUNC(obj->type)->flags & (FUNC_FLAGS_4000000 | FUNC_FLAGS_10000000);
- }
-
- if (!is_typesame(declinfo->thetype, obj->type) || (declinfo->qual & (Q_PASCAL | Q_CONST)) != (obj->qual & (Q_PASCAL | Q_CONST))) {
- tmp = *TYPE_METHOD(obj->type);
- *(TYPE_FUNC(&tmp)) = *TYPE_FUNC(declinfo->thetype);
- tmp.flags |= FUNC_METHOD;
- CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, &tmp, declinfo->qual);
- }
-
- if (TYPE_FUNC(declinfo->thetype)->exspecs || TYPE_FUNC(obj->type)->exspecs)
- CExcept_CompareSpecifications(TYPE_FUNC(declinfo->thetype)->exspecs, TYPE_FUNC(obj->type)->exspecs);
- }
-
- CDecl_FuncRedeclCheck(obj, declinfo, 0);
- if (declinfo->x3C) {
- if (obj->nspace->theclass && !(obj->nspace->theclass->flags & CLASS_IS_TEMPL_INST))
- CError_Error(CErrorStr335);
- declinfo->x3C = 0;
- }
- } else {
- if (TYPE_FUNC(declinfo->thetype)->flags & (FUNC_VOLATILE | FUNC_CONST))
- CError_Error(CErrorStr384);
-
- if (declinfo->operator_token && !CDecl_CheckOperatorType(declinfo, 0))
- return NULL;
-
- list = CScope_GetLocalObject(nspace2, declinfo->name);
- if (declinfo->has_expltargs)
- return CTempl_TemplateFunctionCheck(declinfo, list);
-
- if (list) {
- if (copts.cplusplus) {
- obj = CDecl_OverloadFunctionObject(list, declinfo, &outflag, OverloadMode0, someotherflag);
- if (!obj)
- return NULL;
- if (pflag)
- *pflag = outflag;
- if (nspace)
- obj->nspace = nspace;
- } else {
- obj = OBJECT(list->object);
- if (!is_typesame(declinfo->thetype, obj->type) || (declinfo->qual & (Q_CONST | Q_PASCAL)) != (obj->qual & (Q_CONST | Q_PASCAL))) {
- CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, declinfo->thetype, declinfo->qual);
- r27 = 1;
- if (!IS_TYPE_FUNC(obj->type))
- return NULL;
- }
- }
-
- if (!r27 && pflag)
- CDecl_FuncRedeclCheck(obj, declinfo, *pflag);
- } else {
- if (declinfo->nspace)
- CError_Error(CErrorStr336);
-
- if (declinfo->has_expltargs) {
- if (declinfo->name)
- CError_Error(CErrorStr140, declinfo->name->name);
- else
- CError_Error(CErrorStr127);
- }
-
- obj = CParser_NewFunctionObject(declinfo);
- if (nspace)
- obj->nspace = nspace;
- if (pflag)
- *pflag = 1;
- else
- CError_Error(CErrorStr127);
-
- CheckDefaultArgs(TYPE_FUNC(obj->type)->args);
- CScope_AddObject(nspace2, declinfo->name, OBJ_BASE(obj));
- }
- }
-
- return obj;
-}
-
-void CDecl_TypedefDeclarator(DeclInfo *declinfo) {
- NameSpace *nspace;
- NameSpaceObjectList *list;
- ObjType *objt;
-
- nspace = declinfo->nspace;
- if (!nspace)
- nspace = cscope_current;
-
- CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST));
- if (declinfo->x48 || declinfo->x44)
- CError_Error(CErrorStr121);
- if (declinfo->operator_token)
- CError_Error(CErrorStr193);
-
- objt = NULL;
- list = CScope_FindName(nspace, declinfo->name);
- if (list) {
- switch (list->object->otype) {
- case OT_TYPE:
- objt = OBJ_TYPE(list->object);
- break;
- case OT_TYPETAG:
- break;
- case OT_NAMESPACE:
- CError_Error(CErrorStr321);
- return;
- case OT_ENUMCONST:
- case OT_OBJECT:
- CError_Error(CErrorStr322);
- return;
- default:
- CError_FATAL(2156);
- }
- }
-
- if (objt) {
- const UInt32 mask = Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST;
- if (!is_typesame(objt->type, declinfo->thetype) || (objt->qual & mask) != (declinfo->qual & mask)) {
- CError_Error(CErrorStr249, declinfo->name->name, objt->type, objt->qual, declinfo->thetype, declinfo->qual);
- } else if (!copts.cplusplus && (copts.pedantic || copts.ANSIstrict)) {
- if (copts.pedantic)
- CError_Warning(CErrorStr122, declinfo->name->name);
- else
- CError_Error(CErrorStr122, declinfo->name->name);
- }
- return;
- }
-
- objt = galloc(sizeof(ObjType));
- memclrw(objt, sizeof(ObjType));
- objt->otype = OT_TYPE;
- objt->access = ACCESSPUBLIC;
- objt->type = declinfo->thetype;
- objt->qual = declinfo->qual;
- CScope_AddObject(nspace, declinfo->name, OBJ_BASE(objt));
-
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL) &&
- CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype))
- CTemplClass_RegisterObjectDef(TEMPL_CLASS(nspace->theclass), OBJ_BASE(objt));
-
- if (copts.cplusplus) {
- if (IS_TYPE_CLASS(declinfo->thetype) && IsTempName(TYPE_CLASS(declinfo->thetype)->classname)) {
- TYPE_CLASS(declinfo->thetype)->classname = declinfo->name;
- TYPE_CLASS(declinfo->thetype)->nspace->name = declinfo->name;
- }
- if (IS_TYPE_ENUM(declinfo->thetype) && IsTempName(TYPE_ENUM(declinfo->thetype)->enumname)) {
- TYPE_ENUM(declinfo->thetype)->enumname = declinfo->name;
- }
- }
-
- if (cparamblkptr->browseoptions.recordTypedefs && declinfo->file->recordbrowseinfo)
- CBrowse_NewTypedef(nspace, declinfo->name, declinfo->file, declinfo->file2, declinfo->sourceoffset, CPrep_BrowserFileOffset());
-}
-
-static void CDecl_DataDeclarator(DeclInfo *declinfo, AccessType access, Boolean flag) {
- NameSpaceObjectList *list;
- Object *obj;
- NameSpace *nspace;
- Boolean tmpflag;
- ENode *expr;
-
- nspace = declinfo->nspace;
- if (!nspace)
- nspace = cscope_current;
-
- CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_PASCAL | Q_VOLATILE | Q_CONST));
- if (declinfo->x48 || declinfo->x44)
- CError_Error(CErrorStr121);
- if (declinfo->operator_token)
- CError_Error(CErrorStr193);
-
- obj = NULL;
- list = CScope_FindName(nspace, declinfo->name);
- if (list) {
- switch (list->object->otype) {
- case OT_OBJECT:
- obj = OBJECT(list->object);
- if (flag)
- CError_Error(CErrorStr122, declinfo->name->name);
- break;
- case OT_TYPETAG:
- break;
- case OT_NAMESPACE:
- CError_Error(CErrorStr321);
- return;
- case OT_ENUMCONST:
- case OT_TYPE:
- CError_Error(CErrorStr322);
- break;
- case OT_MEMBERVAR:
- CError_Error(CErrorStr221);
- break;
- default:
- CError_FATAL(2281);
- }
- }
-
- if (copts.cplusplus) {
- if (!flag)
- CDecl_CompleteType(declinfo->thetype);
- switch (declinfo->storageclass) {
- case TK_EXTERN:
- if (tk == '=' || tk == '(')
- declinfo->storageclass = 0;
- break;
- case 0:
- if (CParser_IsConst(declinfo->thetype, declinfo->qual)) {
- if ((!obj && !nspace->theclass) || (obj && obj->sclass != TK_EXTERN && !obj->nspace->theclass))
- declinfo->storageclass = TK_STATIC;
- }
- break;
- }
- } else {
- if (declinfo->storageclass == TK_EXTERN && tk == '=')
- declinfo->storageclass = 0;
- }
-
- if (IS_TYPE_ARRAY(declinfo->thetype) && !declinfo->thetype->size && !declinfo->storageclass && tk != '=')
- declinfo->storageclass = TK_EXTERN;
-
- if (obj) {
- if ((!obj->type->size || !declinfo->thetype->size) && IS_TYPE_ARRAY(declinfo->thetype) && IS_TYPE_ARRAY(obj->type))
- tmpflag = is_typesame(TYPE_POINTER(declinfo->thetype)->target, TYPE_POINTER(obj->type)->target);
- else
- tmpflag = is_typesame(declinfo->thetype, obj->type);
-
- if (!tmpflag || (obj->qual & (Q_PASCAL | Q_VOLATILE | Q_CONST)) != (declinfo->qual & (Q_PASCAL | Q_VOLATILE | Q_CONST)))
- CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, declinfo->thetype, declinfo->qual);
-
- if (obj->qual & Q_INLINE_DATA) {
- if (tk == ',' || tk == ';')
- return;
- CError_Error(CErrorStr333, obj);
- }
-
- if (declinfo->storageclass != TK_EXTERN) {
- if (obj->sclass != TK_EXTERN && declinfo->storageclass && obj->sclass != declinfo->storageclass)
- CError_Error(CErrorStr333, obj);
-
- if (tmpflag) {
- obj->sclass = declinfo->storageclass;
- obj->qual |= declinfo->qual;
- if (declinfo->thetype->size)
- obj->type = declinfo->thetype;
- }
-
- CParser_UpdateObject(obj, declinfo);
- } else {
- flag = 1;
- }
- } else {
- if (declinfo->nspace)
- CError_Error(CErrorStr336);
- if (IS_TYPE_CLASS(declinfo->thetype) && TYPE_CLASS(declinfo->thetype)->sominfo)
- CError_Error(CErrorStr288);
- if (!CanCreateObject(declinfo->thetype))
- declinfo->thetype = TYPE(&stsignedint);
-
- obj = CParser_NewGlobalDataObject(declinfo);
- obj->access = access;
- CScope_AddObject(nspace, declinfo->name, OBJ_BASE(obj));
-
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL) &&
- CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype))
- CTemplClass_RegisterObjectDef(TEMPL_CLASS(nspace->theclass), OBJ_BASE(obj));
-
- if (flag && nspace->theclass && cparamblkptr->browseoptions.recordClasses)
- CBrowse_AddClassMemberData(obj, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset());
- }
-
- if (!flag) {
- if (declinfo->nspace) {
- CScopeSave save;
- CScope_SetNameSpaceScope(declinfo->nspace, &save);
- CInit_InitializeData(obj);
- CScope_RestoreScope(&save);
-
- if (declinfo->x3C && obj->nspace->theclass && (TYPE_CLASS(obj->nspace->theclass)->flags & CLASS_IS_TEMPL_INST))
- declinfo->x3C = 0;
- } else {
- CInit_InitializeData(obj);
- }
-
- if (declinfo->file->recordbrowseinfo && obj->sclass != TK_EXTERN)
- CBrowse_NewData(obj, declinfo->file, declinfo->file2, declinfo->sourceoffset, CPrep_BrowserFileOffset());
- } else if (tk == '=') {
- tk = lex();
- expr = CExpr_IntegralConstOrDepExpr();
- if (IS_TYPE_TEMPLATE(obj->type) || !ENODE_IS(expr, EINTCONST)) {
- CError_ASSERT(2426, nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL));
- CTemplClass_RegisterObjectInit(TEMPL_CLASS(nspace->theclass), obj, expr);
- } else if ((obj->qual & Q_CONST) && IS_TYPE_INT_OR_ENUM(obj->type)) {
- obj->u.data.u.intconst = expr->data.intval;
- obj->qual |= Q_INLINE_DATA | Q_20000;
- } else {
- CError_Error(CErrorStr354, obj->name->name);
- }
- }
-}
-
-Boolean CDecl_FunctionDeclarator(DeclInfo *declinfo, NameSpace *nspace, Boolean flag, Boolean flag2) {
- Object *obj;
- Boolean pflag;
-
- obj = CDecl_GetFunctionObject(declinfo, nspace, &pflag, 0);
- if (obj) {
- if (declinfo->x44 || tk == '{' || tk == TK_TRY || (declinfo->x4B && tk == ':') || (!copts.cplusplus && isdeclaration(0, 0, 0, 0))) {
- if (!flag || cscope_currentfunc) {
- CError_Error(CErrorStr127);
- if (cscope_currentfunc)
- return 0;
- }
-
- if (obj->nspace == cscope_root && !strcmp(obj->name->name, "main")) {
- if (obj->sclass == TK_STATIC || (copts.ANSIstrict && TYPE_FUNC(obj->type)->functype != (Type *) &stsignedint))
- CError_Error(CErrorStr334);
- } else if (copts.checkprotos && (pflag || declinfo->x64)) {
- if (obj->sclass != TK_STATIC && !(obj->qual & Q_INLINE) && !obj->nspace->is_unnamed)
- CError_Warning(CErrorStr178);
- }
-
- CFunc_ParseFuncDef(obj, declinfo, NULL, 0, 0, NULL);
- if (declinfo->file->recordbrowseinfo)
- CBrowse_NewFunction(
- obj,
- declinfo->file,
- declinfo->file2,
- declinfo->sourceoffset,
- CPrep_BrowserFileOffset());
-
- if (copts.cplusplus && lookahead() == ';')
- tk = lex();
- return 0;
- }
- }
-
- return 1;
-}
-
-static void CDecl_ParseSpecialMember(DeclInfo *declinfo, Boolean flag) {
- Object *r28;
- NameSpace *r25;
-
- if (!(r28 = declinfo->x10)) {
- CError_ASSERT(2544, declinfo->x14);
- r28 = OBJECT(declinfo->x14->object);
- CError_ASSERT(2546, r28->otype == OT_OBJECT);
- }
-
- if (!r28->nspace->theclass) {
- CError_Error(CErrorStr121);
- return;
- }
-
- if (IS_TYPE_FUNC(r28->type)) {
- if (TYPE_FUNC(r28->type)->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) {
- if (r28->nspace->theclass->sominfo)
- declinfo->thetype = TYPE(&stvoid);
- else
- declinfo->thetype = TYPE(&void_ptr);
- declinfo->nspace = r28->nspace;
- declinfo->name = r28->name;
- if (TYPE_FUNC(r28->type)->flags & FUNC_IS_CTOR)
- declinfo->x4B = 1;
-
- if ((tk = lex()) == '(') {
- tk = lex();
-
- r25 = cscope_current;
- cscope_current = r28->nspace;
- CDecl_ParseDirectFuncDecl(declinfo);
- cscope_current = r25;
-
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- if (TYPE_FUNC(r28->type)->flags & FUNC_IS_CTOR) {
- if ((r28->nspace->theclass->flags & CLASS_HAS_VBASES) && !r28->nspace->theclass->sominfo)
- CDecl_AddArgument(TYPE_FUNC(declinfo->thetype), TYPE(&stsignedshort));
- } else {
- if (!r28->nspace->theclass->sominfo)
- CDecl_AddArgument(TYPE_FUNC(declinfo->thetype), TYPE(&stsignedshort));
- }
- if (flag)
- CDecl_FunctionDeclarator(declinfo, NULL, 1, 1);
- } else {
- CError_Error(CErrorStr121);
- }
- } else {
- CError_Error(CErrorStr114);
- }
- return;
- } else if (TYPE_FUNC(r28->type)->flags & FUNC_CONVERSION) {
- CError_FATAL(2603);
-
- declinfo->thetype = TYPE_FUNC(r28->type)->functype;
- declinfo->qual |= TYPE_FUNC(r28->type)->qual;
- declinfo->nspace = r28->nspace;
- declinfo->name = r28->name;
-
- if ((tk = lex()) == '(') {
- tk = lex();
- CDecl_ParseDirectFuncDecl(declinfo);
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- TYPE_FUNC(declinfo->thetype)->flags |= FUNC_CONVERSION;
- if (flag)
- CDecl_FunctionDeclarator(declinfo, NULL, 1, 1);
- } else {
- CError_Error(CErrorStr121);
- }
- } else {
- CError_Error(CErrorStr114);
- }
- return;
- } else {
- declinfo->thetype = TYPE(&stsignedint);
- declinfo->nspace = r28->nspace;
- declinfo->name = r28->name;
-
- if ((tk = lex()) == '(') {
- tk = lex();
-
- r25 = cscope_current;
- cscope_current = r28->nspace;
- CDecl_ParseDirectFuncDecl(declinfo);
- cscope_current = r25;
-
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- if (flag)
- CDecl_FunctionDeclarator(declinfo, NULL, 1, 1);
- return;
- }
- } else {
- CError_Error(CErrorStr114);
- }
- }
- }
-
- CError_Error(CErrorStr121);
-}
-
-void CDecl_ScanDeclarator(DeclInfo *declinfo) {
- if (declinfo->x14 || declinfo->x10) {
- CDecl_ParseSpecialMember(declinfo, 0);
- CDecl_GetFunctionObject(declinfo, NULL, NULL, 1);
- return;
- }
-
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- TypeFunc *copy = galloc(sizeof(TypeFunc));
- *copy = *TYPE_FUNC(declinfo->thetype);
- declinfo->thetype = TYPE(copy);
- }
- scandeclarator(declinfo);
- if (!declinfo->name) {
- CError_Error(CErrorStr121);
- return;
- }
-
- if (declinfo->storageclass && declinfo->storageclass != TK_EXTERN)
- CError_Error(CErrorStr177);
-
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- CDecl_GetFunctionObject(declinfo, NULL, NULL, 1);
- return;
- }
-
- if (declinfo->x48 || declinfo->x44)
- CError_Error(CErrorStr121);
-
- if (declinfo->operator_token)
- CError_Error(CErrorStr193);
-
- if (
- (declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_PASCAL | Q_VOLATILE | Q_CONST)) ||
- (declinfo->storageclass == TK_TYPEDEF && (declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST)))
- )
- CError_Error(CErrorStr176);
-}
-
-void scandeclaratorlist(DeclInfo *declinfo) {
- CScopeSave savescope;
- Type *r30;
- UInt32 r29;
- Boolean r28;
-
- if (declinfo->x14 || declinfo->x10) {
- CDecl_ParseSpecialMember(declinfo, 1);
- return;
- }
-
- CScope_GetScope(&savescope);
- CError_ASSERT(2707, declinfo->thetype);
-
- r28 = 1;
- while (1) {
- r30 = declinfo->thetype;
- r29 = declinfo->qual;
- declinfo->nspace = NULL;
- declinfo->operator_token = 0;
- if (IS_TYPE_FUNC(r30)) {
- declinfo->thetype = galloc(sizeof(TypeFunc));
- *TYPE_FUNC(declinfo->thetype) = *TYPE_FUNC(r30);
- }
- declinfo->name = NULL;
- scandeclarator(declinfo);
- if (!declinfo->name) {
- CError_Error(CErrorStr121);
- break;
- }
-
- if (declinfo->storageclass != TK_TYPEDEF) {
- if (IS_TYPE_FUNC(declinfo->thetype)) {
- if (!CDecl_FunctionDeclarator(declinfo, NULL, r28, 1))
- return;
- } else {
- CDecl_DataDeclarator(declinfo, ACCESSPUBLIC, 0);
- }
- } else {
- CDecl_TypedefDeclarator(declinfo);
- }
-
- CScope_RestoreScope(&savescope);
- declinfo->thetype = r30;
- declinfo->qual = r29;
-
- if (tk != ',')
- break;
- tk = lex();
- r28 = 0;
- }
-
- if (tk != ';')
- CError_Error(CErrorStr123);
-}
-
-static TypeIntegral *CDecl_FindSignedType(short size) {
- if (stsignedchar.size == size)
- return &stsignedchar;
- if (stsignedshort.size == size)
- return &stsignedshort;
- if (stsignedint.size == size)
- return &stsignedint;
- if (stsignedlong.size == size)
- return &stsignedlong;
- if (copts.longlong && copts.longlong_enums && stsignedlonglong.size == size)
- return &stsignedlonglong;
- return &stsignedlong;
-}
-
-static TypeIntegral *CDecl_FindUnsignedType(short size) {
- if (stunsignedchar.size == size)
- return &stunsignedchar;
- if (stunsignedshort.size == size)
- return &stunsignedshort;
- if (stunsignedint.size == size)
- return &stunsignedint;
- if (stunsignedlong.size == size)
- return &stunsignedlong;
- if (copts.longlong && copts.longlong_enums && stunsignedlonglong.size == size)
- return &stunsignedlonglong;
- return &stunsignedlong;
-}
-
-static TypeIntegral *CDecl_IterateIntegralEnumType(int *t) {
- switch (*t) {
- case 0:
- *t = 1;
- return &stsignedchar;
- case 1:
- if (stsignedshort.size > stsignedchar.size) {
- *t = 2;
- return &stsignedshort;
- }
- case 2:
- if (stsignedint.size > stsignedshort.size) {
- *t = 3;
- return &stsignedint;
- }
- case 3:
- if (stsignedlong.size > stsignedint.size) {
- *t = 4;
- return &stsignedlong;
- }
- case 4:
- *t = 5;
- if (stsignedlonglong.size > stsignedlong.size && copts.longlong && copts.longlong_enums)
- return &stsignedlonglong;
- default:
- return NULL;
- }
-}
-
-static TypeIntegral *CDecl_IterateUIntegralEnumType(int *t) {
- switch (*t) {
- case 0:
- *t = 1;
- return &stunsignedchar;
- case 1:
- if (stunsignedshort.size > stunsignedchar.size) {
- *t = 2;
- return &stunsignedshort;
- }
- case 2:
- if (stunsignedint.size > stunsignedshort.size) {
- *t = 3;
- return &stunsignedint;
- }
- case 3:
- if (stunsignedlong.size > stunsignedint.size) {
- *t = 4;
- return &stunsignedlong;
- }
- case 4:
- *t = 5;
- if (stunsignedlonglong.size > stunsignedlong.size && copts.longlong && copts.longlong_enums)
- return &stunsignedlonglong;
- default:
- return NULL;
- }
-}
-
-static TypeEnum *CDecl_OldParseEnumList(TypeEnum *tenum, HashNameNode *name) {
- AccessType access;
- Boolean has_template_value;
- Boolean r24;
- Boolean r23;
- ObjEnumConst *oec;
- ObjEnumConst *last;
- Boolean overflowed;
- CInt64 val;
- CInt64 minimum;
- CInt64 maximum;
- CInt64 var_74;
- CInt64 unused;
- Type *basetype;
- Type *basetype2;
- CPrepFileInfo *fileinfo;
- SInt32 offset;
- ENode *expr;
- Type *tmp;
-
- if (!tenum) {
- tenum = galloc(sizeof(TypeEnum));
- memclrw(tenum, sizeof(TypeEnum));
- tenum->type = TYPEENUM;
- tenum->nspace = cscope_current;
-
- if (name) {
- tenum->enumname = name;
- CScope_DefineTypeTag(cscope_current, name, TYPE(tenum));
- }
-
- if (!cscope_current->is_global) {
- do {
- tenum->nspace = tenum->nspace->parent;
- } while (!tenum->nspace->is_global);
- if (tenum->enumname)
- tenum->enumname = CParser_AppendUniqueNameFile(tenum->enumname->name);
- }
- }
-
- if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL)) {
- CTemplClass_RegisterEnumType(TEMPL_CLASS(cscope_current->theclass), tenum);
- }
-
- access = cscope_current->theclass ? global_access : ACCESSPUBLIC;
- last = NULL;
- unused = cint64_zero;
- val = cint64_zero;
- minimum = cint64_zero;
- maximum = cint64_zero;
- r23 = 0;
- if (copts.enumsalwaysint) {
- basetype = TYPE(&stsignedint);
- r24 = 1;
- } else {
- basetype = TYPE(&stunsignedchar);
- r24 = 0;
- }
-
- tk = lex();
- if (!copts.cplusplus || tk != '}') {
- do {
- if (tk != TK_IDENTIFIER) {
- if (tk == '}') {
- if (copts.cpp_extensions)
- break;
- if (!copts.warn_extracomma)
- break;
- }
- CError_Warning(CErrorStr107);
- break;
- }
-
- oec = galloc(sizeof(ObjEnumConst));
- memclrw(oec, sizeof(ObjEnumConst));
- oec->otype = OT_ENUMCONST;
- oec->access = access;
- oec->type = TYPE(tenum);
- oec->name = tkidentifier;
- CPrep_BrowserFilePosition(&fileinfo, &offset);
- overflowed = 0;
- if ((tk = lex()) == '=') {
- tk = lex();
- val = CExpr_IntegralConstExprType(&basetype2);
- if (!CInt64_IsNegative(&val) || is_unsigned(basetype2)) {
- if (CInt64_GreaterU(val, minimum)) {
- minimum = val;
- overflowed = 1;
- }
- } else {
- if (CInt64_Less(val, maximum)) {
- maximum = val;
- overflowed = 1;
- }
- if (!r24) {
- basetype = TYPE(&stsignedchar);
- r24 = 1;
- }
- }
- r23 = 0;
- } else {
- if (r23)
- CError_Error(CErrorStr154);
-
- if (!r24 || !CInt64_IsNegative(&val)) {
- if (CInt64_GreaterU(val, minimum)) {
- minimum = val;
- overflowed = 1;
- }
- } else {
- if (CInt64_Less(val, maximum)) {
- maximum = val;
- overflowed = 1;
- }
- }
- }
-
- if (copts.enumsalwaysint) {
- if (copts.ANSIstrict) {
- if (!CInt64_IsInRange(val, stsignedint.size))
- CError_Error(CErrorStr154);
- } else {
- if (!CInt64_IsInRange(val, stsignedint.size) && !CInt64_IsInURange(val, stunsignedint.size))
- CError_Error(CErrorStr154);
- }
- } else if (r24) {
- switch (basetype->size) {
- case 1:
- if (CInt64_IsInRange(minimum, 1) && CInt64_IsInRange(maximum, 1))
- break;
- basetype = TYPE(CDecl_FindSignedType(2));
- case 2:
- if (CInt64_IsInRange(minimum, 2) && CInt64_IsInRange(maximum, 2))
- break;
- basetype = TYPE(CDecl_FindSignedType(4));
- case 4:
- if (CInt64_IsInRange(minimum, 4) && CInt64_IsInRange(maximum, 4))
- break;
- basetype = TYPE(CDecl_FindSignedType(8));
- if (basetype->size != 8) {
- if (!copts.ANSIstrict && CInt64_IsInRange(maximum, 4) && CInt64_IsInURange(minimum, 4))
- break;
- if (overflowed)
- CError_Error(CErrorStr154);
- break;
- }
- case 8:
- if (CInt64_Equal(val, minimum) && CInt64_IsNegative(&val))
- CError_Error(CErrorStr154);
- break;
- default:
- CError_FATAL(3071);
- }
- } else {
- switch (basetype->size) {
- case 1:
- if (CInt64_IsInURange(minimum, 1))
- break;
- basetype = TYPE(CDecl_FindUnsignedType(2));
- case 2:
- if (CInt64_IsInURange(minimum, 2))
- break;
- basetype = TYPE(CDecl_FindUnsignedType(4));
- case 4:
- if (CInt64_IsInURange(minimum, 4))
- break;
- basetype = TYPE(CDecl_FindUnsignedType(8));
- if (basetype->size != 8) {
- if (overflowed)
- CError_Error(CErrorStr154);
- break;
- }
- case 8:
- break;
- default:
- CError_FATAL(3099);
- }
- }
-
- tenum->size = basetype->size;
- tenum->enumtype = basetype;
- oec->val = val;
- CScope_AddObject(cscope_current, oec->name, OBJ_BASE(oec));
-
- if (last) {
- last->next = oec;
- last = oec;
- } else {
- last = oec;
- tenum->enumlist = oec;
- }
-
- if (cparamblkptr->browseoptions.recordEnums) {
- CPrepFileInfo *f = CPrep_BrowserCurrentFile();
- if (f->recordbrowseinfo) {
- CBrowse_NewEnumConstant(cscope_current, oec->name, f, fileinfo, offset, CPrep_BrowserFileOffset());
- }
- }
-
- var_74 = CInt64_Add(val, cint64_one);
- if (r24) {
- if (CInt64_IsNegative(&var_74) && !CInt64_IsNegative(&val))
- r23 = 1;
- } else {
- if (CInt64_IsZero(&var_74))
- r23 = 1;
- }
- val = var_74;
-
- if (tk != ',')
- break;
- tk = lex();
- } while (1);
- }
-
- tenum->size = basetype->size;
- tenum->enumtype = basetype;
-
- for (oec = tenum->enumlist; oec; oec = oec->next)
- oec->type = TYPE(tenum);
-
- if (tk != '}')
- CError_ErrorSkip(CErrorStr130);
- else
- tk = lex();
-
- return tenum;
-}
-
-static Type *CDecl_MaxType(Type *a, Type *b) {
- if (a->size > b->size)
- return a;
- if (b->size > a->size)
- return b;
- if (is_unsigned(b))
- return b;
- else
- return a;
-}
-
-void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) {
- ObjEnumConst *oec;
- ObjEnumConst *oec2;
- Type *r26;
- int t;
-
- if (!copts.enumsalwaysint) {
- for (oec2 = tenum->enumlist; oec2; oec2 = oec2->next) {
- if (CInt64_IsNegative(&oec2->val) && !is_unsigned(oec2->type))
- break;
- }
-
- if (oec2) {
- CInt64 unused = cint64_zero;
- CInt64 minimum = cint64_zero;
- CInt64 maximum = cint64_zero;
- for (oec = tenum->enumlist; oec; oec = oec->next) {
- if (CInt64_IsNegative(&oec->val) && !is_unsigned(oec->type)) {
- if (CInt64_Less(oec->val, minimum))
- minimum = oec->val;
- } else {
- if (CInt64_GreaterU(oec->val, maximum))
- maximum = oec->val;
- }
- }
-
- if (CInt64_IsNegative(&maximum))
- CError_Error(CErrorStr154);
-
- t = 0;
- do {
- r26 = TYPE(CDecl_IterateIntegralEnumType(&t));
- if (!r26) {
- r26 = TYPE(&stsignedlong);
- CError_Error(CErrorStr154);
- break;
- }
-
- if (CInt64_IsInRange(maximum, r26->size) && CInt64_IsInRange(minimum, r26->size))
- break;
- if (r26->size == stsignedlong.size && !copts.ANSIstrict && CInt64_IsInRange(minimum, r26->size) && CInt64_IsInURange(maximum, r26->size))
- break;
- } while (1);
- } else {
- CInt64 val = cint64_zero;
-
- for (oec = tenum->enumlist; oec; oec = oec->next) {
- if (CInt64_GreaterU(oec->val, val))
- val = oec->val;
- }
-
- t = 0;
- do {
- r26 = TYPE(CDecl_IterateUIntegralEnumType(&t));
- if (!r26) {
- r26 = TYPE(&stunsignedlong);
- CError_Error(CErrorStr154);
- break;
- }
- if (CInt64_IsInURange(val, r26->size))
- break;
- } while (1);
- }
- } else {
- r26 = TYPE(&stsignedint);
- }
-
- tenum->size = r26->size;
- tenum->enumtype = r26;
- for (oec = tenum->enumlist; oec; oec = oec->next)
- oec->type = TYPE(tenum);
-}
-
-static Type *CDecl_FindUnderlyingType(short size, CInt64 *a, CInt64 *b) {
- if (CInt64_IsZero(a)) {
- if (size <= stsignedchar.size && CInt64_IsInURange(*b, stunsignedchar.size))
- return TYPE(&stunsignedchar);
- if (size <= stsignedshort.size && CInt64_IsInURange(*b, stunsignedshort.size))
- return TYPE(&stunsignedshort);
- if (size <= stsignedint.size && CInt64_IsInURange(*b, stunsignedint.size))
- return TYPE(&stunsignedint);
- if (size <= stsignedlong.size && CInt64_IsInURange(*b, stunsignedlong.size))
- return TYPE(&stunsignedlong);
- if (size <= stsignedlonglong.size && copts.longlong && copts.longlong_enums && CInt64_IsInURange(*b, stunsignedlonglong.size))
- return TYPE(&stunsignedlonglong);
- } else {
- if (size <= stsignedchar.size && CInt64_IsInRange(*a, stsignedchar.size) && CInt64_IsInRange(*b, stsignedchar.size))
- return TYPE(&stsignedchar);
- if (size <= stsignedshort.size && CInt64_IsInRange(*a, stsignedshort.size) && CInt64_IsInRange(*b, stsignedshort.size))
- return TYPE(&stsignedshort);
- if (size <= stsignedint.size && CInt64_IsInRange(*a, stsignedint.size) && CInt64_IsInRange(*b, stsignedint.size))
- return TYPE(&stsignedint);
- if (size <= stsignedlong.size && CInt64_IsInRange(*a, stsignedlong.size) && CInt64_IsInRange(*b, stsignedlong.size))
- return TYPE(&stsignedlong);
- if (size <= stsignedlonglong.size && copts.longlong && copts.longlong_enums && CInt64_IsInRange(*a, stsignedlonglong.size) && CInt64_IsInRange(*b, stsignedlonglong.size))
- return TYPE(&stsignedlonglong);
- if (!copts.ANSIstrict && size <= stsignedlong.size && CInt64_IsInRange(*a, stsignedlong.size) && CInt64_IsInURange(*b, stunsignedlong.size))
- return TYPE(&stsignedlong);
- }
-
- return NULL;
-}
-
-static TypeEnum *CDecl_ParseEnumList(TypeEnum *tenum, HashNameNode *name) {
- AccessType access;
- TemplClass *tmclass;
- ObjEnumConst *oec;
- Boolean has_template_value;
- Boolean overflowed;
- Boolean is_first;
- CInt64 val;
- CInt64 minimum;
- CInt64 maximum;
- CInt64 unused;
- Type *basetype;
- CPrepFileInfo *fileinfo;
- SInt32 offset;
- ENode *expr;
- Type *tmp;
- ObjEnumConst *last;
-
- if (!tenum) {
- tenum = galloc(sizeof(TypeEnum));
- memclrw(tenum, sizeof(TypeEnum));
- tenum->type = TYPEENUM;
- tenum->nspace = cscope_current;
-
- if (name) {
- tenum->enumname = name;
- CScope_DefineTypeTag(cscope_current, name, TYPE(tenum));
- }
-
- if (!cscope_current->is_global) {
- do {
- tenum->nspace = tenum->nspace->parent;
- } while (!tenum->nspace->is_global);
- if (tenum->enumname)
- tenum->enumname = CParser_AppendUniqueNameFile(tenum->enumname->name);
- }
- }
-
- if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL)) {
- tmclass = TEMPL_CLASS(cscope_current->theclass);
- CTemplClass_RegisterEnumType(tmclass, tenum);
- } else {
- tmclass = NULL;
- }
-
- access = cscope_current->theclass ? global_access : ACCESSPUBLIC;
- last = NULL;
- is_first = 1;
- has_template_value = 0;
- unused = cint64_zero;
- val = cint64_zero;
- minimum = cint64_zero;
- maximum = cint64_zero;
- basetype = copts.enumsalwaysint ? TYPE(&stsignedint) : TYPE(&stsignedchar);
- tenum->size = basetype->size;
- tenum->enumtype = basetype;
-
- do {
- if ((tk = lex()) != TK_IDENTIFIER) {
- if (tk == '}') {
- if (is_first) {
- if (copts.cplusplus)
- break;
- } else {
- if (!copts.warn_extracomma)
- break;
- if (copts.c9x)
- break;
- if (copts.cpp_extensions)
- break;
- }
- CError_Warning(CErrorStr107);
- } else {
- CError_Error(CErrorStr107);
- }
- break;
- }
-
- oec = galloc(sizeof(ObjEnumConst));
- memclrw(oec, sizeof(ObjEnumConst));
- oec->otype = OT_ENUMCONST;
- oec->access = access;
- oec->name = tkidentifier;
- CPrep_BrowserFilePosition(&fileinfo, &offset);
- overflowed = 0;
- if ((tk = lex()) == '=') {
- tk = lex();
- if (tmclass) {
- expr = CExpr_IntegralConstOrDepExpr();
- if (ENODE_IS(expr, EINTCONST)) {
- val = expr->data.intval;
- basetype = expr->rtype;
- has_template_value = 0;
- } else {
- val = cint64_zero;
- basetype = TYPE(tenum);
- CTemplClass_RegisterEnumerator(tmclass, oec, expr);
- has_template_value = 1;
- }
- } else {
- val = CExpr_IntegralConstExprType(&basetype);
- has_template_value = 0;
- }
- } else if (has_template_value) {
- CTemplClass_RegisterEnumerator(tmclass, oec, NULL);
- } else if (!is_first) {
- if (is_unsigned(basetype)) {
- val = CInt64_Add(val, cint64_one);
- if (CInt64_IsZero(&val))
- overflowed = 1;
- } else if (!CInt64_IsNegative(&val)) {
- val = CInt64_Add(val, cint64_one);
- if (CInt64_IsNegative(&val))
- overflowed = 1;
- } else {
- val = CInt64_Add(val, cint64_one);
- }
- }
-
- if (!has_template_value) {
- if (copts.enumsalwaysint) {
- if (!CInt64_IsInRange(val, stsignedint.size) && (copts.ANSIstrict || !CInt64_IsInURange(val, stunsignedint.size)))
- overflowed = 1;
- basetype = TYPE(&stsignedint);
- } else if (CInt64_IsNegative(&val) && !is_unsigned(basetype)) {
- if (CInt64_Less(val, minimum)) {
- minimum = val;
- if ((tmp = CDecl_FindUnderlyingType(tenum->size, &minimum, &maximum))) {
- tenum->size = tmp->size;
- tenum->enumtype = tmp;
- } else {
- overflowed = 1;
- }
- }
- } else {
- if (CInt64_GreaterU(val, maximum)) {
- maximum = val;
- if ((tmp = CDecl_FindUnderlyingType(tenum->size, &minimum, &maximum))) {
- tenum->size = tmp->size;
- tenum->enumtype = tmp;
- } else {
- overflowed = 1;
- }
- }
- }
- }
-
- if (overflowed)
- CError_Error(CErrorStr154);
-
- oec->val = val;
- oec->type = basetype;
- CScope_AddObject(cscope_current, oec->name, OBJ_BASE(oec));
-
- if (last) {
- last->next = oec;
- last = oec;
- } else {
- last = oec;
- tenum->enumlist = oec;
- }
-
- if (cparamblkptr->browseoptions.recordEnums) {
- CPrepFileInfo *f = CPrep_BrowserCurrentFile();
- if (f->recordbrowseinfo) {
- CBrowse_NewEnumConstant(cscope_current, oec->name, f, fileinfo, offset, CPrep_BrowserFileOffset());
- }
- }
-
- is_first = 0;
- } while (tk == ',');
-
- for (oec = tenum->enumlist; oec; oec = oec->next)
- oec->type = TYPE(tenum);
-
- if (tk != '}')
- CError_ErrorSkip(CErrorStr130);
- else
- tk = lex();
-
- return tenum;
-}
-
-void scanenum(DeclInfo *declinfo) {
- HashNameNode *name;
- Type *type;
- NameResult pr;
-
- if (tk == '{') {
- declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, NULL));
- TYPE_ENUM(declinfo->thetype)->enumname = CParser_AppendUniqueNameFile("@enum");
- return;
- }
-
- if (tk == TK_IDENTIFIER) {
- name = tkidentifier;
- if (lookahead() == '{') {
- type = CScope_GetLocalTagType(cscope_current, name);
- if (type) {
- lex();
- do_shit:
- if (type->size || !IS_TYPE_ENUM(type)) {
- CError_Error(CErrorStr122, name->name);
- declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, NULL));
- return;
- }
- declinfo->thetype = TYPE(CDecl_ParseEnumList(TYPE_ENUM(type), NULL));
- } else {
- lex();
- declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, name));
- }
-
- if (cparamblkptr->browseoptions.recordEnums && declinfo->file->recordbrowseinfo)
- CBrowse_NewEnum(
- cscope_current,
- TYPE_ENUM(declinfo->thetype)->enumname,
- declinfo->file,
- declinfo->file2,
- declinfo->sourceoffset,
- CPrep_BrowserFileOffset());
- return;
- } else {
- CError_ASSERT(3851, !copts.cplusplus || tk != ';');
- tkidentifier = name;
- }
- }
-
- if (CScope_ParseElaborateName(&pr)) {
- if ((type = pr.type)) {
- if (!IS_TYPE_ENUM(type))
- CError_Error(CErrorStr121);
- if ((tk = lex()) == '{')
- goto do_shit;
- declinfo->thetype = type;
- return;
- } else {
- CError_ASSERT(3865, pr.name_4);
- if ((tk = lex()) == '{') {
- declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, pr.name_4));
- return;
- } else {
- CError_Error(CErrorStr140, pr.name_4->name);
- }
- }
- } else {
- CError_Error(CErrorStr121);
- }
-
- declinfo->thetype = TYPE(&stsignedint);
-}
-
-void CDecl_ScanStructDeclarator(BigDeclInfo *bde) {
- ENode *expr;
- short val;
- short bits;
- Boolean is_bitfield;
- TypeTemplDep *ttempl;
- TypeBitfield *tbitfield;
- Type *type;
-
- bde->declinfo2 = bde->declinfo;
- bde->declinfo2.name = NULL;
- bde->declinfo2.operator_token = 0;
- bde->xCD = 0;
- is_bitfield = 0;
-
- if (tk == ':') {
- bde->declinfo2.name = no_name_node;
- is_bitfield = 1;
- } else {
- bde->declinfo2.x50 = 1;
- scandeclarator(&bde->declinfo2);
- if (!bde->declinfo2.name) {
- CError_Error(CErrorStr131);
- return;
- }
-
- if ((!copts.ANSIstrict || copts.c9x) && !bde->declinfo2.thetype->size && IS_TYPE_ARRAY(bde->declinfo2.thetype)) {
- if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) {
- type = TYPE_POINTER(bde->declinfo2.thetype)->target;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (!IsCompleteType(type))
- return;
- if (tk != ';' || lookahead() != '}') {
- CError_Error(CErrorStr145);
- return;
- }
- }
- } else {
- if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) {
- if (!IS_TYPE_FUNC(bde->declinfo2.thetype) && !IsCompleteType(bde->declinfo2.thetype))
- return;
- }
- }
-
- if (IS_TYPE_CLASS(bde->declinfo2.thetype) && TYPE_CLASS(bde->declinfo2.thetype)->sominfo) {
- CError_Error(CErrorStr287);
- return;
- }
-
- if (tk != ':')
- goto not_a_bitfield;
- }
-
- if (!IS_TYPE_INT_OR_ENUM(bde->declinfo2.thetype)) {
- if (CTemplTool_IsTemplateArgumentDependentType(bde->declinfo2.thetype))
- goto fuckup;
- CError_Error(CErrorStr138);
- bde->declinfo2.thetype = TYPE(&stunsignedint);
- } else if (copts.ANSIstrict && !copts.cplusplus) {
- if (bde->declinfo2.thetype != TYPE(&stsignedint) && bde->declinfo2.thetype != TYPE(&stunsignedint)) {
- CError_Error(CErrorStr138);
- bde->declinfo2.thetype = TYPE(&stunsignedint);
- }
- }
-
- switch (bde->declinfo2.thetype->size) {
- case 1:
- bits = 8;
- break;
- case 2:
- bits = 16;
- break;
- case 4:
- bits = 32;
- break;
- default:
- CError_Error(CErrorStr138);
- return;
- }
-fuckup:
- tk = lex();
- expr = CExpr_IntegralConstOrDepExpr();
- if (!ENODE_IS(expr, EINTCONST)) {
- ttempl = TYPE_TEMPLATE(CDecl_NewTemplDepType(TEMPLDEP_BITFIELD));
- ttempl->u.bitfield.type = bde->declinfo2.thetype;
- ttempl->u.bitfield.size = CInline_CopyExpression(expr, CopyMode1);
- bde->declinfo2.thetype = TYPE(ttempl);
- bde->xCD = 1;
- return;
- }
- val = CInt64_GetULong(&expr->data.intval);
- if (is_bitfield) {
- if (val < 0 || val > bits) {
- CError_Error(CErrorStr138);
- return;
- }
- } else {
- if (val <= 0 || val > bits) {
- CError_Error(CErrorStr138);
- return;
- }
- }
-
- tbitfield = galloc(sizeof(TypeBitfield));
- memclrw(tbitfield, sizeof(TypeBitfield));
- tbitfield->type = TYPEBITFIELD;
- tbitfield->size = bde->declinfo2.thetype->size;
- tbitfield->bitfieldtype = bde->declinfo2.thetype;
- tbitfield->bitlength = val;
- bde->declinfo2.thetype = TYPE(tbitfield);
-
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(NULL, &bde->declinfo2);
-
-not_a_bitfield:
- bde->xCD = 1;
-}
-
-static void CDecl_LayoutStruct(TypeStruct *tstruct) {
- StructMember *member;
- SInt32 r28;
- StructMember *innermember;
- SInt32 innerbase;
- StructMember *newmember;
- StructMember **memberp;
- TypeBitfield *bf;
- SInt32 r24;
- Boolean r23;
- SInt32 tmp;
-
- r28 = 0;
- r23 = 0;
- CMach_StructLayoutInitOffset(0);
- for (member = tstruct->members; member; member = member->next) {
- if (tstruct->stype == STRUCT_TYPE_UNION)
- CMach_StructLayoutInitOffset(0);
-
- if (IS_TYPE_BITFIELD(member->type))
- member->offset = CMach_StructLayoutBitfield(TYPE_BITFIELD(member->type), member->qual);
- else
- member->offset = CMach_StructLayoutGetOffset(member->type, member->qual);
-
- if (tstruct->stype == STRUCT_TYPE_UNION) {
- tmp = CMach_StructLayoutGetCurSize();
- if (tmp > r28)
- r28 = tmp;
- }
-
- if (member->name == no_name_node)
- r23 = 1;
-
- if (!member->name) {
- CError_ASSERT(4064, IS_TYPE_STRUCT(member->type));
- innerbase = member->offset;
- innermember = TYPE_STRUCT(member->type)->members;
- r23 = 1;
- while (innermember) {
- if (ismember(tstruct, innermember->name))
- CError_Error(CErrorStr133, innermember->name->name);
- if (r23) {
- member->type = innermember->type;
- member->name = innermember->name;
- member->qual = innermember->qual;
- member->offset = innerbase + innermember->offset;
- } else {
- newmember = galloc(sizeof(StructMember));
- memclrw(newmember, sizeof(StructMember));
- newmember->next = member->next;
- newmember->type = innermember->type;
- newmember->name = innermember->name;
- newmember->qual = innermember->qual | Q_WEAK;
- newmember->offset = innerbase + innermember->offset;
- member->next = newmember;
- member = newmember;
- }
- if (copts.reverse_bitfields && IS_TYPE_BITFIELD(member->type)) {
- bf = galloc(sizeof(TypeBitfield));
- *bf = *TYPE_BITFIELD(member->type);
- CABI_ReverseBitField(bf);
- member->type = TYPE(bf);
- }
- r23 = 0;
- innermember = innermember->next;
- }
- r23 = 1;
- }
- }
-
- if (r23) {
- memberp = &tstruct->members;
- while (*memberp) {
- if ((*memberp)->name == no_name_node || !(*memberp)->name)
- *memberp = (*memberp)->next;
- else
- memberp = &(*memberp)->next;
- }
- }
-
- if (tstruct->stype == STRUCT_TYPE_UNION)
- r24 = r28;
- else
- r24 = CMach_StructLayoutGetCurSize();
- tstruct->size = r24;
- tstruct->align = CMach_GetStructAlign(tstruct);
- tstruct->size = r24 + CABI_StructSizeAlignValue(TYPE(tstruct), r24);
-
- if (copts.reverse_bitfields) {
- for (member = tstruct->members; member; member = member->next) {
- if (IS_TYPE_BITFIELD(member->type))
- CABI_ReverseBitField(TYPE_BITFIELD(member->type));
- }
- }
-
- if (copts.warn_padding && tstruct->stype != STRUCT_TYPE_UNION) {
- StructMember *prev;
-
- member = tstruct->members;
- prev = NULL;
- while (member) {
- if (prev && (prev->offset + prev->type->size) < member->offset) {
- CError_Warning(CErrorStr350, member->offset - (prev->offset + prev->type->size), prev->name->name);
- }
- prev = member;
- member = member->next;
- }
-
- if (prev && (prev->offset + prev->type->size) < tstruct->size) {
- CError_Warning(CErrorStr350, tstruct->size - (prev->offset + prev->type->size), prev->name->name);
- }
- }
-}
-
-static SInt32 scanstructdeclarationlist(TypeStruct *tstruct, Boolean flag) {
- SInt32 offset;
- StructMember *member;
- BigDeclInfo bde;
-
- offset = -1;
- memclrw(&bde, sizeof(BigDeclInfo));
-
- if (tk == TK_AT_DEFS) {
- CPrep_NewFileOffsetInfo(&member_fileoffset, NULL);
- CObjC_ParseDefs(tstruct);
- if ((tk = lex()) != '}')
- CError_Error(CErrorStr130);
- } else {
- do {
- CPrep_NewFileOffsetInfo(&member_fileoffset, NULL);
- memclrw(&bde.declinfo, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&bde.declinfo, 0);
- if (bde.declinfo.storageclass || bde.declinfo.x44) {
- CError_Error(CErrorStr131);
- tstruct->members = NULL;
- return -1;
- }
-
- if (tk != ';') {
- while (1) {
- CDecl_ScanStructDeclarator(&bde);
- if (!CanCreateObject(bde.declinfo2.thetype)) {
- CError_Error(CErrorStr131);
- bde.xCD = 0;
- }
-
- if (bde.declinfo2.operator_token) {
- CError_Error(CErrorStr131);
- bde.xCD = 0;
- }
-
- if (bde.xCD) {
- if (bde.declinfo2.name == no_name_node || !ismember(tstruct, bde.declinfo2.name)) {
- member = galloc(sizeof(StructMember));
- memclrw(member, sizeof(StructMember));
- member->type = bde.declinfo2.thetype;
- member->name = bde.declinfo2.name;
- member->qual = bde.declinfo2.qual;
- appendmember(tstruct, member);
-
- if (flag) {
- CBrowse_AddStructMember(member, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset());
- }
- } else {
- CError_Error(CErrorStr133, bde.declinfo2.name->name);
- }
- }
-
- if (tk != ',')
- break;
- tk = lex();
- }
- } else if (!copts.ANSIstrict && IS_TYPE_STRUCT(bde.declinfo.thetype)) {
- member = galloc(sizeof(StructMember));
- memclrw(member, sizeof(StructMember));
- member->type = bde.declinfo.thetype;
- appendmember(tstruct, member);
- } else {
- CError_Error(CErrorStr131);
- }
-
- if (tk != ';') {
- tstruct->members = NULL;
- CError_Error(CErrorStr123);
- return -1;
- }
-
- CPrep_TokenStreamFlush();
- } while ((tk = lex()) != '}');
- CDecl_LayoutStruct(tstruct);
- }
-
- if (flag) {
- offset = CPrep_BrowserFileOffset();
- if (tk == ';')
- offset++;
- }
-
- tk = lex();
- return offset;
-}
-
-static TypeStruct *CDecl_DefineStruct(HashNameNode *name, short stype) {
- TypeStruct *tstruct;
-
- tstruct = galloc(sizeof(TypeStruct));
- memclrw(tstruct, sizeof(TypeStruct));
-
- tstruct->type = TYPESTRUCT;
- tstruct->align = 1;
- tstruct->stype = stype;
- if (name) {
- tstruct->name = name;
- CScope_DefineTypeTag((in_func_arglist && !copts.cplusplus) ? cscope_root : cscope_current, name, (Type *) tstruct);
- }
-
- return tstruct;
-}
-
-void scanstruct(DeclInfo *declinfo, short structtype) {
- Type *type;
- HashNameNode *name;
- TypeStruct typecopy;
- Boolean add_to_browse;
- GList gl;
- SInt32 offset;
-
- if (copts.cplusplus) {
- CDecl_ParseClass(declinfo, structtype, 1, 0);
- return;
- }
-
- if (tk == TK_IDENTIFIER) {
- name = tkidentifier;
- type = CScope_GetTagType(cscope_current, name);
- if (type) {
- if (IS_TYPE_CLASS(type)) {
- CDecl_ParseClass(declinfo, structtype, 1, 0);
- return;
- }
-
- tk = lex();
- if (!CScope_GetLocalTagType(cscope_current, name) && (tk == ';' || tk == '{'))
- type = (Type *) CDecl_DefineStruct(name, structtype);
-
- if (!IS_TYPE_STRUCT(type) || TYPE_STRUCT(type)->stype != structtype) {
- CError_Error(CErrorStr132, name->name);
- declinfo->thetype = type;
- return;
- }
-
- if (tk != '{') {
- declinfo->thetype = type;
- return;
- }
-
- if (type->size) {
- CError_Error(CErrorStr132, name->name);
- type = (Type *) CDecl_DefineStruct(NULL, structtype);
- }
- } else {
- type = (Type *) CDecl_DefineStruct(name, structtype);
- if ((tk = lex()) != '{') {
- declinfo->thetype = type;
- return;
- }
- }
- } else if (tk != '{') {
- CError_Error(CErrorStr131);
- declinfo->thetype = (Type *) &stsignedint;
- return;
- } else {
- type = (Type *) CDecl_DefineStruct(NULL, structtype);
- }
-
- if ((add_to_browse = cparamblkptr->browseoptions.recordClasses && declinfo->file->recordbrowseinfo))
- CBrowse_BeginStruct(declinfo, TYPE_STRUCT(type), &gl);
-
- typecopy = *TYPE_STRUCT(type);
- tk = lex();
- offset = scanstructdeclarationlist(&typecopy, add_to_browse);
- *TYPE_STRUCT(type) = typecopy;
- declinfo->thetype = type;
-
- if (add_to_browse)
- CBrowse_EndStruct(offset, &gl);
-}
-
-static void InlineFunctionObject(Object *obj, TypeClass *tclass) {
- TokenStream stream;
- CPrepFileInfo *file;
-
- obj->qual |= Q_INLINE;
- TYPE_FUNC(obj->type)->flags |= FUNC_DEFINED;
-
- CPrep_StreamGetBlock(&stream, NULL, 1);
- if (stream.tokens) {
- if (IS_TYPEFUNC_METHOD(TYPE_FUNC(obj->type)) && (TYPE_METHOD(obj->type)->theclass->flags & CLASS_IS_TEMPL)) {
- TYPE_FUNC(obj->type)->flags |= FUNC_IS_TEMPL_INSTANCE;
- CTemplClass_DefineMember(TEMPL_CLASS(TYPE_METHOD(obj->type)->theclass), obj, &member_fileoffset, &stream);
- } else {
- CInline_AddInlineFunctionAction(obj, tclass, &member_fileoffset, &stream, 0);
- }
- }
-
- file = CPrep_BrowserCurrentFile();
- if (file->recordbrowseinfo) {
- CBrowse_NewFunction(
- obj, file,
- member_fileoffset.file,
- CPrep_BrowserTokenOffset(&member_fileoffset) + 1,
- CPrep_BrowserFileOffset());
- }
-
- if (lookahead() == ';')
- tk = lex();
- else
- tk = ';';
-}
-
-void CDecl_ExtractClassExportFlags(DeclInfo *declinfo, UInt8 flags) {
- if (flags & CLASS_EFLAGS_INTERNAL)
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_INTERNAL;
- if (flags & CLASS_EFLAGS_IMPORT)
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_IMPORT;
- if (flags & CLASS_EFLAGS_EXPORT)
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_EXPORT;
-}
-
-TypeMemberFunc *CDecl_MakeTypeMemberFunc(TypeFunc *tfunc, TypeClass *tclass, Boolean flag) {
- TypeMemberFunc *method;
-
- method = galloc(sizeof(TypeMemberFunc));
- memclrw(method, sizeof(TypeMemberFunc));
- *TYPE_FUNC(method) = *tfunc;
- method->theclass = tclass;
- method->is_static = flag;
- method->flags |= FUNC_METHOD;
- if (!flag)
- CDecl_AddThisPointerArgument(TYPE_FUNC(method), tclass);
-
- if ((flag || (tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR))) && (tfunc->flags & (FUNC_CONST | FUNC_VOLATILE)))
- CError_Error(CErrorStr384);
-
- return method;
-}
-
-static void CDecl_MakeFunctionVirtual(TypeClass *tclass, Object *func) {
- if (is_pascal_object(func))
- CError_Error(CErrorStr219);
- if (tclass->mode == CLASS_MODE_UNION)
- CError_Error(CErrorStr352, func);
- func->datatype = DVFUNC;
-}
-
-static void CDecl_AddFunctionMember(ClassLayout *decle, TypeClass *tclass, DeclInfo *declinfo, AccessType access, Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) {
- NameSpaceObjectList *list; // r20
- Object *obj; // also r20
- TypeMemberFunc *tfunc; // r19
- Boolean r31;
- Boolean outflag;
-
- if (IS_TYPE_ARRAY(TYPE_FUNC(declinfo->thetype)->functype) || IS_TYPE_FUNC(TYPE_FUNC(declinfo->thetype)->functype)) {
- CError_Error(CErrorStr128);
- TYPE_FUNC(declinfo->thetype)->functype = (Type *) &stsignedint;
- }
-
- if (tclass->sominfo)
- CSOM_CheckFuncType(TYPE_FUNC(declinfo->thetype));
-
- r31 = 0;
- if (declinfo->qual & Q_VIRTUAL) {
- declinfo->qual &= ~Q_VIRTUAL;
- r31 = 1;
- flag1 = 1;
- }
-
- if ((list = CScope_FindName(tclass->nspace, declinfo->name))) {
- if (list->object->otype != OT_TYPETAG) {
- if (list->object->otype != OT_OBJECT || !IS_TYPE_FUNC(OBJECT(list->object)->type))
- CError_Error(CErrorStr133, declinfo->name->name);
- } else {
- list = NULL;
- }
- }
-
- if (!IS_TYPEFUNC_METHOD(TYPE_FUNC(declinfo->thetype))) {
- tfunc = CDecl_MakeTypeMemberFunc(TYPE_FUNC(declinfo->thetype), tclass, flag4);
- declinfo->thetype = (Type *) tfunc;
- } else {
- tfunc = TYPE_METHOD(declinfo->thetype);
- CError_ASSERT(4579, !tclass->sominfo);
- }
-
- CDecl_ExtractClassExportFlags(declinfo, tclass->eflags);
-
- CError_ASSERT(4597, cscope_current == tclass->nspace);
-
- if (list) {
- obj = CDecl_OverloadFunctionObject(list, declinfo, &outflag, flag4 ? OverloadMode1 : OverloadMode2, 0);
- if (!obj)
- return;
- if (outflag)
- tfunc->vtbl_index = ++decle->lex_order_count;
- else
- CError_Error(CErrorStr133, CError_GetObjectName(obj));
- } else {
- tfunc->vtbl_index = ++decle->lex_order_count;
- obj = CParser_NewFunctionObject(declinfo);
- if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype))
- CTemplClass_RegisterObjectDef(TEMPL_CLASS(tclass), OBJ_BASE(obj));
- CScope_AddObject(tclass->nspace, declinfo->name, OBJ_BASE(obj));
- }
-
- obj->access = access;
- CheckDefaultArgs(TYPE_FUNC(obj->type)->args);
-
- if (flag2) {
- tfunc->flags |= FUNC_CONVERSION;
- tclass->flags = tclass->flags | CLASS_IS_CONVERTIBLE;
- }
-
- if (r31) {
- CDecl_MakeFunctionVirtual(tclass, obj);
- decle->has_vtable = 1;
- }
-
- if ((flag1 || r31) && flag3 && (tk == '=')) {
- if ((tk = lex()) == TK_INTCONST) {
- if (!CInt64_IsZero(&tkintconst))
- CError_Error(CErrorStr121);
- tfunc->flags |= FUNC_PURE;
- tclass->flags = tclass->flags | CLASS_ABSTRACT;
- tk = lex();
- } else {
- CError_Error(CErrorStr121);
- }
- }
-
- if (flag3 && ((tk == '{') || (tk == TK_TRY) || ((tk == ':') && CClass_IsConstructor(obj)))) {
- if (declinfo->x49)
- CError_Error(CErrorStr127);
- InlineFunctionObject(obj, NULL);
- }
-
- if (cparamblkptr->browseoptions.recordClasses)
- CBrowse_AddClassMemberFunction(obj, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset());
-}
-
-static Boolean CDecl_IsAccessDeclaration(TypeClass *tclass, AccessType access) {
- SInt32 state;
- Boolean flag;
-
- CPrep_TokenStreamGetState(&state);
- flag = 0;
-
-restart:
- switch (tk) {
- case TK_IDENTIFIER:
- if ((tk = lex()) != ';')
- break;
- case TK_OPERATOR:
- CPrep_TokenStreamSetCurState(&state);
- if (flag) {
- CScope_ParseUsingDeclaration(tclass->nspace, access, 1);
- return 1;
- }
- return 0;
- default:
- CPrep_TokenStreamSetCurState(&state);
- return 0;
- }
-
- switch (tk) {
- case TK_COLON_COLON:
- flag = 1;
- tk = lex();
- goto restart;
- case '<':
- tk = lex();
- while (1) {
- switch (tk) {
- case 0:
- case ';':
- case '{':
- case '}':
- CPrep_TokenStreamSetCurState(&state);
- return 0;
- case '>':
- if ((tk = lex()) == TK_COLON_COLON) {
- flag = 1;
- tk = lex();
- goto restart;
- }
- default:
- tk = lex();
- }
- }
- }
-
- CPrep_TokenStreamSetCurState(&state);
- return 0;
-}
-
-void CDecl_PackDeclInfo(PackedDeclInfo *packed, DeclInfo *declinfo) {
- packed->thetype = declinfo->thetype;
- packed->qual = declinfo->qual;
- packed->nspace = declinfo->nspace;
- packed->name = declinfo->name;
- packed->expltargs = CTemplTool_MakeGlobalTemplArgCopy(declinfo->expltargs);
- packed->storageclass = declinfo->storageclass;
- packed->section = declinfo->section;
- packed->exportflags = declinfo->exportflags;
- packed->has_expltargs = declinfo->has_expltargs;
-}
-
-void CDecl_UnpackDeclInfo(DeclInfo *declinfo, PackedDeclInfo *packed) {
- memclrw(declinfo, sizeof(DeclInfo));
- declinfo->thetype = packed->thetype;
- declinfo->qual = packed->qual;
- declinfo->nspace = packed->nspace;
- declinfo->name = packed->name;
- declinfo->expltargs = packed->expltargs;
- declinfo->storageclass = packed->storageclass;
- declinfo->section = packed->section;
- declinfo->exportflags = packed->exportflags;
- declinfo->has_expltargs = packed->has_expltargs;
-}
-
-void CDecl_AddFriend(TypeClass *tclass, Object *friendfunc, TypeClass *friendclass) {
- ClassFriend *scan;
- ClassFriend *newfriend;
-
- if (friendfunc) {
- for (scan = tclass->friends; scan; scan = scan->next) {
- if (!scan->isclass && scan->u.obj == friendfunc)
- break;
- }
- if (!scan) {
- newfriend = galloc(sizeof(ClassFriend));
- memclrw(newfriend, sizeof(ClassFriend));
- newfriend->next = tclass->friends;
- tclass->friends = newfriend;
- newfriend->u.obj = friendfunc;
- newfriend->isclass = 0;
- }
- }
-
- if (friendclass) {
- for (scan = tclass->friends; scan; scan = scan->next) {
- if (scan->isclass && scan->u.theclass == friendclass)
- break;
- }
- if (!scan) {
- newfriend = galloc(sizeof(ClassFriend));
- memclrw(newfriend, sizeof(ClassFriend));
- newfriend->next = tclass->friends;
- tclass->friends = newfriend;
- newfriend->u.theclass = friendclass;
- newfriend->isclass = 1;
- }
- }
-}
-
-static void CDecl_ParseFriendDecl(TypeClass *tclass) {
- DeclInfo declinfo;
- DeclInfo declinfo_copy;
- Boolean is_templ;
- Boolean r27;
- Boolean pflag;
- CScopeSave save;
- Object *obj;
- NameSpace *nspace;
-
- is_templ = (tclass->flags & CLASS_IS_TEMPL) != 0;
- r27 = (tk == TK_CLASS || tk == TK_STRUCT || tk == TK_UNION);
- memclrw(&declinfo, sizeof(DeclInfo));
-
- declinfo.in_friend_decl = 1;
- CParser_GetDeclSpecs(&declinfo, 1);
- if (declinfo.storageclass) {
- CError_Error(CErrorStr177);
- declinfo.storageclass = 0;
- }
- declinfo.in_friend_decl = 0;
-
- if (tk == ';') {
- if (!r27)
- CError_Error(CErrorStr201);
-
- if (IS_TYPE_CLASS(declinfo.thetype)) {
- if (!(TYPE_CLASS(declinfo.thetype)->flags & CLASS_IS_TEMPL) || CParser_CheckTemplateClassUsage(TEMPL_CLASS(declinfo.thetype), 1)) {
- if (!is_templ)
- CDecl_AddFriend(tclass, NULL, TYPE_CLASS(declinfo.thetype));
- else
- CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo);
- }
- } else {
- if (IS_TYPE_TEMPLATE(declinfo.thetype) && is_templ)
- CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo);
- else
- CError_Error(CErrorStr201);
- }
- } else {
- if (declinfo.x14 || declinfo.x10) {
- CDecl_ParseSpecialMember(&declinfo, 0);
- if (declinfo.name) {
- obj = CDecl_GetFunctionObject(&declinfo, NULL, &pflag, 0);
- if (obj)
- CDecl_AddFriend(tclass, obj, NULL);
- if (tk != ';')
- CError_Error(CErrorStr123);
- else
- tk = lex();
- }
- return;
- } else {
- nspace = CScope_FindGlobalNS(cscope_current);
- declinfo_copy = declinfo;
- while (1) {
- declinfo = declinfo_copy;
- declinfo.x4D = 1;
- declinfo.x51 = 1;
- scandeclarator(&declinfo);
-
- if (IS_TYPE_FUNC(declinfo.thetype)) {
- if (!is_templ) {
- CScope_SetNameSpaceScope(nspace, &save);
- obj = CDecl_GetFunctionObject(&declinfo, NULL, &pflag, 0);
- CScope_RestoreScope(&save);
-
- if (obj) {
- CDecl_AddFriend(tclass, obj, NULL);
- if (!declinfo.nspace && tk == '{') {
- InlineFunctionObject(obj, tclass);
- } else {
- if (!obj->sclass)
- obj->sclass = TK_EXTERN;
- }
- }
- } else {
- CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo);
- }
- } else {
- CError_Error(CErrorStr201);
- }
-
- if (tk != ',')
- break;
- tk = lex();
- }
- }
- }
-
- if (tk == ';')
- tk = lex();
- else
- CError_Error(CErrorStr123);
-}
-
-static ObjMemberVar *CDecl_InstanceDataDeclarator(ClassLayout *decle, TypeClass *tclass, Type *type, UInt32 qual, HashNameNode *name, AccessType access) {
- NameSpaceObjectList *list;
- ObjMemberVar *ivar;
- ObjMemberVar *scan;
-
- if (name && (list = CScope_FindName(tclass->nspace, name))) {
- switch (list->object->otype) {
- case OT_NAMESPACE:
- CError_Error(CErrorStr321);
- return NULL;
- case OT_ENUMCONST:
- case OT_TYPE:
- case OT_OBJECT:
- CError_Error(CErrorStr322);
- return NULL;
- case OT_MEMBERVAR:
- CError_Error(CErrorStr122, name->name);
- return NULL;
- case OT_TYPETAG:
- break;
- default:
- CError_FATAL(4989);
- }
- }
-
- ivar = galloc(sizeof(ObjMemberVar));
- memclrw(ivar, sizeof(ObjMemberVar));
- ivar->otype = OT_MEMBERVAR;
- ivar->access = access;
- ivar->name = name;
- ivar->type = type;
- ivar->qual = qual;
- if (!tclass->sominfo)
- decle->lex_order_count++;
-
- if ((scan = tclass->ivars)) {
- while (scan->next)
- scan = scan->next;
- scan->next = ivar;
- } else {
- tclass->ivars = ivar;
- }
-
- if (name && name != no_name_node) {
- CScope_AddObject(tclass->nspace, name, OBJ_BASE(ivar));
- if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(type))
- CTemplClass_RegisterObjectDef(TEMPL_CLASS(tclass), OBJ_BASE(ivar));
- if (cparamblkptr->browseoptions.recordClasses)
- CBrowse_AddClassMemberVar(ivar, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset());
- }
-
- return ivar;
-}
-
-void CDecl_CheckCtorIntegrity(FuncArg *args, TypeClass *tclass) {
- if (args && args->type == TYPE(tclass)) {
- if (!args->next || args->next->dexpr) {
- CError_Error(CErrorStr239);
- args->type = &stvoid;
- }
- }
-}
-
-static void CDecl_ParseClassMembers(ClassLayout *decle, TypeClass *tclass, short mode) {
- AccessType access;
- Boolean r17;
- BigDeclInfo bde;
- DeclInfo declinfo;
- //Type *newtype
- ObjMemberVar *ivar;
- ObjMemberVar *scanivar;
- Type *tmptype;
- UInt32 r22;
- UInt32 r21;
- UInt8 r20;
- UInt8 r18;
- Boolean r19;
- short t;
-
- r17 = (tclass->flags & CLASS_IS_TEMPL) && TEMPL_CLASS(tclass)->pspec_owner;
- memclrw(&bde, sizeof(BigDeclInfo));
-
- access = (mode == CLASS_MODE_CLASS) ? ACCESSPRIVATE : ACCESSPUBLIC;
- global_access = access;
-
- restart:
- while (tk != '}') {
- CPrep_NewFileOffsetInfo(&member_fileoffset, NULL);
- r21 = 0;
- r22 = 0;
- r20 = 0;
- r18 = 0;
-
- if (tk == TK_TEMPLATE) {
- NameSpace *nspace = cscope_current;
- TemplClass *tmclass;
-
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) {
- tmclass = TEMPL_CLASS(nspace->theclass);
- } else {
- for (; nspace; nspace = nspace->parent) {
- if (!nspace->name && !nspace->theclass && nspace->parent && !nspace->is_templ) {
- CError_Error(CErrorStr347);
- break;
- }
- }
- }
-
- CTempl_Parse(TEMPL_CLASS(tclass), access);
- tk = lex();
- continue;
- }
-
- restart2:
- r19 = 0;
- switch (tk) {
- case TK_UU_DECLSPEC:
- if ((tk = lex()) != '(')
- CError_Error(CErrorStr114);
- memclrw(&declinfo, sizeof(DeclInfo));
- CParser_ParseDeclSpec(&declinfo, 1);
- r21 |= declinfo.qual;
- r20 |= declinfo.exportflags;
- r18 = declinfo.section;
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- tk = lex();
- goto restart2;
- case TK_PRIVATE:
- global_access = access = ACCESSPRIVATE;
- goto check_access;
- case TK_PROTECTED:
- global_access = access = ACCESSPROTECTED;
- goto check_access;
- case TK_PUBLIC:
- global_access = access = ACCESSPUBLIC;
- check_access:
- if (r22 || r20)
- CError_Error(CErrorStr121);
- if ((tk = lex()) != ':')
- CError_Error(CErrorStr170);
- else
- tk = lex();
- goto restart;
- case TK_EXPLICIT:
- CError_QualifierCheck(r22 & Q_EXPLICIT);
- r22 |= Q_EXPLICIT;
- tk = lex();
- goto restart2;
- case TK_INLINE:
- CError_QualifierCheck(r22 & Q_INLINE);
- r22 |= Q_INLINE;
- tk = lex();
- goto restart2;
- case TK_ASM:
- CError_QualifierCheck(r22 & Q_ASM);
- r22 |= Q_ASM;
- tk = lex();
- goto restart2;
- case TK_VIRTUAL:
- CError_QualifierCheck(r22 & Q_VIRTUAL);
- r22 |= Q_VIRTUAL;
- tk = lex();
- goto restart2;
- case TK_IDENTIFIER:
- while (1) {
- if (tkidentifier == tclass->classname) {
- t = lookahead();
- tkidentifier = tclass->classname;
- r19 = 1;
- if (copts.cpp_extensions && t == TK_COLON_COLON) {
- lex();
- tk = lex();
- if (tk == TK_IDENTIFIER)
- continue;
- if (tk == '~')
- goto restart2;
- CError_Error(CErrorStr107);
- }
-
- if (t == '(') {
- redo_thing:
- CError_QualifierCheck(r22 & ~(Q_EXPLICIT | Q_INLINE | Q_ASM));
- memclrw(&bde.declinfo2, sizeof(DeclInfo));
- if (tclass->sominfo)
- bde.declinfo2.thetype = &stvoid;
- else
- bde.declinfo2.thetype = TYPE(&void_ptr);
-
- bde.declinfo2.qual = r22;
- bde.declinfo2.exportflags = r20;
- bde.declinfo2.section = r18;
- bde.declinfo2.x4B = 1;
- scandeclarator(&bde.declinfo2);
- if (IS_TYPE_FUNC(bde.declinfo2.thetype)) {
- if (r17)
- bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual);
- if (tclass->sominfo) {
- if (TYPE_FUNC(bde.declinfo2.thetype)->args)
- CError_Error(CErrorStr272);
- bde.declinfo2.qual |= Q_VIRTUAL;
- } else {
- CDecl_CheckCtorIntegrity(TYPE_FUNC(bde.declinfo2.thetype)->args, tclass);
- if (tclass->flags & CLASS_HAS_VBASES)
- CDecl_AddArgument(TYPE_FUNC(bde.declinfo2.thetype), TYPE(&stsignedshort));
- bde.declinfo2.qual &= ~Q_VIRTUAL;
- }
- TYPE_FUNC(bde.declinfo2.thetype)->flags |= FUNC_IS_CTOR;
- bde.declinfo2.name = constructor_name_node;
- bde.declinfo2.qual |= r21;
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 0, 0, 1, 0);
- } else {
- CError_Error(CErrorStr241);
- }
- if (tk == ';')
- tk = lex();
- else
- CError_Error(CErrorStr123);
- goto restart;
- }
- }
- // 6F8D8
- if (!r22 && CDecl_IsAccessDeclaration(tclass, access)) {
- tk = lex();
- goto restart;
- }
- break;
- }
- break;
- case TK_USING:
- CError_QualifierCheck(r22);
- tk = lex();
- CScope_ParseUsingDeclaration(tclass->nspace, access, 0);
- tk = lex();
- goto restart;
- case '~':
- if ((tk = lex()) != TK_IDENTIFIER || tkidentifier != tclass->classname) {
- CError_Error(CErrorStr241);
- goto restart;
- }
- CError_QualifierCheck(r22 & ~(Q_VIRTUAL | Q_INLINE | Q_ASM));
- if (tclass->flags & CLASS_IS_TEMPL_ANY) {
- t = lookahead();
- tkidentifier = tclass->classname;
- if (t == '<') {
- memclrw(&bde.declinfo, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&bde.declinfo, 0);
- if (tk != '(' || bde.declinfo.thetype != TYPE(tclass) || bde.declinfo.nspace) {
- CError_Error(CErrorStr241);
- goto restart;
- }
- CPrep_UnLex();
- tk = TK_IDENTIFIER;
- tkidentifier = tclass->classname;
- }
- }
- memclrw(&bde.declinfo2, sizeof(DeclInfo));
- bde.declinfo2.qual = r22;
- bde.declinfo2.exportflags = r20;
- bde.declinfo2.section = r18;
- if (tclass->sominfo)
- bde.declinfo2.thetype = &stvoid;
- else
- bde.declinfo2.thetype = TYPE(&void_ptr);
- scandeclarator(&bde.declinfo2);
- if (IS_TYPE_FUNC(bde.declinfo2.thetype) && !TYPE_FUNC(bde.declinfo2.thetype)->args) {
- if (!CScope_FindName(tclass->nspace, destructor_name_node)) {
- if (tclass->sominfo)
- bde.declinfo2.qual |= Q_VIRTUAL;
- else
- CDecl_AddArgument(TYPE_FUNC(bde.declinfo2.thetype), TYPE(&stsignedshort));
- bde.declinfo2.name = destructor_name_node;
- TYPE_FUNC(bde.declinfo2.thetype)->flags |= FUNC_IS_DTOR;
- bde.declinfo2.qual |= r21;
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 0, 1, 0);
- } else {
- CError_Error(CErrorStr133, CError_GetFunctionName(tclass->nspace, destructor_name_node, NULL));
- }
- } else {
- CError_Error(CErrorStr146);
- }
- if (tk == ';')
- tk = lex();
- else
- CError_Error(CErrorStr123);
- goto restart;
- case TK_OPERATOR:
- if (CMangler_OperatorName(lookahead())) {
- memclrw(&bde.declinfo, sizeof(DeclInfo));
- bde.declinfo.thetype = TYPE(&stsignedint);
- goto after_various_things;
- } else {
- tk = lex();
- CError_QualifierCheck(r22 & ~(Q_VIRTUAL | Q_INLINE | Q_ASM));
- memclrw(&bde.declinfo2, sizeof(DeclInfo));
- bde.declinfo2.qual = r22;
- bde.declinfo2.exportflags = r20;
- bde.declinfo2.section = r18;
- conversion_type_name(&bde.declinfo2);
- bde.declinfo2.qual |= r21;
- tmptype = bde.declinfo2.thetype;
- CDecl_NewConvFuncType(&bde.declinfo2);
- if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(tmptype))
- bde.declinfo2.name = CParser_GetUniqueName();
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 1, 1, 0);
- if (tk == ';')
- tk = lex();
- else
- CError_Error(CErrorStr123);
- goto restart;
- }
- case TK_FRIEND:
- tk = lex();
- CDecl_ParseFriendDecl(tclass);
- goto restart;
- }
-
- CError_QualifierCheck(r22 & Q_EXPLICIT);
- global_access = access;
- memclrw(&bde.declinfo, sizeof(DeclInfo));
- bde.declinfo.qual = r22;
- bde.declinfo.exportflags = r20;
- bde.declinfo.section = r18;
- CParser_GetDeclSpecs(&bde.declinfo, 0);
-
- if (r19 && tk == '(' && (tclass->flags & CLASS_IS_TEMPL_ANY) && bde.declinfo.thetype == TYPE(tclass) && !bde.declinfo.nspace) {
- CPrep_UnLex();
- tk = TK_IDENTIFIER;
- tkidentifier = tclass->classname;
- r22 = bde.declinfo.qual;
- goto redo_thing;
- }
-
- after_various_things:
- switch (bde.declinfo.storageclass) {
- case 0:
- case TK_STATIC:
- case TK_TYPEDEF:
- case TK_MUTABLE:
- break;
- default:
- CError_Error(CErrorStr177);
- bde.declinfo.storageclass = 0;
- }
-
- if (tk != ';') {
- while (1) {
- CDecl_ScanStructDeclarator(&bde);
- if (r17)
- bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual);
- if (bde.declinfo2.nspace)
- CError_Error(CErrorStr200);
- if (bde.declinfo2.operator_token) {
- if (bde.declinfo.storageclass == TK_MUTABLE)
- CError_QualifierCheck(Q_MUTABLE);
- r19 = 0;
- switch (bde.declinfo2.operator_token) {
- case TK_NEW:
- case TK_NEW_ARRAY:
- CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL);
- r19 = 1;
- break;
- case TK_DELETE:
- case TK_DELETE_ARRAY:
- CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL);
- r19 = 1;
- break;
- default:
- if (bde.declinfo2.storageclass == TK_STATIC)
- CError_Error(CErrorStr193);
- if (tclass->sominfo)
- CError_Error(CErrorStr193);
- }
-
- bde.declinfo2.storageclass = 0;
- if (IS_TYPE_FUNC(bde.declinfo2.thetype)) {
- bde.declinfo2.qual |= r21;
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, r19 == 0, 0, 1, r19);
- CDecl_CheckOperatorType(&bde.declinfo2, 1);
- if (tclass->sominfo)
- CSOM_FixNewDeleteFunctype(TYPE_FUNC(bde.declinfo2.thetype));
- } else {
- CError_Error(CErrorStr121);
- }
- } else if (bde.xCD) {
- if (bde.declinfo2.name == constructor_name_node || bde.declinfo2.name == destructor_name_node)
- CError_Error(CErrorStr241);
- switch (bde.declinfo2.storageclass) {
- case TK_TYPEDEF:
- CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL);
- CDecl_TypedefDeclarator(&bde.declinfo2);
- break;
- case TK_STATIC:
- CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL);
- if (tclass->sominfo)
- CError_Error(CErrorStr271);
- if (IS_TYPE_FUNC(bde.declinfo2.thetype)) {
- bde.declinfo2.qual |= r21;
- bde.declinfo2.storageclass = 0;
- if (bde.declinfo2.name == tclass->classname)
- CError_Error(CErrorStr241);
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 0, 0, 1, 1);
- } else {
- CDecl_ExtractClassExportFlags(&bde.declinfo2, tclass->eflags);
- bde.declinfo2.storageclass = 0;
- CDecl_DataDeclarator(&bde.declinfo2, access, 1);
- }
- break;
- case 0:
- case TK_MUTABLE:
- if (IS_TYPE_FUNC(bde.declinfo2.thetype)) {
- if (bde.declinfo2.name == tclass->classname)
- CError_Error(CErrorStr241);
- if (bde.declinfo.storageclass == TK_MUTABLE)
- CError_QualifierCheck(Q_MUTABLE);
- bde.declinfo2.qual |= r21;
- CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 0, 1, 0);
- } else {
- CDecl_CompleteType(bde.declinfo2.thetype);
- CanCreateObject(bde.declinfo2.thetype);
- CError_QualifierCheck(bde.declinfo2.qual & (Q_VIRTUAL | Q_INLINE));
- if (bde.declinfo2.storageclass == TK_MUTABLE)
- bde.declinfo2.qual |= Q_MUTABLE;
- CDecl_InstanceDataDeclarator(decle, tclass, bde.declinfo2.thetype, bde.declinfo2.qual, bde.declinfo2.name, access);
- }
- break;
- default:
- CError_Error(CErrorStr177);
- }
- }
-
- // this should be 70058
- if (tk != ',')
- break; // goes to 70148
- tk = lex();
- }
- } else if (CParser_IsAnonymousUnion(&bde.declinfo, 1)) {
- if ((ivar = CDecl_InstanceDataDeclarator(decle, tclass, bde.declinfo.thetype, 0, NULL, access)))
- ivar->anonunion = 1;
- for (scanivar = TYPE_CLASS(bde.declinfo.thetype)->ivars; scanivar; scanivar = scanivar->next) {
- tmptype = scanivar->type;
- if (IS_TYPE_BITFIELD(tmptype) && copts.reverse_bitfields) {
- TypeBitfield *newtype = galloc(sizeof(TypeBitfield));
- *newtype = *TYPE_BITFIELD(tmptype);
- CABI_ReverseBitField(newtype);
- tmptype = TYPE(newtype);
- }
- if ((ivar = CDecl_InstanceDataDeclarator(decle, tclass, tmptype, scanivar->qual, scanivar->name, access)))
- ivar->offset = scanivar->offset | 0x80000000;
- }
- }
-
- // this should be 70148 i think
- if (tk != ';') {
- CError_Error(CErrorStr123);
- return;
- }
- CPrep_TokenStreamFlush();
- tk = lex();
- }
-}
-
-static VClassList *AddVBaseToList(TypeClass *tclass, TypeClass *baseclass) {
- VClassList *scan;
- VClassList *vbase;
-
- for (scan = tclass->vbases; scan; scan = scan->next) {
- if (scan->base == baseclass)
- return NULL;
- }
-
- vbase = galloc(sizeof(VClassList));
- memclrw(vbase, sizeof(VClassList));
- vbase->base = baseclass;
-
- if ((scan = tclass->vbases)) {
- while (scan->next)
- scan = scan->next;
- scan->next = vbase;
- } else {
- tclass->vbases = vbase;
- }
-
- return vbase;
-}
-
-void CDecl_MakeVBaseList(TypeClass *tclass) {
- ClassList *base;
- VClassList *vbase;
- VClassList *new_vbase;
- SInt32 offset;
-
- if (copts.vbase_ctor_offset)
- tclass->flags = tclass->flags | CLASS_FLAGS_8000;
-
- for (base = tclass->bases, offset = tclass->size; base; base = base->next) {
- for (vbase = base->base->vbases; vbase; vbase = vbase->next) {
- if ((new_vbase = AddVBaseToList(tclass, vbase->base))) {
- new_vbase->offset = offset + CMach_MemberAlignValue(TYPE(vbase->base), offset);
- offset = new_vbase->offset + vbase->base->size;
- }
- }
-
- if (base->is_virtual && (new_vbase = AddVBaseToList(tclass, base->base))) {
- new_vbase->offset = offset + CMach_MemberAlignValue(TYPE(base->base), offset);
- offset = new_vbase->offset + base->base->size;
- }
- }
-}
-
-Boolean CDecl_CheckNewBase(TypeClass *tclass, TypeClass *baseclass, Boolean is_virtual) {
- ClassList *scan;
-
- if (tclass == baseclass) {
- CError_Error(CErrorStr131);
- return 0;
- }
-
- if (!(baseclass->flags & CLASS_COMPLETED)) {
- CError_Error(CErrorStr136, baseclass, 0);
- return 0;
- }
-
- if (baseclass->flags & CLASS_SINGLE_OBJECT) {
- if (is_virtual || tclass->bases) {
- CError_Error(CErrorStr191);
- return 0;
- }
- tclass->flags = tclass->flags | CLASS_SINGLE_OBJECT;
- }
-
- if (baseclass->flags & CLASS_HANDLEOBJECT) {
- if (is_virtual || tclass->bases) {
- CError_Error(CErrorStr191);
- return 0;
- }
- tclass->flags = tclass->flags | CLASS_HANDLEOBJECT;
- }
-
- if (baseclass->sominfo) {
- if (!is_virtual)
- CError_Error(CErrorStr268);
- CSOM_MakeSOMClass(tclass);
- } else if (tclass->sominfo) {
- CError_Error(CErrorStr267);
- }
-
- if (tclass->bases && (tclass->flags & CLASS_SINGLE_OBJECT) && (tclass->flags & CLASS_SINGLE_OBJECT)) {
- CError_Error(CErrorStr131);
- return 0;
- }
-
- if (copts.ecplusplus && (is_virtual || tclass->bases)) {
- CError_Error(CErrorStr339);
- return 0;
- }
-
- for (scan = tclass->bases; scan; scan = scan->next) {
- if (scan->base == baseclass) {
- CError_Error(CErrorStr131);
- return 0;
- }
- }
-
- if (baseclass->flags & CLASS_COM_OBJECT)
- tclass->flags = tclass->flags | CLASS_COM_OBJECT;
- if (baseclass->flags & CLASS_IS_CONVERTIBLE)
- tclass->flags = tclass->flags | CLASS_IS_CONVERTIBLE;
- if (baseclass->flags & CLASS_HAS_VBASES)
- tclass->flags = tclass->flags | CLASS_HAS_VBASES;
-
- if (is_virtual)
- tclass->flags = tclass->flags | CLASS_HAS_VBASES;
-
- return 1;
-}
-
-static void CDecl_ParseBaseClassList(TypeClass *tclass, short mode, Boolean is_templ) {
- Boolean is_virtual;
- AccessType access;
- NameResult pr;
- ObjType *inherited_type;
- ClassList *base;
- ClassList *scan;
- TypeClass *baseclass;
-
- do {
- if (mode == CLASS_MODE_CLASS)
- access = ACCESSPRIVATE;
- else
- access = ACCESSPUBLIC;
-
- is_virtual = 0;
- if ((tk = lex()) == TK_VIRTUAL) {
- tk = lex();
- is_virtual = 1;
- }
-
- switch (tk) {
- case TK_PRIVATE:
- access = ACCESSPRIVATE;
- tk = lex();
- break;
- case TK_PUBLIC:
- access = ACCESSPUBLIC;
- tk = lex();
- break;
- case TK_PROTECTED:
- if (!copts.ARMconform) {
- access = ACCESSPROTECTED;
- tk = lex();
- }
- break;
- }
-
- if (tk == TK_VIRTUAL) {
- if (is_virtual)
- CError_Error(CErrorStr121);
- is_virtual = 1;
- tk = lex();
- }
-
- if (CScope_ParseDeclName(&pr)) {
- if (!pr.type) {
- if (!pr.name_4) {
- CError_Error(CErrorStr121);
- } else if (tk == TK_IDENTIFIER && pr.name_4 == tkidentifier) {
- goto special_parsing;
- }
- CError_Error(CErrorStr140, tkidentifier->name);
- continue;
- }
-
- CDecl_CompleteType(pr.type);
- if (is_templ && CTemplTool_IsTemplateArgumentDependentType(pr.type)) {
- if (!IS_TYPE_CLASS(pr.type) || !(TYPE_CLASS(pr.type)->flags & CLASS_IS_TEMPL) ||
- CParser_CheckTemplateClassUsage(TEMPL_CLASS(pr.type), 1)) {
- CTemplClass_RegisterBaseClass(TEMPL_CLASS(tclass), pr.type, access, is_virtual);
- if (is_virtual)
- tclass->flags = tclass->flags | CLASS_HAS_VBASES;
- }
- continue;
- }
-
- if (!IS_TYPE_CLASS(pr.type) || (TYPE_CLASS(pr.type)->flags & CLASS_IS_TEMPL)) {
- CError_Error(CErrorStr131);
- continue;
- }
- baseclass = TYPE_CLASS(pr.type);
- } else {
- special_parsing:
- if (!strcmp(tkidentifier->name, "HandleObject")) {
- if (tclass->bases)
- CError_Error(CErrorStr191);
- tclass->flags |= CLASS_SINGLE_OBJECT | CLASS_HANDLEOBJECT;
- tk = lex();
- break;
- }
- if (!strcmp(tkidentifier->name, "SingleObject") || !strcmp(tkidentifier->name, "SingleInheritance")) {
- if (tclass->bases)
- CError_Error(CErrorStr191);
- tclass->flags = tclass->flags | CLASS_SINGLE_OBJECT;
- tk = lex();
- break;
- }
- if (!strcmp(tkidentifier->name, "__comobject")) {
- tclass->flags = tclass->flags | CLASS_COM_OBJECT;
- tk = lex();
- break;
- }
- if (!strcmp(tkidentifier->name, "__somobject")) {
- if (!is_virtual)
- CError_Error(CErrorStr268);
- CSOM_MakeSOMClass(tclass);
- tk = lex();
- break;
- }
- if (!strcmp(tkidentifier->name, "__javaobject")) {
- tk = lex();
- tclass->action = CLASS_ACTION_3;
- break;
- }
-
- CError_Error(CErrorStr140, tkidentifier->name);
- continue;
- }
-
- if (CDecl_CheckNewBase(tclass, baseclass, is_virtual)) {
- base = galloc(sizeof(ClassList));
- memclrw(base, sizeof(ClassList));
- base->base = baseclass;
- base->access = access;
- base->is_virtual = is_virtual;
- if ((scan = tclass->bases)) {
- while (scan->next)
- scan = scan->next;
- scan->next = base;
- } else {
- tclass->bases = base;
- }
- }
- } while ((tk = lex()) == ',');
-
- if (tclass->flags & CLASS_HAS_VBASES)
- CDecl_MakeVBaseList(tclass);
-
- if (copts.def_inherited && tclass->bases && !tclass->bases->next) {
- inherited_type = galloc(sizeof(ObjType));
- memclrw(inherited_type, sizeof(ObjType));
- inherited_type->otype = OT_TYPE;
- inherited_type->access = ACCESSPUBLIC;
- inherited_type->type = TYPE(tclass->bases->base);
- CScope_AddObject(tclass->nspace, GetHashNameNodeExport("inherited"), OBJ_BASE(inherited_type));
- }
-}
-
-static AccessType getaccesstype(AccessType a, AccessType b, AccessType c) {
- if (a == ACCESSNONE || b == ACCESSNONE || b == ACCESSPRIVATE)
- return ACCESSNONE;
-
- if (c == ACCESSPUBLIC && b != ACCESSPUBLIC)
- return ACCESSNONE;
-
- return ACCESSPUBLIC;
-}
-
-static TypeMemberFunc *CDecl_MakeDefaultCtorType(TypeClass *tclass) {
- TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc));
- memclrw(tmeth, sizeof(TypeMemberFunc));
- tmeth->type = TYPEFUNC;
- tmeth->functype = TYPE(&void_ptr);
- tmeth->flags = FUNC_IS_CTOR | FUNC_AUTO_GENERATED | FUNC_METHOD;
- tmeth->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1);
-
- if (tclass->flags & CLASS_HAS_VBASES)
- CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort));
-
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass);
- return tmeth;
-}
-
-static void CDecl_AddDefArgConstructor(TypeClass *tclass) {
- // empty
-}
-
-static void CDecl_AddMemberFunctionObject(TypeClass *tclass, HashNameNode *name, TypeMemberFunc *tmeth, AccessType access) {
- Object *obj = CParser_NewCompilerDefFunctionObject();
- obj->name = name;
- obj->type = TYPE(tmeth);
- obj->qual = Q_MANGLE_NAME;
- obj->access = access;
- obj->nspace = tclass->nspace;
- obj->qual = obj->qual | Q_INLINE;
- CScope_AddObject(tclass->nspace, obj->name, OBJ_BASE(obj));
-}
-
-static void CDecl_AddDefaultConstructor(ClassLayout *decle, TypeClass *tclass) {
- ClassList *base;
- ObjMemberVar *ivar;
- Object *obj;
- Boolean has_ctor;
-
- if (CClass_Constructor(tclass)) {
- CDecl_AddDefArgConstructor(tclass);
- return;
- }
-
- has_ctor = 0;
-
- if (tclass->flags & CLASS_HAS_VBASES)
- has_ctor = 1;
- if (decle->has_vtable)
- has_ctor = 1;
-
- for (base = tclass->bases; base; base = base->next) {
- if (CClass_Constructor(base->base))
- has_ctor = 1;
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- Type *type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type)))
- has_ctor = 1;
- }
-
- if (has_ctor) {
- CDecl_AddMemberFunctionObject(
- tclass,
- constructor_name_node,
- CDecl_MakeDefaultCtorType(tclass),
- ACCESSPUBLIC
- );
- }
-}
-
-static TypeMemberFunc *CDecl_MakeCopyCtorType(TypeClass *tclass, Boolean is_const) {
- FuncArg *arg;
- TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc));
- memclrw(tmeth, sizeof(TypeMemberFunc));
- tmeth->type = TYPEFUNC;
- tmeth->functype = TYPE(&void_ptr);
- tmeth->flags = FUNC_IS_CTOR | FUNC_AUTO_GENERATED | FUNC_METHOD;
- tmeth->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1);
-
- arg = CParser_NewFuncArg();
- if (is_const)
- arg->qual = Q_CONST;
- arg->type = CDecl_NewRefPointerType(TYPE(tclass));
- tmeth->args = arg;
-
- if (tclass->flags & CLASS_HAS_VBASES)
- CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort));
-
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass);
- return tmeth;
-}
-
-static void CDecl_AddDefaultCopyConstructor(ClassLayout *decle, TypeClass *tclass) {
- ClassList *base;
- ObjMemberVar *ivar;
- Object *obj;
- AccessType access;
- Boolean has_copyctor;
- Boolean is_const;
- FuncArg *arg;
-
- if (CClass_CopyConstructor(tclass))
- return;
-
- access = ACCESSPUBLIC;
- is_const = 1;
- has_copyctor = 0;
-
- if (CClass_Constructor(tclass))
- has_copyctor = 1;
- if ((tclass->flags & CLASS_HAS_VBASES) || decle->has_vtable)
- has_copyctor = 1;
-
- for (base = tclass->bases; base; base = base->next) {
- if ((obj = CClass_CopyConstructor(base->base))) {
- has_copyctor = 1;
- access = getaccesstype(access, obj->access, ACCESSPRIVATE);
- arg = TYPE_FUNC(obj->type)->args->next;
- if (base->base->flags & CLASS_HAS_VBASES)
- arg = arg->next;
- if (!(arg->qual & Q_CONST))
- is_const = 0;
- }
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- Type *type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type) && (obj = CClass_CopyConstructor(TYPE_CLASS(type)))) {
- has_copyctor = 1;
- access = getaccesstype(access, obj->access, ACCESSPUBLIC);
- arg = TYPE_FUNC(obj->type)->args->next;
- if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES)
- arg = arg->next;
- if (!(arg->qual & Q_CONST))
- is_const = 0;
- }
- }
-
- if (has_copyctor) {
- CDecl_AddMemberFunctionObject(
- tclass,
- constructor_name_node,
- CDecl_MakeCopyCtorType(tclass, is_const),
- access
- );
- }
-}
-
-static TypeMemberFunc *CDecl_MakeAssignmentOperatorType(TypeClass *tclass, Boolean is_const) {
- FuncArg *arg;
- TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc));
- memclrw(tmeth, sizeof(TypeMemberFunc));
- tmeth->type = TYPEFUNC;
- tmeth->functype = CDecl_NewRefPointerType(TYPE(tclass));
- tmeth->flags = FUNC_AUTO_GENERATED | FUNC_METHOD;
- tmeth->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1);
-
- arg = CParser_NewFuncArg();
- if (is_const)
- arg->qual = Q_CONST;
- arg->type = CDecl_NewRefPointerType(TYPE(tclass));
- tmeth->args = arg;
-
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass);
- return tmeth;
-}
-
-static void CDecl_AddDefaultAssignmentOperator(ClassLayout *decle, TypeClass *tclass) {
- ClassList *base;
- ObjMemberVar *ivar;
- Object *obj;
- AccessType access;
- Boolean is_const;
- Boolean has_ass;
- DeclInfo declinfo;
-
- is_const = 1;
- has_ass = 0;
- access = ACCESSPUBLIC;
-
- if (!CClass_AssignmentOperator(tclass)) {
- if (!copts.old_argmatch)
- has_ass = 1;
-
- if ((tclass->flags & CLASS_HAS_VBASES) || decle->has_vtable || CClass_MemberObject(tclass, asop_name_node))
- has_ass = 1;
-
- for (base = tclass->bases; base; base = base->next) {
- if ((obj = CClass_AssignmentOperator(base->base))) {
- has_ass = 1;
- access = getaccesstype(access, obj->access, ACCESSPRIVATE);
- if (!(TYPE_FUNC(obj->type)->args->next->qual & Q_CONST))
- is_const = 0;
- }
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- Type *type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type) && (obj = CClass_AssignmentOperator(TYPE_CLASS(type)))) {
- has_ass = 1;
- access = getaccesstype(access, obj->access, ACCESSPUBLIC);
- if (!(TYPE_FUNC(obj->type)->args->next->qual & Q_CONST))
- is_const = 0;
- }
- }
- }
-
- if (has_ass) {
- memclrw(&declinfo, sizeof(DeclInfo));
- declinfo.qual |= Q_INLINE;
- declinfo.thetype = (Type *) CDecl_MakeAssignmentOperatorType(tclass, is_const);
- declinfo.name = asop_name_node;
- CDecl_AddFunctionMember(decle, tclass, &declinfo, access, 1, 0, 0, 0);
- }
-}
-
-TypeMemberFunc *CDecl_MakeDefaultDtorType(TypeClass *tclass, Boolean is_virtual) {
- TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc));
- memclrw(tmeth, sizeof(TypeMemberFunc));
- tmeth->type = TYPEFUNC;
- tmeth->functype = (Type *) &void_ptr;
- tmeth->flags = FUNC_IS_DTOR | FUNC_AUTO_GENERATED | FUNC_METHOD;
- tmeth->theclass = tclass;
- CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1);
- if (is_virtual)
- CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort));
- CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass);
- return tmeth;
-}
-
-static void CDecl_AddDefaultDestructor(ClassLayout *decle, TypeClass *tclass) {
- ClassList *base;
- ObjMemberVar *ivar;
- Object *obj;
- AccessType access;
- Boolean has_dtor;
- Boolean is_virtual;
- DeclInfo declinfo;
-
- if (CClass_Destructor(tclass))
- return;
-
- has_dtor = 0;
- is_virtual = 0;
- access = ACCESSPUBLIC;
-
- for (base = tclass->bases; base; base = base->next) {
- if ((obj = CClass_Destructor(base->base))) {
- has_dtor = 1;
- if (obj->datatype == DVFUNC)
- is_virtual = 1;
- access = getaccesstype(access, obj->access, ACCESSPRIVATE);
- }
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- Type *type = ivar->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type) && (obj = CClass_Destructor(TYPE_CLASS(type)))) {
- has_dtor = 1;
- access = getaccesstype(access, obj->access, ACCESSPUBLIC);
- }
- }
-
- if (has_dtor) {
- memclrw(&declinfo, sizeof(DeclInfo));
- declinfo.qual |= Q_INLINE;
- if (is_virtual)
- declinfo.qual |= Q_VIRTUAL;
-
- declinfo.thetype = (Type *) CDecl_MakeDefaultDtorType(tclass, 1);
- declinfo.name = destructor_name_node;
- CDecl_AddFunctionMember(decle, tclass, &declinfo, access, 1, 0, 0, 0);
- }
-}
-
-static void CDecl_SetupClassLayout(ClassLayout *decle, TypeClass *tclass, ObjBase **objbuf) {
- SInt32 index;
- SInt32 i;
- Object *obj;
- CScopeObjectIterator iter;
- ObjMemberVar *ivar;
- SInt32 bufsize;
-
- if (decle->lex_order_count > 32) {
- bufsize = decle->lex_order_count * sizeof(ObjBase *);
- objbuf = lalloc(bufsize);
- } else {
- bufsize = 32 * sizeof(ObjBase *);
- }
- memclrw(objbuf, bufsize);
- decle->objlist = objbuf;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- index = 0;
- while (1) {
- obj = OBJECT(CScope_NextObjectIteratorObject(&iter));
- if (!obj) break;
-
- if (!IS_TYPE_FUNC(obj->type))
- continue;
- if (!IS_TYPEFUNC_METHOD(TYPE_FUNC(obj->type)))
- continue;
- if (obj->datatype == DALIAS)
- continue;
-
- i = TYPE_METHOD(obj->type)->vtbl_index;
- if (i > 0) {
- CError_ASSERT(6363, (i - 1) < decle->lex_order_count && !objbuf[(int) (i - 1)]);
- objbuf[(int) (i - 1)] = OBJ_BASE(obj);
- index++;
- if (obj->datatype != DVFUNC && !TYPE_METHOD(obj->type)->is_static && CClass_OverridesBaseMember(tclass, obj->name, obj))
- CDecl_MakeFunctionVirtual(tclass, obj);
-
- if (obj->datatype == DVFUNC) {
- decle->has_vtable = 1;
- if (!tclass->vtable) {
- CABI_AddVTable(tclass);
- decle->xA = i - 1;
- } else {
- if ((i - 1) < decle->xA)
- decle->xA = i - 1;
- }
- } else if (TYPE_FUNC(obj->type)->flags & FUNC_PURE) {
- CError_Error(CErrorStr351, obj);
- TYPE_FUNC(obj->type)->flags &= ~FUNC_PURE;
- }
- } else {
- CError_ASSERT(6412, i == 0);
- }
-
- if (!tclass->sominfo)
- TYPE_METHOD(obj->type)->vtbl_index = 0;
- }
-
- if (!tclass->action) {
- for (i = 0; i < decle->lex_order_count; i++) {
- Object *obj2 = OBJECT(objbuf[i]);
- if (obj2 && obj2->datatype == DVFUNC && !(obj2->qual & Q_INLINE) && !(TYPE_FUNC(obj2->type)->flags & FUNC_PURE)) {
- tclass->action = CLASS_ACTION_1;
- TYPE_FUNC(obj2->type)->flags |= FUNC_FLAGS_4;
- break;
- }
- }
- }
-
- if (!tclass->sominfo) {
- for (i = 0, ivar = tclass->ivars; i < decle->lex_order_count; i++) {
- if (!objbuf[i]) {
- CError_ASSERT(6449, ivar);
- objbuf[i] = OBJ_BASE(ivar);
- ivar = ivar->next;
- index++;
- }
- }
- CError_ASSERT(6455, ivar == NULL);
- }
-
- CError_ASSERT(6458, index == decle->lex_order_count);
-}
-
-void CDecl_CompleteClass(ClassLayout *decle, TypeClass *tclass) {
- ClassList *base;
- ObjBase *buf[32];
-
- for (base = tclass->bases; base; base = base->next) {
- if (base->base->vtable)
- decle->has_vtable = 1;
- }
-
- if (!tclass->sominfo) {
- CDecl_AddDefaultDestructor(decle, tclass);
- CDecl_AddDefaultAssignmentOperator(decle, tclass);
- CDecl_AddDefaultConstructor(decle, tclass);
- CDecl_AddDefaultCopyConstructor(decle, tclass);
- }
-
- CDecl_SetupClassLayout(decle, tclass, buf);
- if (decle->has_vtable)
- CClass_CheckOverrides(tclass);
- CABI_LayoutClass(decle, tclass);
- if (tclass->sominfo)
- CSOM_ClassComplete(tclass);
-
- if ((tclass->flags & CLASS_IS_TEMPL_INST) && !TEMPL_CLASS_INST(tclass)->is_specialized)
- tclass->action = CLASS_ACTION_0;
-
- if (!tclass->action)
- CClass_MakeStaticActionClass(tclass);
- CClass_ClassDefaultFuncAction(tclass);
-}
-
-TypeClass *CDecl_DefineClass(NameSpace *nspace, HashNameNode *name, TypeClass *tclass, short mode, Boolean flag2, Boolean flag3) {
- NameSpace *mynspace;
- ObjType *objtype;
-
- if (!tclass && nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) {
- CError_ASSERT(6556, !flag2);
- return TYPE_CLASS(CTemplClass_DefineNestedClass(TEMPL_CLASS(nspace->theclass), name, mode));
- }
-
- mynspace = CScope_NewListNameSpace(name, 1);
- if (!tclass) {
- tclass = galloc(sizeof(TypeClass));
- memclrw(tclass, sizeof(TypeClass));
- }
-
- tclass->type = TYPECLASS;
- tclass->align = 1;
- tclass->mode = mode;
- tclass->action = CLASS_ACTION_0;
- if (name) {
- tclass->classname = name;
- if (flag3) {
- if (flag2) {
- objtype = galloc(sizeof(ObjType));
- memclrw(objtype, sizeof(ObjType));
- objtype->otype = OT_TYPE;
- objtype->access = ACCESSPUBLIC;
- objtype->type = (Type *) tclass;
- CScope_AddObject(nspace, name, OBJ_BASE(objtype));
- } else {
- CScope_DefineTypeTag(nspace, name, (Type *) tclass);
- }
- }
- CScope_DefineTypeTag(mynspace, name, (Type *) tclass);
-
- if (cscope_currentfunc)
- mynspace->name = CParser_AppendUniqueNameFile(name->name);
-
- if (copts.direct_to_som && nspace == cscope_root && !strcmp(name->name, "SOMObject"))
- CSOM_MakeSOMClass(tclass);
- } else {
- tclass->classname = CParser_AppendUniqueNameFile("@class");
- mynspace->name = tclass->classname;
- }
-
- tclass->nspace = mynspace;
- mynspace->theclass = tclass;
- mynspace->parent = nspace;
- if (!nspace->is_global)
- CParser_RegisterNonGlobalClass(tclass);
-
- return tclass;
-}
-
-void CDecl_ParseClassDeclSpec(UInt8 *declspec) {
- DeclInfo declinfo;
-
- if ((tk = lex()) == '(') {
- memclrw(&declinfo, sizeof(DeclInfo));
- CParser_ParseDeclSpec(&declinfo, 1);
- if (declinfo.exportflags & EXPORT_FLAGS_INTERNAL)
- *declspec = *declspec | CLASS_EFLAGS_INTERNAL;
- if (declinfo.exportflags & EXPORT_FLAGS_IMPORT)
- *declspec = *declspec | CLASS_EFLAGS_IMPORT;
- if (declinfo.exportflags & EXPORT_FLAGS_EXPORT)
- *declspec = *declspec | CLASS_EFLAGS_EXPORT;
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- CError_Error(CErrorStr114);
- }
-}
-
-static TemplClass *CDecl_SpecializeTemplateClass(TemplClass *tmclass) {
- tmclass->theclass.nspace->names = 0;
- tmclass->theclass.nspace->data.list = NULL;
- tmclass->theclass.ivars = NULL;
- tmclass->theclass.bases = NULL;
- tmclass->theclass.vbases = NULL;
- tmclass->theclass.friends = NULL;
- tmclass->theclass.vtable = NULL;
- tmclass->members = NULL;
- tmclass->instances = NULL;
- tmclass->pspec_owner = NULL;
- tmclass->pspecs = NULL;
- tmclass->actions = NULL;
- tmclass->lex_order_count = 0;
- tmclass->align = 0;
- tmclass->flags = TEMPLCLASS_FLAGS_2;
- return tmclass;
-}
-
-void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class_declspec) {
- ClassLayout decle;
- TypeClass *tclass;
- HashNameNode *classname;
- Type *search;
- short t;
- NameSpace *nspace;
- NameResult pr;
- CScopeSave scopesave;
- GList gl;
- FileOffsetInfo offsetsave;
- SInt32 offset;
- Boolean is_templ;
- Boolean add_to_browse;
-
- memclrw(&decle, sizeof(ClassLayout));
- if (declinfo->x28) {
- tclass = TYPE_CLASS(declinfo->x28);
- } else {
- if (tk == TK_UU_DECLSPEC)
- CDecl_ParseClassDeclSpec(&class_declspec);
-
- switch (tk) {
- case ':':
- case '{':
- tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1);
- tclass->eflags |= class_declspec;
- break;
- case TK_IDENTIFIER:
- classname = tkidentifier;
- if (!declinfo->in_friend_decl && !declinfo->x4F && ((t = lookahead()) == ':' || t == ';' || t == '{')) {
- tk = lex();
- search = CScope_GetLocalTagType(cscope_current, classname);
- if (search) {
- tagtype_search:
- if (!IS_TYPE_CLASS(search)) {
- if ((IS_TYPE_TEMPLATE(search) || IS_TYPE_STRUCT(search)) && tk != '{' && tk != ':') {
- declinfo->thetype = search;
- return;
- }
- if (!IS_TYPE_TEMPLATE(search) || !(tclass = TYPE_CLASS(CTemplTool_GetSelfRefTemplate(search)))) {
- CError_Error(CErrorStr132, classname->name);
- tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1);
- break;
- }
- } else {
- tclass = TYPE_CLASS(search);
- }
- if (tclass->mode != mode) {
- if (
- (mode == CLASS_MODE_CLASS && tclass->mode == CLASS_MODE_STRUCT) ||
- (mode == CLASS_MODE_STRUCT && tclass->mode == CLASS_MODE_CLASS)
- )
- {
- if (copts.warn_structclass)
- CError_Warning(CErrorStr343);
- } else {
- CError_Error(CErrorStr132, classname);
- }
- }
- tclass->eflags |= class_declspec;
- break;
- } else {
- tclass = CDecl_DefineClass(cscope_current, classname, NULL, mode, 0, 1);
- tclass->eflags |= class_declspec;
- break;
- }
- } else {
- tkidentifier = classname;
- }
- default:
- if (!CScope_ParseElaborateName(&pr)) {
- CError_Error(CErrorStr121);
- declinfo->thetype = TYPE(&stsignedint);
- return;
- }
-
- tk = lex();
- if ((search = pr.type)) {
- goto tagtype_search;
- }
-
- CError_ASSERT(6786, pr.name_4);
-
- tclass = CDecl_DefineClass(CScope_FindNonClassNonFunctionNS(cscope_current), pr.name_4, NULL, mode, 0, 1);
- tclass->eflags |= class_declspec;
- }
- }
-
- declinfo->thetype = TYPE(tclass);
- if (tk == ':' || tk == '{') {
- if (declinfo->in_friend_decl)
- CError_Error(CErrorStr201);
-
- if (tclass->flags & CLASS_COMPLETED) {
- if (
- (tclass->flags & CLASS_IS_TEMPL) &&
- !TEMPL_CLASS(tclass)->instances &&
- !(TEMPL_CLASS(tclass)->flags & TEMPLCLASS_FLAGS_2)
- )
- {
- tclass = TYPE_CLASS(CDecl_SpecializeTemplateClass(TEMPL_CLASS(tclass)));
- } else {
- CError_Error(CErrorStr132, tclass->classname->name);
- tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1);
- }
- }
-
- for (nspace = cscope_current; nspace; nspace = nspace->parent) {
- if (nspace == tclass->nspace) {
- CError_Error(CErrorStr132, tclass->classname->name);
- tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1);
- break;
- }
- }
-
- is_templ = (tclass->flags & CLASS_IS_TEMPL) != 0;
- if (tclass->flags & CLASS_IS_TEMPL_INST) {
- TEMPL_CLASS_INST(tclass)->is_instantiated = 1;
- if (!declinfo->x28)
- TEMPL_CLASS_INST(tclass)->is_specialized = 1;
- }
-
- CError_ASSERT(6853, copts.structalignment >= 0 && copts.structalignment <= 14);
-
- tclass->eflags = tclass->eflags | (((copts.structalignment + 1) << 4) & 0xF0);
- if (tk == ':')
- CDecl_ParseBaseClassList(tclass, mode, is_templ);
-
- CScope_SetClassDefScope(tclass, &scopesave);
- if (tk == '{') {
- tk = lex();
- if ((add_to_browse = cparamblkptr->browseoptions.recordClasses && declinfo->file->recordbrowseinfo)) {
- offsetsave = member_fileoffset;
- CBrowse_BeginClass(declinfo, &gl);
- }
- CDecl_ParseClassMembers(&decle, tclass, mode);
- offset = CPrep_BrowserFileOffset();
- if (flag1)
- tk = lex();
- if (add_to_browse) {
- member_fileoffset = offsetsave;
- if (flag1 && tk == ';')
- CPrep_BrowserFileOffset();
- CBrowse_EndClass(offset, &gl);
- }
- } else {
- CError_Error(CErrorStr135);
- }
-
- if (is_templ)
- CTemplClass_CompleteClass(TEMPL_CLASS(tclass), &decle);
- else
- CDecl_CompleteClass(&decle, tclass);
- CScope_RestoreScope(&scopesave);
- }
-}
diff --git a/compiler_and_linker/unsorted/CError.c b/compiler_and_linker/unsorted/CError.c
deleted file mode 100644
index 02265c3..0000000
--- a/compiler_and_linker/unsorted/CError.c
+++ /dev/null
@@ -1,1098 +0,0 @@
-#include "cos.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/Unmangle.h"
-#include "compiler/enode.h"
-#include "compiler/objc.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/tokens.h"
-
-TStreamElement *cerror_locktoken;
-static TStreamElement *cerror_token;
-static short cerror_errorcount;
-static SInt32 cerror_lasterrorline;
-char cerror_synchdata[32];
-short cerror_synchoffset;
-int CError_BreakPointcount;
-
-// forward decls
-static void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual);
-static void CError_AppendObjectName(CErrorBuffer *eb, Object *obj);
-
-void CError_Init(void) {
- cerror_errorcount = 0;
- cerror_lasterrorline = -1;
- cerror_token = 0;
- cerror_locktoken = 0;
-}
-
-void CError_SetErrorToken(TStreamElement *token) {
- if (token && token->tokenfile)
- cerror_token = token;
-}
-
-void CError_SetNullErrorToken(void) {
- cerror_token = (TStreamElement *) -1;
-}
-
-void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved) {
- *saved = cerror_locktoken;
- if (token && token->tokenfile)
- cerror_locktoken = token;
-}
-
-void CError_UnlockErrorPos(TStreamElement **saved) {
- cerror_locktoken = *saved;
-}
-
-void CError_ResetErrorSkip(void) {
- cerror_lasterrorline = -1;
-}
-
-static void CError_GetErrorString(char *buf, short code) {
- CError_ASSERT(142, code >= CErrorStr100 && code < CErrorStrMAX);
- COS_GetString(buf, 10000, code - 99);
-}
-
-static void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) {
- eb->start = eb->end = buf;
- eb->size = eb->remaining = bufSize - 1;
-}
-
-static void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount) {
- char *newBuf;
-
- newBuf = lalloc(eb->size + amount);
- memcpy(newBuf, eb->start, eb->size);
- eb->start = newBuf;
- eb->end = newBuf + eb->size - eb->remaining;
- eb->size += amount;
- eb->remaining += amount;
-}
-
-static void CError_BufferAppendChar(CErrorBuffer *eb, char ch) {
- if (eb) {
- if (!eb->remaining)
- CError_BufferGrow(eb, 256);
- *(eb->end++) = ch;
- eb->remaining--;
- }
-}
-
-static void CError_BufferAppendString(CErrorBuffer *eb, const char *str) {
- size_t len;
-
- if (eb) {
- len = strlen(str);
- if (eb->remaining < len)
- CError_BufferGrow(eb, len);
- memcpy(eb->end, str, len);
- eb->end += len;
- eb->remaining -= len;
- }
-}
-
-static void CError_BufferTerminate(CErrorBuffer *eb) {
- if (eb->remaining == 0)
- CError_BufferGrow(eb, 1);
- *eb->end = 0;
- eb->remaining = 0;
-}
-
-static void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual) {
- if (qual & Q_PASCAL)
- CError_BufferAppendString(eb, "pascal ");
- if (qual & Q_CONST)
- CError_BufferAppendString(eb, "const ");
- if (qual & Q_VOLATILE)
- CError_BufferAppendString(eb, "volatile ");
- if (qual & Q_EXPLICIT)
- CError_BufferAppendString(eb, "explicit ");
- if (qual & Q_RESTRICT)
- CError_BufferAppendString(eb, "restrict ");
-}
-
-static void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node) {
- char buf[32];
-
- if (node) {
- switch (node->type) {
- case EINTCONST:
- CInt64_PrintDec(buf, node->data.intval);
- CError_BufferAppendString(eb, buf);
- return;
- case EOBJREF:
- CError_BufferAppendChar(eb, '&');
- CError_AppendObjectName(eb, node->data.objref);
- return;
- }
- }
-
- CError_BufferAppendString(eb, "{targ_expr}");
-}
-
-static void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) {
- switch (targ->pid.type) {
- case TPT_TYPE:
- CError_BufferAppendType(eb, targ->data.typeparam.type, targ->data.typeparam.qual);
- break;
- case TPT_NONTYPE:
- CError_BufferAppendTemplArgExpr(eb, targ->data.paramdecl.expr);
- break;
- case TPT_TEMPLATE:
- CError_BufferAppendType(eb, targ->data.ttargtype, 0);
- break;
- default:
- CError_FATAL(300);
- }
-}
-
-static void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs) {
- if (targs) {
- CError_BufferAppendChar(eb, '<');
- while (targs) {
- CError_BufferAppendTemplArg(eb, targs);
- if (targs->next)
- CError_BufferAppendString(eb, ", ");
- targs = targs->next;
- }
- CError_BufferAppendChar(eb, '>');
- }
-}
-
-static void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace) {
- while (nspace) {
- if (nspace->name) {
- CError_BufferAppendNameSpace(eb, nspace->parent);
- if (nspace->theclass) {
- CError_BufferAppendString(eb, nspace->theclass->classname->name);
- if (nspace->theclass->flags & CLASS_IS_TEMPL_INST)
- CError_BufferAppendTemplArgs(
- eb,
- !TEMPL_CLASS_INST(nspace->theclass)->oargs ? TEMPL_CLASS_INST(nspace->theclass)->inst_args : TEMPL_CLASS_INST(nspace->theclass)->oargs
- );
- } else {
- CError_BufferAppendString(eb, nspace->name->name);
- }
- CError_BufferAppendString(eb, "::");
- return;
- }
- nspace = nspace->parent;
- }
-}
-
-static void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty) {
- switch (ty->type) {
- case TYPEPOINTER:
- CError_BufferAppendPType(eb, TYPE_POINTER(ty)->target);
- if (TYPE_POINTER(ty)->qual & Q_REFERENCE)
- CError_BufferAppendString(eb, "&");
- else
- CError_BufferAppendString(eb, "*");
- CError_BufferAppendQualifier(eb, TYPE_POINTER(ty)->qual);
- break;
- case TYPEMEMBERPOINTER:
- CError_BufferAppendPType(eb, TYPE_MEMBER_POINTER(ty)->ty1);
- CError_BufferAppendType(eb, TYPE_MEMBER_POINTER(ty)->ty2, 0);
- CError_BufferAppendString(eb, "::*");
- CError_BufferAppendQualifier(eb, TYPE_MEMBER_POINTER(ty)->qual);
- break;
- }
-}
-
-static void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) {
- char buf[64];
- switch (type->dtype) {
- case TEMPLDEP_ARGUMENT:
- if (type->u.pid.nindex)
- sprintf(buf, "T%" PRId32 "_%" PRId32, type->u.pid.nindex, type->u.pid.index);
- else
- sprintf(buf, "T%" PRId32, type->u.pid.index);
- CError_BufferAppendString(eb, buf);
- break;
- case TEMPLDEP_QUALNAME:
- CError_BufferAppendTemplDepType(eb, type->u.qual.type);
- CError_BufferAppendString(eb, "::");
- CError_BufferAppendString(eb, type->u.qual.name->name);
- break;
- case TEMPLDEP_TEMPLATE:
- CError_BufferAppendType(eb, (Type *) type->u.templ.templ, 0);
- CError_BufferAppendTemplArgs(eb, type->u.templ.args);
- break;
- case TEMPLDEP_ARRAY:
- CError_BufferAppendType(eb, type->u.array.type, 0);
- CError_BufferAppendChar(eb, '[');
- CError_BufferAppendTemplArgExpr(eb, type->u.array.index);
- CError_BufferAppendChar(eb, ']');
- break;
- case TEMPLDEP_QUALTEMPL:
- CError_BufferAppendTemplDepType(eb, type->u.qualtempl.type);
- CError_BufferAppendString(eb, "::");
- CError_BufferAppendTemplArgs(eb, type->u.qualtempl.args);
- break;
- case TEMPLDEP_BITFIELD:
- CError_BufferAppendType(eb, type->u.bitfield.type, 0);
- CError_BufferAppendChar(eb, '[');
- CError_BufferAppendTemplArgExpr(eb, type->u.bitfield.size);
- CError_BufferAppendChar(eb, ']');
- break;
- default:
- CError_FATAL(463);
- }
-}
-
-static void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) {
- FuncArg *arg;
- UInt32 qual;
-
- qual = 0;
- CError_BufferAppendChar(eb, '(');
- if ((arg = tfunc->args)) {
- if (isMethod) {
- qual = arg->qual;
- arg = arg->next;
- if (arg)
- arg = arg->next;
- } else if ((tfunc->flags & FUNC_METHOD) && !TYPE_METHOD(tfunc)->is_static) {
- qual = arg->qual;
- arg = arg->next;
- if (arg) {
- if ((tfunc->flags & FUNC_IS_DTOR) || ((tfunc->flags & FUNC_IS_CTOR) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_HAS_VBASES)))
- arg = arg->next;
- }
- }
-
- while (arg) {
- if (arg == &elipsis || arg == &oldstyle) {
- CError_BufferAppendString(eb, "...");
- break;
- }
-
- CError_BufferAppendType(eb, arg->type, arg->qual);
-
- if ((arg = arg->next))
- CError_BufferAppendString(eb, ", ");
- else
- break;
- }
- }
- CError_BufferAppendChar(eb, ')');
- if (qual)
- CError_BufferAppendQualifier(eb, qual);
-}
-
-static void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) {
- // not matching - register issues
- Type *scan;
- Type *scan2;
- char buf[16];
-
- switch (ty->type) {
- case TYPEVOID:
- CError_BufferAppendQualifier(eb, qual);
- CError_BufferAppendString(eb, "void");
- return;
- case TYPEINT:
- case TYPEFLOAT:
- CError_BufferAppendQualifier(eb, qual);
- switch (TYPE_INTEGRAL(ty)->integral) {
- case IT_BOOL:
- CError_BufferAppendString(eb, "bool");
- return;
- case IT_CHAR:
- CError_BufferAppendString(eb, "char");
- return;
- case IT_UCHAR:
- CError_BufferAppendString(eb, "unsigned char");
- return;
- case IT_SCHAR:
- CError_BufferAppendString(eb, "signed char");
- return;
- case IT_WCHAR_T:
- CError_BufferAppendString(eb, "wchar_t");
- return;
- case IT_SHORT:
- CError_BufferAppendString(eb, "short");
- return;
- case IT_USHORT:
- CError_BufferAppendString(eb, "unsigned short");
- return;
- case IT_INT:
- CError_BufferAppendString(eb, "int");
- return;
- case IT_UINT:
- CError_BufferAppendString(eb, "unsigned int");
- return;
- case IT_LONG:
- CError_BufferAppendString(eb, "long");
- return;
- case IT_ULONG:
- CError_BufferAppendString(eb, "unsigned long");
- return;
- case IT_LONGLONG:
- CError_BufferAppendString(eb, "long long");
- return;
- case IT_ULONGLONG:
- CError_BufferAppendString(eb, "unsigned long long");
- return;
- case IT_FLOAT:
- CError_BufferAppendString(eb, "float");
- return;
- case IT_SHORTDOUBLE:
- CError_BufferAppendString(eb, "short double");
- return;
- case IT_DOUBLE:
- CError_BufferAppendString(eb, "double");
- return;
- case IT_LONGDOUBLE:
- CError_BufferAppendString(eb, "long double");
- return;
- default:
- CError_FATAL(584);
- }
- case TYPEENUM:
- CError_BufferAppendQualifier(eb, qual);
- CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace);
- if (TYPE_ENUM(ty)->enumname)
- CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name);
- else
- CError_BufferAppendString(eb, "{unnamed-enum}");
- return;
- case TYPESTRUCT:
- CError_BufferAppendQualifier(eb, qual);
- switch (TYPE_STRUCT(ty)->stype) {
- case STRUCT_TYPE_STRUCT:
- CError_BufferAppendString(eb, "struct ");
- break;
- case STRUCT_TYPE_UNION:
- CError_BufferAppendString(eb, "union ");
- break;
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- case STRUCT_VECTOR_FLOAT:
- case STRUCT_VECTOR_PIXEL:
- break;
- default:
- CError_FATAL(618);
- }
- if (TYPE_STRUCT(ty)->name)
- CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name);
- return;
- case TYPECLASS:
- CError_BufferAppendQualifier(eb, qual);
- CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent);
- if (TYPE_CLASS(ty)->classname) {
- CError_BufferAppendString(eb, TYPE_CLASS(ty)->classname->name);
- if (TYPE_CLASS(ty)->flags & CLASS_IS_TEMPL_INST)
- CError_BufferAppendTemplArgs(
- eb,
- TEMPL_CLASS_INST(ty)->oargs ? TEMPL_CLASS_INST(ty)->oargs : TEMPL_CLASS_INST(ty)->inst_args
- );
- } else {
- CError_BufferAppendString(eb, "{unnamed-class}");
- }
- return;
- case TYPEPOINTER:
- case TYPEMEMBERPOINTER:
- scan = ty;
- next_ptr:
- switch (scan->type) {
- case TYPEPOINTER:
- scan = TYPE_POINTER(scan)->target;
- goto next_ptr;
- case TYPEMEMBERPOINTER:
- scan = TYPE_MEMBER_POINTER(scan)->ty1;
- goto next_ptr;
- }
-
- CError_BufferAppendQualifier(eb, qual);
- switch (scan->type) {
- case TYPEFUNC:
- if (TYPE_FUNC(scan)->flags & FUNC_PASCAL)
- CError_BufferAppendString(eb, "pascal ");
- CError_BufferAppendType(eb, TYPE_FUNC(scan)->functype, 0);
- CError_BufferAppendString(eb, " (");
- CError_BufferAppendPType(eb, ty);
- CError_BufferAppendChar(eb, ')');
- CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER);
- return;
- case TYPEARRAY:
- scan2 = scan;
- while (scan->type == TYPEARRAY)
- scan = TYPE_POINTER(scan)->target;
- CError_BufferAppendType(eb, scan, 0);
- CError_BufferAppendString(eb, " (");
- CError_BufferAppendPType(eb, ty);
- CError_BufferAppendChar(eb, ')');
- ty = scan2;
- goto append_array_lengths;
- default:
- CError_BufferAppendType(eb, scan, 0);
- CError_BufferAppendChar(eb, ' ');
- CError_BufferAppendPType(eb, ty);
- return;
- }
- break;
- case TYPEFUNC:
- if (TYPE_FUNC(ty)->flags & FUNC_PASCAL)
- CError_BufferAppendString(eb, "pascal ");
- CError_BufferAppendQualifier(eb, qual);
- CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0);
- CError_BufferAppendChar(eb, ' ');
- CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0);
- return;
- case TYPEARRAY:
- CError_BufferAppendQualifier(eb, qual);
- scan = ty;
- while (scan->type == TYPEARRAY)
- scan = TYPE_POINTER(scan)->target;
- CError_BufferAppendType(eb, scan, 0);
- append_array_lengths:
- while (ty->type == TYPEARRAY) {
- CError_BufferAppendChar(eb, '[');
- if (ty->size && TYPE_POINTER(ty)->target->size) {
- sprintf(buf, "%" PRId32, ty->size / TYPE_POINTER(ty)->target->size);
- CError_BufferAppendString(eb, buf);
- }
- CError_BufferAppendChar(eb, ']');
- ty = TYPE_POINTER(ty)->target;
- }
- return;
- case TYPETEMPLATE:
- CError_BufferAppendQualifier(eb, qual);
- CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty));
- return;
- case TYPETEMPLDEPEXPR:
- CError_BufferAppendString(eb, "T");
- return;
- case TYPEBITFIELD:
- sprintf(buf, "bitfield:%" PRId32, TYPE_BITFIELD(ty)->bitlength);
- CError_BufferAppendString(eb, buf);
- return;
- default:
- CError_FATAL(752);
- }
-}
-
-char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap) {
- CErrorBuffer eb;
- char buf[256];
- char *ptr;
-
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_BufferAppendType(&eb, ty, qual);
- CError_BufferTerminate(&eb);
-
- if (useGlobalHeap)
- ptr = galloc(eb.size + 1);
- else
- ptr = lalloc(eb.size + 1);
-
- return strcpy(ptr, eb.start);
-}
-
-static void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) {
- Boolean flag = 0;
- char *opname;
-
- if (nspace && nspace->theclass) {
- if (name == constructor_name_node) {
- CError_BufferAppendString(eb, nspace->theclass->classname->name);
- flag = 1;
- } else if (name == destructor_name_node) {
- CError_BufferAppendChar(eb, '~');
- CError_BufferAppendString(eb, nspace->theclass->classname->name);
- flag = 1;
- }
- }
-
- if (!flag) {
- opname = CMangler_GetOperator(name);
- if (!opname) {
- if (tfunc && (tfunc->flags & FUNC_CONVERSION)) {
- CError_BufferAppendString(eb, "operator ");
- CError_BufferAppendType(eb, tfunc->functype, tfunc->qual);
- } else {
- CError_BufferAppendString(eb, name->name);
- }
- } else {
- CError_BufferAppendString(eb, opname);
- }
- }
-}
-
-static void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc) {
- while (nspace->is_templ && nspace->parent)
- nspace = nspace->parent;
-
- CError_BufferAppendNameSpace(eb, nspace);
- CError_AppendUnqualFunctionName(eb, nspace, name, tfunc);
- CError_BufferAppendTemplArgs(eb, templargs);
- if (tfunc) {
- if (!templargs && (tfunc->flags & FUNC_IS_TEMPL))
- CError_BufferAppendString(eb, "<...>");
- CError_BufferAppendFuncArgs(eb, tfunc, 0);
- } else {
- CError_BufferAppendString(eb, "()");
- }
-}
-
-static void CError_AppendObjectName(CErrorBuffer *eb, Object *obj) {
- if (obj->type->type == TYPEFUNC) {
- CError_AppendFunctionName(eb, obj->nspace, obj->name, obj->u.func.inst ? obj->u.func.inst->args : NULL, TYPE_FUNC(obj->type));
- } else {
- CError_BufferAppendNameSpace(eb, obj->nspace);
- CError_BufferAppendString(eb, obj->name->name);
- }
-}
-
-static void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth) {
- ObjCMethodArg *arg;
-
- CError_BufferAppendChar(eb, meth->is_class_method ? '+' : '-');
- CError_BufferAppendChar(eb, '(');
- CError_BufferAppendType(eb, meth->return_type, meth->return_qual);
- CError_BufferAppendChar(eb, ')');
- for (arg = meth->selector_args; arg; arg = arg->next) {
- if (arg->selector)
- CError_BufferAppendString(eb, arg->selector->name);
- if (arg->type) {
- CError_BufferAppendString(eb, ":(");
- CError_BufferAppendType(eb, arg->type, arg->qual);
- CError_BufferAppendChar(eb, ')');
- }
- }
- if (meth->has_valist)
- CError_BufferAppendString(eb, ",...");
-}
-
-char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name) {
- CErrorBuffer eb;
- char buf[256];
- char *ptr;
-
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_BufferAppendNameSpace(&eb, nspace);
- CError_BufferAppendString(&eb, name->name);
- CError_BufferTerminate(&eb);
-
- ptr = lalloc(eb.size + 1);
- return strcpy(ptr, eb.start);
-}
-
-char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) {
- CErrorBuffer eb;
- char buf[256];
- char *ptr;
-
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_AppendFunctionName(&eb, nspace, name, 0, tfunc);
- CError_BufferTerminate(&eb);
-
- ptr = lalloc(eb.size + 1);
- return strcpy(ptr, eb.start);
-}
-
-char *CError_GetObjectName(Object *obj) {
- CErrorBuffer eb;
- char buf[256];
- char *ptr;
-
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_AppendObjectName(&eb, obj);
- CError_BufferTerminate(&eb);
-
- ptr = lalloc(eb.size + 1);
- return strcpy(ptr, eb.start);
-}
-
-char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) {
- CErrorBuffer eb;
- char buf[256];
- char *ptr;
- char *opStr;
-
- CError_ASSERT(973, operatorName);
-
- opStr = CMangler_GetOperator(operatorName);
- if (!opStr)
- opStr = operatorName->name;
-
- if (nspace && nspace->name) {
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_BufferAppendNameSpace(&eb, nspace);
- CError_BufferAppendString(&eb, opStr);
- CError_BufferTerminate(&eb);
- ptr = lalloc(eb.size + 1);
- return strcpy(ptr, eb.start);
- } else {
- return opStr;
- }
-}
-
-void CError_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) {
- TStreamElement *token;
- short tokensize;
- CPrepFileInfo *tokenfile;
- CWMessageRef myref;
- char buf[128];
- CWMessageRef *ref;
- unsigned char messagetype;
-
- if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr)
- CError_UserBreak();
-
- if (!in_assembler && !flag1 && cerror_lasterrorline == lines) {
- if (cerror_errorcount++ >= 50) {
- if (cerror_errorcount > 60)
- longjmp(errorreturn, 1);
- tk = lex();
- cerror_errorcount = 0;
- if (tk == 0) {
- CompilerGetCString(1, buf);
- CWReportMessage(cparamblkptr->context, NULL, buf, NULL, messagetypeError, errTable);
- longjmp(errorreturn, 1);
- }
- }
- } else {
- if (!flag2) {
- cerror_lasterrorline = lines;
- cerror_errorcount = 0;
- }
- if (copts.warningerrors)
- flag2 = 0;
-
- if (cerror_token)
- token = cerror_token;
- else if (cerror_locktoken)
- token = cerror_locktoken;
- else
- token = NULL;
- //token = cerror_token ? cerror_token : cerror_locktoken ? cerror_locktoken : NULL;
- if ((SInt32) token == -1) {
- ref = NULL;
- } else {
- CPrep_GetTokenContext(token, &tokenfile, &myref.selectionoffset, &tokensize, &myref.linenumber, buf, &myref.tokenoffset, &myref.tokenlength, cerror_synchdata, &cerror_synchoffset);
- myref.selectionlength = tokensize;
- myref.sourcefile = tokenfile->textfile;
- ref = &myref;
- }
- messagetype = flag2 ? messagetypeWarning : messagetypeError;
- if (!flag2) {
- anyerrors = 1;
- fatalerrors = 1;
- }
- if (CWReportMessage(cparamblkptr->context, ref, str, buf, messagetype, errTable) != cwNoErr)
- longjmp(errorreturn, 1);
- }
-
- cerror_token = NULL;
-}
-
-static void CError_BufferAppendTemplateStack(CErrorBuffer *eb) {
- TemplStack *stack[64];
- TemplStack *scan;
- int index;
- int indent;
- int count;
-
- scan = ctempl_curinstance;
- for (count = 0; scan && count < 64; count++) {
- stack[count] = scan;
- scan = scan->next;
- }
-
- for (index = count - 1; index >= 0; index--) {
- CError_BufferAppendChar(eb, LF);
- for (indent = index; indent < count; indent++)
- CError_BufferAppendChar(eb, ' ');
- CError_BufferAppendString(eb, "(instantiating: '");
- if (stack[index]->is_func)
- CError_AppendObjectName(eb, stack[index]->u.func);
- else
- CError_BufferAppendType(eb, (Type *) stack[index]->u.theclass, 0);
- CError_BufferAppendString(eb, "')");
- }
-
- CError_BufferTerminate(eb);
-}
-
-void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) {
- // register allocation is fucked, matches otherwise
- CErrorBuffer eb;
- char buf[256];
- char unmangleBuf[256];
- SInt32 moddate;
- Type *type;
- UInt32 qual;
- const char *p;
- CError_BufferInit(&eb, buf, sizeof(buf));
-
- p = format;
- do {
- switch (p[0]) {
- case 0:
- break;
- case '%':
- switch (p[1]) {
- case 'n':
- MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf));
- CError_BufferAppendString(&eb, unmangleBuf);
- p += 2;
- continue;
- case 'u':
- CError_BufferAppendString(&eb, va_arg(list, const char *));
- p += 2;
- continue;
- case 'o':
- CError_AppendObjectName(&eb, va_arg(list, Object *));
- p += 2;
- continue;
- case 'm':
- CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *));
- p += 2;
- continue;
- case 't':
- type = va_arg(list, Type *);
- qual = va_arg(list, UInt32);
- CError_BufferAppendType(&eb, type, qual);
- p += 2;
- continue;
- case '%':
- CError_BufferAppendChar(&eb, '%');
- p += 2;
- continue;
- case 'i':
- sprintf(unmangleBuf, "%" PRId32, va_arg(list, SInt32));
- CError_BufferAppendString(&eb, unmangleBuf);
- p += 2;
- continue;
- case 'f':
- CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name);
- p += 2;
- continue;
- default:
- CError_FATAL(1174);
- }
- break;
- default:
- CError_BufferAppendChar(&eb, *(p++));
- continue;
- }
- break;
- } while (1);
-
- CError_BufferAppendTemplateStack(&eb);
- CError_ErrorMessage(code, eb.start, flag1, flag2);
-}
-
-static void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) {
- char buf[256];
-
- CError_GetErrorString(buf, code);
- CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2);
-}
-
-void CError_Error(int code, ...) {
- va_list va;
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- va_start(va, code);
- CError_VAErrorMessage(code, va, 0, 0);
- va_end(va);
-
- if (in_assembler && !preprocessing_only)
- AssemblerError();
-}
-
-void CError_ErrorTerm(short code) {
- CError_GetErrorString(string, code);
- CError_ErrorMessage(code + 10000, string, 0, 0);
- longjmp(errorreturn, 1);
-}
-
-void CError_ErrorSkip(int code, ...) {
- va_list va;
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- va_start(va, code);
- CError_VAErrorMessage(code, va, 0, 0);
- va_end(va);
-
- if (tk != ';' && tk != ')' && tk != '}' && tk != ',' && tk != ']')
- tk = lex();
-}
-
-void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes) {
- // does not match - one branch has loop weirdness
- CErrorBuffer eb;
- char buf[256];
- char *p;
- ENodeList *argscan;
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- CError_GetErrorString(string, code);
- CError_BufferInit(&eb, buf, sizeof(buf));
-
- while (args && args->object->otype != OT_OBJECT)
- args = args->next;
- CError_ASSERT(1268, args);
-
- p = string;
- do {
- switch (*p) {
- case 0:
- goto exit_main_loop;
- case '*':
- if (OBJECT(args->object)->type->type == TYPEFUNC) {
- CError_AppendUnqualFunctionName(
- &eb,
- OBJECT(args->object)->nspace,
- OBJECT(args->object)->name,
- TYPE_FUNC(OBJECT(args->object)->type));
- if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_METHOD)
- if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_IS_CTOR)
- if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_HAS_VBASES)
- if (argNodes)
- argNodes = argNodes->next;
- } else {
- CError_BufferAppendString(&eb, OBJECT(args->object)->name->name);
- }
- CError_BufferAppendChar(&eb, '(');
- argscan = argNodes;
- while (argscan) {
- CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS);
- if ((argscan = argscan->next))
- CError_BufferAppendString(&eb, ", ");
- else
- break;
- }
- CError_BufferAppendChar(&eb, ')');
- break;
- default:
- CError_BufferAppendChar(&eb, *p);
- }
- p++;
- } while (1);
-
-exit_main_loop:
- while (args) {
- if (args->object->otype == OT_OBJECT) {
- CError_BufferAppendChar(&eb, LF);
- CError_BufferAppendChar(&eb, '\'');
- CError_AppendObjectName(&eb, (Object *) args->object);
- CError_BufferAppendChar(&eb, '\'');
- }
- args = args->next;
- }
-
- CError_BufferAppendTemplateStack(&eb);
- CError_ErrorMessage(10000 + code, eb.start, 0, 0);
-}
-
-void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes) {
- // not sure if the arg is actually ObjectList since it's never called lmao
- NameSpaceObjectList first;
- NameSpaceObjectList *current;
-
- first.object = (ObjBase *) obj;
- current = &first;
- while (olst) {
- current->next = lalloc(sizeof(NameSpaceObjectList));
- current = current->next;
- current->object = (ObjBase *) olst->object;
- olst = olst->next;
- }
- current->next = NULL;
-
- CError_ErrorFuncCall(CErrorStr392, &first, argNodes);
-}
-
-void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) {
- // not sure if this arg is ObjectList or NameSpaceObjectList
- CErrorBuffer eb;
- char buf[256];
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- CError_GetErrorString(string, CErrorStr199);
- CError_BufferInit(&eb, buf, sizeof(buf));
- CError_BufferAppendString(&eb, string);
-
- if (obj) {
- CError_BufferAppendChar(&eb, LF);
- CError_BufferAppendChar(&eb, '\'');
- CError_AppendObjectName(&eb, obj);
- CError_BufferAppendChar(&eb, '\'');
- }
- while (olst) {
- CError_BufferAppendChar(&eb, LF);
- CError_BufferAppendChar(&eb, '\'');
- CError_AppendObjectName(&eb, olst->object);
- CError_BufferAppendChar(&eb, '\'');
- olst = olst->next;
- }
- CError_BufferAppendTemplateStack(&eb);
- CError_ErrorMessage(10199, eb.start, 0, 0);
-}
-
-void CError_AbstractClassError(TypeClass *tclass) {
- Object *result = CClass_CheckPures(tclass);
- if (!result)
- CError_Error(CErrorStr372, tclass, 0);
- else
- CError_Error(CErrorStr194, result);
-}
-
-void CError_Warning(int code, ...) {
- va_list va;
- if (trychain || copts.supress_warnings)
- return;
-
- va_start(va, code);
- CError_VAErrorMessage(code, va, 0, 1);
- va_end(va);
-}
-
-void CError_BreakPoint(const char *a, const char *b) {
- if (!a || !strcmp(a, b))
- CError_BreakPointcount++;
-}
-
-void CError_Internal(char *filename, int line) {
- char tmp[128];
- CompilerGetCString(5, tmp);
- sprintf(string, tmp, filename, line);
- CError_ErrorMessage(10001, string, 1, 0);
- longjmp(errorreturn, 1);
- CError_BreakPoint(0, 0);
-}
-
-void CError_ExpressionTooComplex(void) {
- CompilerGetCString(6, string);
- CError_ErrorMessage(10002, string, 1, 0);
- longjmp(errorreturn, 1);
-}
-
-void CError_NoMem(void) {
- cprep_nomem_exit = 1;
- longjmp(errorreturn, 1);
-}
-
-void CError_UserBreak(void) {
- CompilerGetCString(8, string);
- longjmp(errorreturn, 1);
-}
-
-void CError_CannotOpen(void) {
- CompilerGetCString(9, string);
- CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0);
- longjmp(errorreturn, 1);
-}
-
-void CError_QualifierCheck(UInt32 qual) {
- if (qual) {
- Boolean anything = 0;
-
- if (qual & Q_CONST) {
- CError_Error(CErrorStr313, "const");
- anything = 1;
- }
- if (qual & Q_VOLATILE) {
- CError_Error(CErrorStr313, "volatile");
- anything = 1;
- }
- if (qual & Q_RESTRICT) {
- CError_Error(CErrorStr313, "restrict");
- anything = 1;
- }
- if (qual & Q_ASM) {
- CError_Error(CErrorStr313, "asm");
- anything = 1;
- }
- if (qual & Q_PASCAL) {
- CError_Error(CErrorStr313, "pascal");
- anything = 1;
- }
- if (qual & Q_INLINE) {
- CError_Error(CErrorStr313, "inline");
- anything = 1;
- }
- if (qual & Q_REFERENCE) {
- CError_Error(CErrorStr313, "& reference type");
- anything = 1;
- }
- if (qual & Q_EXPLICIT) {
- CError_Error(CErrorStr313, "explicit");
- anything = 1;
- }
- if (qual & Q_MUTABLE) {
- CError_Error(CErrorStr313, "mutable");
- anything = 1;
- }
- if (qual & Q_VIRTUAL) {
- CError_Error(CErrorStr313, "virtual");
- anything = 1;
- }
- if (qual & Q_FRIEND) {
- CError_Error(CErrorStr313, "friend");
- anything = 1;
- }
- if (qual & Q_IN) {
- CError_Error(CErrorStr313, "in");
- anything = 1;
- }
- if (qual & Q_OUT) {
- CError_Error(CErrorStr313, "out");
- anything = 1;
- }
- if (qual & Q_INOUT) {
- CError_Error(CErrorStr313, "inout");
- anything = 1;
- }
- if (qual & Q_BYCOPY) {
- CError_Error(CErrorStr313, "bycopy");
- anything = 1;
- }
- if (qual & Q_BYREF) {
- CError_Error(CErrorStr313, "byref");
- anything = 1;
- }
- if (qual & Q_ONEWAY) {
- CError_Error(CErrorStr313, "oneway");
- anything = 1;
- }
- if (qual & Q_ALIGNED_MASK) {
- CError_Error(CErrorStr313, "__attribute__((aligned(?)))");
- anything = 1;
- }
-
- if (!anything)
- CError_Error(CErrorStr176);
- }
-}
diff --git a/compiler_and_linker/unsorted/CException.c b/compiler_and_linker/unsorted/CException.c
deleted file mode 100644
index d68ce13..0000000
--- a/compiler_and_linker/unsorted/CException.c
+++ /dev/null
@@ -1,2183 +0,0 @@
-#include "compiler/CException.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInline.h"
-#include "compiler/CInit.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-typedef struct UniqueObj {
- struct UniqueObj *next;
- Object *object;
- SInt32 uniqueid;
-} UniqueObj;
-
-ExceptionAction *cexcept_dobjstack;
-Boolean cexcept_hasdobjects;
-Boolean cexcept_magic;
-static UniqueObj *cexcept_uniqueobjs;
-static Boolean cexcept_canthrow;
-static DtorTemp *cexcept_dtortemps;
-static Statement *cexcept_prevstmt;
-static ExceptionAction *cexcept_eabefore;
-static ExceptionAction *cexcept_eaafter;
-static Boolean cexcept_expandtrycatch;
-static Boolean cexcept_hastrycatch;
-static Boolean cexcept_serialize;
-
-// forward decls
-static ENode *CExcept_TempTransExprCond(ENode *expr);
-static ENode *CExcept_TempTransExpr(ENode *expr);
-
-void CExcept_Setup(void) {
- cexcept_dobjstack = NULL;
- cexcept_uniqueobjs = NULL;
- cexcept_hasdobjects = 0;
- cexcept_magic = 0;
-}
-
-Boolean CExcept_CanThrowException(Object *object, Boolean flag) {
- if (copts.optEH && IS_TYPE_FUNC(object->type)) {
- if (flag)
- return 1;
-
- if (TYPE_FUNC(object->type)->flags & FUNC_NOTHROW)
- return 0;
-
- if (
- !flag &&
- TYPE_FUNC(object->type)->exspecs &&
- TYPE_FUNC(object->type)->exspecs &&
- !TYPE_FUNC(object->type)->exspecs->type
- )
- return 0;
-
- if (
- copts.optEH2 &&
- !(object->qual & Q_MANGLE_NAME) &&
- object != rt_ptmf_call &&
- object != rt_ptmf_scall &&
- object != Rdync_func &&
- object != rt_som_glue1 &&
- object != rt_som_glue2 &&
- object != rt_som_glue3 &&
- object != carr_func &&
- object != cnar_func &&
- object != darr_func &&
- object != dnar_func &&
- object != dnar3_func &&
- object != Xthrw_func
- )
- return 0;
- }
-
- return 1;
-}
-
-void CExcept_CheckStackRefs(ExceptionAction *actions) {
- while (actions) {
- switch (actions->type) {
- case EAT_DESTROYLOCAL:
- CInline_ObjectAddrRef(actions->data.destroy_local.dtor);
- break;
- case EAT_DESTROYLOCALCOND:
- CInline_ObjectAddrRef(actions->data.destroy_local_cond.dtor);
- break;
- case EAT_DESTROYLOCALOFFSET:
- CInline_ObjectAddrRef(actions->data.destroy_local_offset.dtor);
- break;
- case EAT_DESTROYLOCALPOINTER:
- CInline_ObjectAddrRef(actions->data.destroy_local_pointer.dtor);
- break;
- case EAT_DESTROYLOCALARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_local_array.dtor);
- break;
- case EAT_DESTROYPARTIALARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_partial_array.dtor);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- CInline_ObjectAddrRef(actions->data.destroy_member.dtor);
- break;
- case EAT_DESTROYMEMBERCOND:
- CInline_ObjectAddrRef(actions->data.destroy_member_cond.dtor);
- break;
- case EAT_DESTROYMEMBERARRAY:
- CInline_ObjectAddrRef(actions->data.destroy_member_array.dtor);
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- CInline_ObjectAddrRef(actions->data.delete_pointer.deletefunc);
- break;
- case EAT_DELETEPOINTERCOND:
- CInline_ObjectAddrRef(actions->data.delete_pointer_cond.deletefunc);
- break;
- case EAT_CATCHBLOCK:
- case EAT_ACTIVECATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(192);
- }
- actions = actions->prev;
- }
-}
-
-void CExcept_CompareSpecifications(ExceptSpecList *a, ExceptSpecList *b) {
- ExceptSpecList *aa;
- ExceptSpecList *bb;
-
- aa = a;
- bb = b;
- while (1) {
- if (!aa) {
- if (!bb)
- break;
- CError_Error(CErrorStr265);
- return;
- }
-
- if (!bb) {
- CError_Error(CErrorStr265);
- return;
- }
-
- aa = aa->next;
- bb = bb->next;
- }
-
- if (a->type == NULL) {
- if (b->type != NULL)
- CError_Error(CErrorStr265);
- } else if (b->type == NULL) {
- CError_Error(CErrorStr265);
- } else {
- for (aa = a; aa; aa = aa->next) {
- for (bb = b; bb; bb = bb->next) {
- if (is_typesame(aa->type, bb->type) && aa->qual == bb->qual)
- break;
- }
-
- if (bb == NULL) {
- CError_Error(CErrorStr265);
- return;
- }
- }
- }
-}
-
-Boolean CExcept_ActionCompare(ExceptionAction *a, ExceptionAction *b) {
- if (a->type == b->type) {
- switch (a->type) {
- case EAT_DESTROYLOCAL:
- return a->data.destroy_local.local == b->data.destroy_local.local;
- case EAT_DESTROYLOCALCOND:
- return a->data.destroy_local_cond.local == b->data.destroy_local_cond.local;
- case EAT_DESTROYLOCALOFFSET:
- return a->data.destroy_local_offset.local == b->data.destroy_local_offset.local &&
- a->data.destroy_local_offset.offset == b->data.destroy_local_offset.offset;
- case EAT_DESTROYLOCALPOINTER:
- return a->data.destroy_local_pointer.pointer == b->data.destroy_local_pointer.pointer;
- case EAT_DESTROYLOCALARRAY:
- return a->data.destroy_local_array.localarray == b->data.destroy_local_array.localarray;
- case EAT_DESTROYPARTIALARRAY:
- return a->data.destroy_partial_array.arraypointer == b->data.destroy_partial_array.arraypointer;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- return a->data.destroy_member.objectptr == b->data.destroy_member.objectptr &&
- a->data.destroy_member.offset == b->data.destroy_member.offset;
- case EAT_DESTROYMEMBERCOND:
- return a->data.destroy_member_cond.objectptr == b->data.destroy_member_cond.objectptr &&
- a->data.destroy_member_cond.offset == b->data.destroy_member_cond.offset;
- case EAT_DESTROYMEMBERARRAY:
- return a->data.destroy_member_array.objectptr == b->data.destroy_member_array.objectptr &&
- a->data.destroy_member_array.offset == b->data.destroy_member_array.offset;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- return a->data.delete_pointer.pointerobject == b->data.delete_pointer.pointerobject &&
- a->data.delete_pointer.deletefunc == b->data.delete_pointer.deletefunc;
- case EAT_DELETEPOINTERCOND:
- return a->data.delete_pointer_cond.cond == b->data.delete_pointer_cond.cond;
- case EAT_CATCHBLOCK:
- return a->data.catch_block.catch_label == b->data.catch_block.catch_label;
- case EAT_ACTIVECATCHBLOCK:
- return a->data.active_catch_block.catch_info_object == b->data.active_catch_block.catch_info_object;
- case EAT_TERMINATE:
- return 1;
- case EAT_SPECIFICATION:
- return a->data.specification.unexp_id == b->data.specification.unexp_id;
- default:
- CError_FATAL(314);
- }
- }
-
- return 0;
-}
-
-int CExcept_IsSubList(ExceptionAction *a, ExceptionAction *b) {
- int diff;
- int i;
- int count1;
- int count2;
- ExceptionAction *scan;
-
- if (a == b)
- return 0;
-
- count1 = 0;
- scan = a;
- while (scan) {
- scan = scan->prev;
- count1++;
- }
-
- scan = b;
- count2 = 0;
- while (scan) {
- scan = scan->prev;
- count2++;
- }
-
- diff = count2 - count1;
- if (diff < 0)
- return -1;
-
- for (i = 0; i < diff; i++)
- b = b->prev;
-
- while (a != b) {
- if (!a || !b || !CExcept_ActionCompare(a, b))
- return -1;
- a = a->prev;
- b = b->prev;
- }
-
- return diff;
-}
-
-Boolean CExcept_ActionNeedsDestruction(ExceptionAction *action) {
- switch (action->type) {
- case EAT_CATCHBLOCK:
- return 0;
- case EAT_DESTROYLOCAL:
- case EAT_DESTROYLOCALOFFSET:
- case EAT_DESTROYLOCALARRAY:
- case EAT_DELETELOCALPOINTER:
- case EAT_ACTIVECATCHBLOCK:
- return 1;
- case EAT_NOP:
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_DESTROYBASE:
- break;
- default:
- CError_FATAL(363);
- }
-
- return 0;
-}
-
-ENode *CExcept_RegisterDestructorObject(Object *local, SInt32 offset, Object *dtor, Boolean flag) {
- ExceptionAction *action;
- ENode *expr;
- Object *dtorObject;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- expr = create_objectrefnode(local);
- dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1);
-
- if (offset == 0) {
- action->type = EAT_DESTROYLOCAL;
- action->data.destroy_local.local = local;
- action->data.destroy_local.dtor = dtorObject;
- } else {
- action->type = EAT_DESTROYLOCALOFFSET;
- action->data.destroy_local_offset.local = local;
- action->data.destroy_local_offset.dtor = dtorObject;
- action->data.destroy_local_offset.offset = offset;
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- }
-
- cexcept_hasdobjects = 1;
- return expr;
-}
-
-void CExcept_RegisterLocalArray(Statement *stmt, Object *localarray, Object *dtor, SInt32 elements, SInt32 element_size) {
- ExceptionAction *action;
- Object *dtorObject;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1);
-
- action->type = EAT_DESTROYLOCALARRAY;
- action->data.destroy_local_array.localarray = localarray;
- action->data.destroy_local_array.dtor = dtorObject;
- action->data.destroy_local_array.elements = elements;
- action->data.destroy_local_array.element_size = element_size;
-
- cexcept_hasdobjects = 1;
-}
-
-void CExcept_RegisterDeleteObject(Statement *stmt, Object *pointerobject, Object *deletefunc) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-
- action->type = EAT_DELETELOCALPOINTER;
- action->data.delete_pointer.pointerobject = pointerobject;
- action->data.delete_pointer.deletefunc = deletefunc;
-
- cexcept_hasdobjects = 1;
-}
-
-static void CExcept_PatchConstructorAction(Statement *stmt, ExceptionAction *actionArg) {
- ExceptionAction *action30;
- ExceptionAction *action;
- ExceptionAction *scan;
-
- for (action = stmt->dobjstack; action; action = action->prev) {
- switch (action->type) {
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_SPECIFICATION:
- case EAT_DESTROYBASE:
- goto exitFirstLoop;
- case EAT_CATCHBLOCK:
- action30 = action;
- while (1) {
- if (!action30->prev)
- goto exitFirstLoop;
- action30 = action30->prev;
- if (action30->type != EAT_CATCHBLOCK) {
- CError_FATAL(481);
- }
- }
- }
- }
- exitFirstLoop:
- if (action == NULL) {
- while (stmt) {
- if ((scan = stmt->dobjstack)) {
- while (1) {
- if (scan == actionArg)
- break;
- if (scan->prev == NULL) {
- scan->prev = actionArg;
- break;
- }
- scan = scan->prev;
- }
- } else {
- stmt->dobjstack = actionArg;
- }
- stmt = stmt->next;
- }
- } else {
- actionArg->prev = action;
- while (stmt) {
- if (stmt->dobjstack != action) {
- scan = stmt->dobjstack;
- do {
- if (scan == actionArg)
- goto nextStmt;
- if (scan->prev == action) {
- scan->prev = actionArg;
- goto nextStmt;
- }
- } while ((scan = scan->prev));
-
- while (1) {
- if (action->type == EAT_CATCHBLOCK && action->prev == NULL)
- return;
-
- action = action->prev;
- if (!action)
- CError_FATAL(531);
- }
- } else {
- stmt->dobjstack = actionArg;
- }
- nextStmt:
- stmt = stmt->next;
- }
- }
-}
-
-void CExcept_Terminate(void) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_TERMINATE;
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-}
-
-void CExcept_Magic(void) {
- cexcept_magic = 1;
-}
-
-static Object *CExcept_FindLocalObject(char *name) {
- NameResult result;
- NameSpaceObjectList *list;
-
- list = CScope_FindObjectList(&result, GetHashNameNodeExport(name));
- if (list && list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DLOCAL)
- return OBJECT(list->object);
-
- CError_FATAL(580);
- return NULL;
-}
-
-void CExcept_ArrayInit(void) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_DESTROYPARTIALARRAY;
- action->data.destroy_partial_array.arraypointer = CExcept_FindLocalObject("ptr");
- action->data.destroy_partial_array.arraycounter = CExcept_FindLocalObject("i");
- action->data.destroy_partial_array.dtor = CExcept_FindLocalObject("dtor");
- action->data.destroy_partial_array.element_size = CExcept_FindLocalObject("size");
-
- action->prev = cexcept_dobjstack;
- cexcept_dobjstack = action;
-}
-
-void CExcept_RegisterMember(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, Object *cond, Boolean isMember) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- if (cond == NULL) {
- if (isMember) {
- action->type = EAT_DESTROYMEMBER;
- action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- } else {
- action->type = EAT_DESTROYBASE;
- action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy0);
- }
- action->data.destroy_member.objectptr = objectptr;
- action->data.destroy_member.offset = offset;
- } else {
- CError_ASSERT(632, cond->type == TYPE(&stsignedshort));
- action->type = EAT_DESTROYMEMBERCOND;
- action->data.destroy_member_cond.objectptr = objectptr;
- action->data.destroy_member_cond.cond = cond;
- action->data.destroy_member_cond.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- action->data.destroy_member_cond.offset = offset;
- }
-
- CExcept_PatchConstructorAction(stmt, action);
- stmt->flags |= StmtFlag_2;
-}
-
-void CExcept_RegisterMemberArray(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, SInt32 elements, SInt32 element_size) {
- ExceptionAction *action;
-
- action = lalloc(sizeof(ExceptionAction));
- memclrw(action, sizeof(ExceptionAction));
-
- action->type = EAT_DESTROYMEMBERARRAY;
- action->data.destroy_member_array.objectptr = objectptr;
- action->data.destroy_member_array.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
- action->data.destroy_member_array.offset = offset;
- action->data.destroy_member_array.elements = elements;
- action->data.destroy_member_array.element_size = element_size;
-
- CExcept_PatchConstructorAction(stmt, action);
- stmt->flags |= StmtFlag_2;
-}
-
-static Statement *CExcept_DestroyLocal(ExceptionAction *ea, Statement *stmt, Object *object, Object *dtor, SInt32 offset) {
- ENode *expr;
-
- expr = create_objectrefnode(object);
- if (offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
-
- expr = CABI_DestroyObject(dtor, expr, CABIDestroy1, 1, 0);
-
- CError_ASSERT(687, expr->type == EFUNCCALL && expr->data.funccall.funcref->type == EOBJREF);
- if (expr->data.funccall.funcref->data.objref->datatype == DVFUNC)
- expr->data.funccall.funcref->flags |= ENODE_FLAG_80;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr;
- stmt->dobjstack = ea->prev;
- return stmt;
-}
-
-static Statement *CExcept_DestroyLocalPointer(ExceptionAction *ea, Statement *stmt, Object *object, Object *deletefunc) {
- Statement *newStmt;
-
- newStmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- newStmt->expr = funccallexpr(deletefunc, create_objectnode2(object), NULL, NULL, NULL);
- newStmt->dobjstack = ea->prev;
- return newStmt;
-}
-
-static Statement *CExcept_DestroyLocalArray(ExceptionAction *ea, Statement *stmt, Object *object, Object *dtor, SInt32 elements, SInt32 element_size) {
- Statement *newStmt;
- ENode *dtorExpr;
-
- newStmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
-
- if (dtor)
- dtorExpr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- else
- dtorExpr = nullnode();
-
- newStmt->expr = funccallexpr(
- darr_func,
- create_objectrefnode(object),
- dtorExpr,
- intconstnode(TYPE(&stunsignedlong), element_size),
- intconstnode(TYPE(&stunsignedlong), elements)
- );
-
- newStmt->dobjstack = ea->prev;
- return newStmt;
-}
-
-static Statement *CExcept_EndCatch(ExceptionAction *ea, Statement *stmt) {
- stmt = CFunc_InsertStatement(ST_ENDCATCHDTOR, stmt);
- stmt->expr = create_objectrefnode(ea->data.active_catch_block.catch_info_object);
- stmt->dobjstack = ea->prev;
- if (!ea->data.active_catch_block.call_dtor)
- stmt->type = ST_ENDCATCH;
- return stmt;
-}
-
-Statement *CExcept_ActionCleanup(ExceptionAction *ea, Statement *stmt) {
- switch (ea->type) {
- case EAT_DESTROYLOCALCOND:
- case EAT_DESTROYLOCALPOINTER:
- case EAT_DESTROYPARTIALARRAY:
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYMEMBERCOND:
- case EAT_DESTROYMEMBERARRAY:
- case EAT_DELETEPOINTER:
- case EAT_DELETEPOINTERCOND:
- case EAT_CATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- case EAT_DESTROYBASE:
- break;
- case EAT_DESTROYLOCAL:
- stmt = CExcept_DestroyLocal(
- ea, stmt,
- ea->data.destroy_local.local,
- ea->data.destroy_local.dtor,
- 0);
- break;
- case EAT_DESTROYLOCALOFFSET:
- stmt = CExcept_DestroyLocal(
- ea, stmt,
- ea->data.destroy_local.local,
- ea->data.destroy_local.dtor,
- ea->data.destroy_local_offset.offset);
- break;
- case EAT_DELETELOCALPOINTER:
- stmt = CExcept_DestroyLocalPointer(
- ea, stmt,
- ea->data.delete_pointer.pointerobject,
- ea->data.delete_pointer.deletefunc);
- break;
- case EAT_DESTROYLOCALARRAY:
- stmt = CExcept_DestroyLocalArray(
- ea, stmt,
- ea->data.destroy_local_array.localarray,
- ea->data.destroy_local_array.dtor,
- ea->data.destroy_local_array.elements,
- ea->data.destroy_local_array.element_size);
- break;
- case EAT_ACTIVECATCHBLOCK:
- stmt = CExcept_EndCatch(ea, stmt);
- break;
- default:
- CError_FATAL(827);
- }
-
- return stmt;
-}
-
-static void CExcept_MangleNameSpaceName(NameSpace *nspace) {
- while (nspace) {
- if (nspace->name) {
- CExcept_MangleNameSpaceName(nspace->parent);
- AppendGListName(&name_mangle_list, nspace->name->name);
- AppendGListName(&name_mangle_list, "::");
- break;
- }
- nspace = nspace->parent;
- }
-}
-
-static void CExcept_MangleClassName(TypeClass *tclass) {
- NameSpace *nspace;
- char buf[64];
-
- CExcept_MangleNameSpaceName(tclass->nspace->parent);
- AppendGListName(&name_mangle_list, tclass->classname->name);
-
- for (nspace = tclass->nspace->parent; nspace; nspace = nspace->parent) {
- if (!nspace->is_global && !nspace->is_templ && !nspace->name) {
- CError_ASSERT(868, cscope_currentfunc != NULL);
-
- sprintf(buf, "*%" PRIxPTR "*%" PRIxPTR "*", &cscope_currentfunc, &nspace);
- AppendGListName(&name_mangle_list, buf);
- break;
- }
- }
-}
-
-typedef struct BCL {
- struct BCL *next;
- TypeClass *tclass;
- SInt32 offset;
- Boolean is_virtual;
- Boolean is_public;
- Boolean is_ambig;
-} BCL;
-
-static void CExcept_MakeBaseClassListAmbig(BCL *bcl, TypeClass *tclass) {
- BCL *scan;
- ClassList *list;
-
- for (scan = bcl; scan; scan = scan->next) {
- if (scan->tclass == tclass)
- scan->is_ambig = 1;
- }
-
- for (list = tclass->bases; list; list = list->next)
- CExcept_MakeBaseClassListAmbig(bcl, list->base);
-}
-
-static BCL *CExcept_GetBaseClassList(BCL *bcl, TypeClass *tclass1, TypeClass *tclass2, SInt32 offset, Boolean is_virtual, Boolean is_public) {
- BCL *node;
- ClassList *base;
- Boolean new_is_public;
-
- for (node = bcl; node; node = node->next) {
- if (node->tclass == tclass2) {
- if (is_virtual && node->is_virtual) {
- if (is_public)
- node->is_public = 1;
- } else {
- CExcept_MakeBaseClassListAmbig(bcl, tclass2);
- }
- return bcl;
- }
- }
-
- node = lalloc(sizeof(BCL));
- node->tclass = tclass2;
- node->offset = offset;
- node->is_virtual = is_virtual;
- node->is_public = is_public;
- node->is_ambig = 0;
- node->next = bcl;
- bcl = node;
-
- for (base = tclass2->bases; base; base = base->next) {
- new_is_public = is_public && (base->access == ACCESSPUBLIC);
- bcl = base->is_virtual
- ? CExcept_GetBaseClassList(bcl, tclass1, base->base, CClass_VirtualBaseOffset(tclass1, base->base), 1, new_is_public)
- : CExcept_GetBaseClassList(bcl, tclass1, base->base, offset + base->offset, 0, new_is_public);
- }
-
- return bcl;
-}
-
-static void CExcept_MangleClass(TypeClass *tclass) {
- BCL *bcl;
- char buf[20];
-
- for (bcl = CExcept_GetBaseClassList(NULL, tclass, tclass, 0, 0, 1); bcl; bcl = bcl->next) {
- if (bcl->is_public && !bcl->is_ambig) {
- CExcept_MangleClassName(bcl->tclass);
- AppendGListByte(&name_mangle_list, '!');
-
- if (bcl->offset) {
- sprintf(buf, "%" PRId32 "!", bcl->offset);
- AppendGListName(&name_mangle_list, buf);
- } else {
- AppendGListByte(&name_mangle_list, '!');
- }
- }
- }
-}
-
-static ENode *CExcept_GetTypeID(Type *type, UInt32 qual, Boolean flag) {
- ENode *expr;
- TypePointer my_tptr;
-
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) || (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_CLASS(TPTR_TARGET(type)))) {
- name_mangle_list.size = 0;
- if (IS_TYPE_POINTER_ONLY(type)) {
- AppendGListByte(&name_mangle_list, '*');
- type = TPTR_TARGET(type);
- } else {
- AppendGListByte(&name_mangle_list, '!');
- }
-
- if (flag) {
- CExcept_MangleClass(TYPE_CLASS(type));
- } else {
- CExcept_MangleClassName(TYPE_CLASS(type));
- AppendGListByte(&name_mangle_list, '!');
- }
- } else {
- if (IS_TYPE_POINTER_ONLY(type)) {
- if (TPTR_QUAL(type) & (Q_CONST | Q_VOLATILE)) {
- my_tptr = *TYPE_POINTER(type);
- my_tptr.qual = 0;
- type = TYPE(&my_tptr);
- }
- } else {
- qual = 0;
- }
- CMangler_MangleType(type, qual);
- }
-
- AppendGListByte(&name_mangle_list, 0);
-
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewPointerType(TYPE(&stchar));
- expr->data.string.size = name_mangle_list.size;
- expr->data.string.data = galloc(name_mangle_list.size);
- memcpy(expr->data.string.data, *name_mangle_list.data, name_mangle_list.size);
- return expr;
-}
-
-static Object *CExcept_TypeID(Type *type, UInt32 qual) {
- ENode *expr = CExcept_GetTypeID(type, qual, 0);
- CError_ASSERT(1086, expr->type == ESTRINGCONST);
- return CInit_DeclareString(expr->data.string.data, expr->data.string.size, 0, 0);
-}
-
-void CExcept_ScanExceptionSpecification(TypeFunc *tfunc) {
- ExceptSpecList *exspecs;
- ExceptSpecList *exspec;
- DeclInfo di;
-
- exspecs = NULL;
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return;
- }
-
- if ((tk = lex()) != ')') {
- while (1) {
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass)
- CError_Error(CErrorStr177);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr146);
-
- if (IS_TYPE_POINTER_ONLY(di.thetype)) {
- if (TPTR_QUAL(di.thetype) & (Q_CONST | Q_VOLATILE)) {
- TypePointer *newtype = galloc(sizeof(TypePointer));
- *newtype = *TYPE_POINTER(di.thetype);
- newtype->qual = 0;
- di.thetype = TYPE(newtype);
- }
- } else {
- di.qual = 0;
- }
-
- for (exspec = exspecs; exspec; exspec = exspec->next) {
- if (is_typesame(exspec->type, di.thetype) && exspec->qual == di.qual)
- break;
- }
-
- if (!exspec) {
- exspec = galloc(sizeof(ExceptSpecList));
- memclrw(exspec, sizeof(ExceptSpecList));
- exspec->next = exspecs;
- exspec->type = di.thetype;
- exspec->qual = di.qual;
- exspecs = exspec;
- }
-
- if (tk == ')')
- break;
-
- if (tk != ',') {
- CError_Error(CErrorStr115);
- break;
- }
-
- tk = lex();
- }
- }
-
- if (!exspecs) {
- exspecs = galloc(sizeof(ExceptSpecList));
- memclrw(exspecs, sizeof(ExceptSpecList));
- }
- tfunc->exspecs = exspecs;
- tk = lex();
-}
-
-static ENode *CExcept_CallCopyCtor(Object *object, Type *type, ENode *expr1, ENode *expr2) {
- ENodeList *list;
- ENode *expr;
- FuncArg *arg;
-
- if (
- !IS_TYPE_FUNC(object->type) ||
- !(arg = TYPE_FUNC(object->type)->args) ||
- !(arg = arg->next)
- )
- CError_FATAL(1169);
-
- expr = funccallexpr(object, expr1, NULL, NULL, NULL);
- list = expr->data.funccall.args;
-
- if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(1179, arg = arg->next);
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = intconstnode(TYPE(&stsignedshort), 1);
- }
-
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = expr2;
-
- while ((arg = arg->next)) {
- CError_ASSERT(1195, arg->dexpr);
-
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->next = NULL;
- list->node = CExpr_GetDefaultArgument(expr->data.funccall.funcref, arg);
- }
-
- return expr;
-}
-
-ENode *CExcept_ScanThrowExpression(void) {
- ENode *expr;
- Object *func;
- ENode *resultExpr;
- Object *obj;
- ENode *thrownExpr;
- ENode *tempExpr;
-
- if (!copts.exceptions)
- CError_Error(CErrorStr252);
-
- switch ((tk = lex())) {
- case ')':
- case ',':
- case ':':
- case ';':
- expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
- break;
- default:
- thrownExpr = pointer_generation(assignment_expression());
- obj = create_temp_object(thrownExpr->rtype);
- if (!IS_TYPE_CLASS(thrownExpr->rtype) || !(resultExpr = CExpr_IsTempConstruction(thrownExpr, thrownExpr->rtype, &expr))) {
- tempExpr = create_objectrefnode(obj);
- if (IS_TYPE_CLASS(thrownExpr->rtype) && (func = CClass_CopyConstructor(TYPE_CLASS(thrownExpr->rtype)))) {
- resultExpr = CExcept_CallCopyCtor(func, thrownExpr->rtype, tempExpr, getnodeaddress(thrownExpr, 0));
- } else {
- if (thrownExpr->rtype->size == 0)
- CError_Error(CErrorStr146);
-
- tempExpr = makemonadicnode(tempExpr, EINDIRECT);
- tempExpr->rtype = thrownExpr->rtype;
- resultExpr = makediadicnode(tempExpr, thrownExpr, EASS);
- resultExpr = makediadicnode(resultExpr, create_objectrefnode(obj), ECOMMA);
- resultExpr->rtype = TYPE(&void_ptr);
- }
- } else {
- *expr = *create_objectrefnode(obj);
- }
-
- expr = CExcept_GetTypeID(thrownExpr->rtype, ENODE_QUALS(thrownExpr), 1);
- if (IS_TYPE_CLASS(thrownExpr->rtype) && (func = CClass_Destructor(TYPE_CLASS(thrownExpr->rtype)))) {
- expr = funccallexpr(
- Xthrw_func,
- expr,
- resultExpr,
- create_objectrefnode(CABI_GetDestructorObject(func, CABIDestroy1)),
- NULL);
- } else {
- expr = funccallexpr(
- Xthrw_func,
- expr,
- resultExpr,
- nullnode(),
- NULL);
- }
- }
-
- expr->flags |= ENODE_FLAG_VOLATILE;
- return expr;
-}
-
-static Boolean CExcept_MightNeedDtor(Type *type) {
- if (type) {
- if (IS_TYPE_CLASS(type)) {
- if (!CClass_Destructor(TYPE_CLASS(type)))
- return 0;
- } else if (IS_TYPE_POINTER_ONLY(type)) {
- if (!(TPTR_QUAL(type) & Q_REFERENCE) || !IS_TYPE_CLASS(TPTR_TARGET(type)))
- return 0;
- } else {
- return 0;
- }
- }
-
- return 1;
-}
-
-typedef struct CatchBlock {
- struct CatchBlock *next;
- Object *catch_object;
- Object *catch_info_object;
- Statement *stmt;
- Statement *anotherStmt;
- Type *type;
- UInt32 qual;
-} CatchBlock;
-
-static void CExcept_PatchDObjStack(Statement *beginCatchStmt, Statement *tryEndStmt, Statement *endStmt, CatchBlock *catchBlock) {
- ExceptionAction *ea;
- ExceptionAction *stackHead;
- ExceptionAction *stackTail;
- ExceptionAction *firstEA;
- Statement *stmt;
- Object *catch_info_object;
- Boolean call_dtor;
-
- catch_info_object = catchBlock->catch_info_object;
- call_dtor = 0;
- stackHead = stackTail = beginCatchStmt->dobjstack;
- firstEA = NULL;
-
- while (catchBlock) {
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
-
- ea->prev = stackTail;
- stackTail = ea;
-
- if (!firstEA)
- firstEA = ea;
-
- ea->type = EAT_CATCHBLOCK;
- ea->data.catch_block.catch_object = catchBlock->catch_object;
- ea->data.catch_block.catch_label = catchBlock->stmt->label;
- if (catchBlock->type)
- ea->data.catch_block.catch_typeid = CExcept_TypeID(catchBlock->type, catchBlock->qual);
- ea->data.catch_block.catch_info_object = catch_info_object;
-
- if (!call_dtor && CExcept_MightNeedDtor(catchBlock->type))
- call_dtor = 1;
-
- ea->data.catch_block.catch_type = catchBlock->type;
- ea->data.catch_block.catch_qual = catchBlock->qual;
- catchBlock = catchBlock->next;
- }
-
- stmt = beginCatchStmt;
- while (1) {
- if ((ea = stmt->dobjstack) != stackHead) {
- while (1) {
- CError_ASSERT(1404, ea);
- if (ea->prev == stackTail)
- break;
- if (ea->prev == stackHead) {
- ea->prev = stackTail;
- break;
- }
- ea = ea->prev;
- }
- } else {
- stmt->dobjstack = stackTail;
- }
-
- if (stmt == endStmt)
- break;
-
- if (stmt == tryEndStmt) {
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->prev = stackHead;
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->data.active_catch_block.call_dtor = call_dtor;
- stackTail = ea;
- }
-
- stmt = stmt->next;
- CError_ASSERT(1426, stmt);
- }
-
- cexcept_hasdobjects = 1;
-}
-
-static void CExcept_CheckTryObjects(ENode *expr) {
- if (expr->data.objref->datatype == DLOCAL && expr->data.objref->u.var.info)
- expr->data.objref->u.var.info->noregister = 1;
-}
-
-static ENode *CExcept_CatchExpressionInit(DeclInfo *di, CatchBlock *catchBlock) {
- Object *catch_object;
- Object *copyCtor;
- Object *dtor;
- ENode *expr;
-
- if (CScope_FindName(cscope_current, di->name))
- CError_Error(CErrorStr122, di->name->name);
-
- catch_object = CParser_NewLocalDataObject(di, 1);
- CFunc_SetupLocalVarInfo(catch_object);
- CScope_AddObject(cscope_current, di->name, OBJ_BASE(catch_object));
- catchBlock->catch_object = catch_object;
-
- expr = makediadicnode(
- create_objectrefnode(catchBlock->catch_info_object),
- intconstnode(TYPE(&stunsignedlong), 12),
- EADD);
- expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(di->thetype));
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = CDecl_NewPointerType(di->thetype);
-
- if (IS_TYPE_REFERENCE(di->thetype))
- return makediadicnode(create_objectnode2(catch_object), expr, EASS);
-
- if (IS_TYPE_CLASS(di->thetype) && (copyCtor = CClass_CopyConstructor(TYPE_CLASS(di->thetype)))) {
- dtor = CClass_Destructor(TYPE_CLASS(di->thetype));
- return CExcept_CallCopyCtor(
- copyCtor,
- di->thetype,
- (dtor == NULL) ? create_objectrefnode(catch_object) : CExcept_RegisterDestructorObject(catch_object, 0, dtor, 0),
- expr);
- }
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = di->thetype;
- return makediadicnode(create_objectnode(catch_object), expr, EASS);
-}
-
-void CExcept_ScanTryBlock(DeclThing *dt, Boolean flag) {
- Object *catch_info_object; // r27
- Statement *beginCatchStmt; // r14
- Statement *tryEndStmt; // r16
- Statement *endStmt; // r17
- Statement *stmt; // r14
- CLabel *catchEndLabel; // r19
- CLabel *endLabel; // r24
- CatchBlock *catchStack; // r23
- CatchBlock *catchBlock; // r22
- DeclBlock *declBlock; // r20
- DeclInfo di;
-
- if (!copts.exceptions)
- CError_Error(CErrorStr252);
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
- if (cexcept_magic) {
- catch_info_object->name = GetHashNameNodeExport("__exception_magic");
- CScope_AddObject(cscope_current, catch_info_object->name, OBJ_BASE(catch_info_object));
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->flags = StmtFlag_1;
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
-
- beginCatchStmt = CFunc_AppendStatement(ST_BEGINCATCH);
- beginCatchStmt->expr = create_objectrefnode(catch_info_object);
-
- if (tk != '{') {
- CError_Error(CErrorStr135);
- return;
- }
-
- CFunc_CompoundStatement(dt);
-
- if (tk != TK_CATCH) {
- CError_Error(CErrorStr242);
- return;
- }
-
- stmt = CFunc_AppendStatement(ST_GOTO);
- catchEndLabel = stmt->label = newlabel();
- tryEndStmt = stmt;
-
- endLabel = newlabel();
- catchStack = NULL;
-
- while (1) {
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->flags = StmtFlag_1;
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
-
- declBlock = NULL;
-
- catchBlock = lalloc(sizeof(ExceptionAction));
- memclrw(catchBlock, sizeof(ExceptionAction));
- catchBlock->next = catchStack;
- catchStack = catchBlock;
-
- catchBlock->stmt = stmt;
- catchBlock->catch_info_object = catch_info_object;
-
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- break;
- }
-
- if ((tk = lex()) == TK_ELLIPSIS) {
- tk = lex();
- } else {
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (di.x48)
- CError_Error(CErrorStr121);
- if (di.storageclass)
- CError_Error(CErrorStr177);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
-
- if (IS_TYPE_FUNC(di.thetype))
- di.thetype = CDecl_NewPointerType(di.thetype);
- else if (IS_TYPE_ARRAY(di.thetype))
- di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype));
-
- IsCompleteType(di.thetype);
- if (IS_TYPE_CLASS(di.thetype) && (TYPE_CLASS(di.thetype)->flags & CLASS_ABSTRACT))
- CError_AbstractClassError(TYPE_CLASS(di.thetype));
-
- catchBlock->type = di.thetype;
- catchBlock->qual = di.qual;
-
- if (di.name) {
- ENode *expr;
- declBlock = CFunc_NewDeclBlock();
- expr = CExcept_CatchExpressionInit(&di, catchBlock);
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
- }
- }
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- break;
- }
-
- if ((tk = lex()) != '{') {
- CError_Error(CErrorStr123);
- break;
- }
-
- CFunc_CompoundStatement(dt);
- if (flag) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
- }
-
- catchBlock->anotherStmt = stmt;
-
- if (declBlock)
- CFunc_RestoreBlock(declBlock);
-
- if (tk != TK_CATCH)
- break;
-
- CFunc_AppendStatement(ST_GOTO)->label = endLabel;
- }
-
- endStmt = CFunc_AppendStatement(ST_LABEL);
- endStmt->label = endLabel;
- endLabel->stmt = endStmt;
-
- CExcept_PatchDObjStack(beginCatchStmt, tryEndStmt, endStmt, catchBlock);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = catchEndLabel;
- catchEndLabel->stmt = stmt;
-}
-
-static Statement *CExcept_InsertPrevStatement(StatementType sttype) {
- Statement *stmt = CFunc_InsertStatement(sttype, cexcept_prevstmt);
- stmt->sourceoffset = stmt->next->sourceoffset;
- stmt->sourcefilepath = stmt->next->sourcefilepath;
- stmt->dobjstack = cexcept_eabefore;
- return stmt;
-}
-
-static Object *CExcept_GetETEMPObject(ENode *expr) {
- UniqueObj *uobj;
- SInt32 id;
-
- if ((id = expr->data.temp.uniqueid)) {
- for (uobj = cexcept_uniqueobjs; uobj; uobj = uobj->next) {
- if (uobj->uniqueid == id)
- return uobj->object;
- }
-
- uobj = galloc(sizeof(UniqueObj));
- uobj->next = cexcept_uniqueobjs;
- cexcept_uniqueobjs = uobj;
- uobj->uniqueid = id;
- return (uobj->object = create_temp_object(expr->data.temp.type));
- } else {
- return create_temp_object(expr->data.temp.type);
- }
-}
-
-static ENode *CExcept_TempTrans_ETEMP(ENode *expr) {
- Object *object;
- ExceptionAction *ea;
- DtorTemp *dtorTemp;
- Object *dtor;
-
- object = CExcept_GetETEMPObject(expr);
- if (expr->data.temp.needs_dtor) {
- dtorTemp = lalloc(sizeof(DtorTemp));
- dtorTemp->next = cexcept_dtortemps;
- cexcept_dtortemps = dtorTemp;
- dtorTemp->object = object;
- dtorTemp->temp = NULL;
-
- if (
- !IS_TYPE_CLASS(expr->data.temp.type) ||
- !(dtorTemp->dtor = CClass_Destructor(TYPE_CLASS(expr->data.temp.type)))
- )
- CError_FATAL(1749);
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
- ea->type = EAT_DESTROYLOCAL;
- ea->data.destroy_local.local = dtorTemp->object;
- ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
- }
-
- expr->type = EOBJREF;
- expr->data.objref = object;
- return expr;
-}
-
-static ENode *CExcept_TransNewException(ENode *expr, Boolean isCond) {
- Object *tempObj;
- CLabel *label;
- Boolean isArray;
- Statement *stmt;
- ExceptionAction *ea;
- ENode *result;
-
- isArray = expr->type == ENEWEXCEPTIONARRAY;
-
- if (isCond) {
- expr->data.newexception.initexpr = CExcept_TempTransExprCond(expr->data.newexception.initexpr);
- expr->data.newexception.tryexpr = CExcept_TempTransExprCond(expr->data.newexception.tryexpr);
- tempObj = create_temp_object(TYPE(&stchar));
-
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS);
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DELETEPOINTERCOND;
- ea->data.delete_pointer_cond.pointerobject = expr->data.newexception.pointertemp;
- ea->data.delete_pointer_cond.deletefunc = expr->data.newexception.deletefunc;
- ea->data.delete_pointer_cond.cond = tempObj;
-
- if (isArray) {
- result = makediadicnode(
- makediadicnode(
- expr->data.newexception.initexpr,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 1), EASS),
- ECOMMA
- ),
- expr->data.newexception.tryexpr,
- ECOMMA
- );
-
- result = makediadicnode(
- result,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS),
- ECOMMA
- );
-
- result = makediadicnode(
- result,
- create_objectnode(expr->data.newexception.pointertemp),
- ECOMMA
- );
- } else {
- result = makediadicnode(
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 1), EASS),
- expr->data.newexception.tryexpr,
- ECOMMA
- );
-
- result = makediadicnode(
- expr->data.newexception.initexpr,
- makediadicnode(
- result,
- makediadicnode(create_objectnode(tempObj), intconstnode(TYPE(&stchar), 0), EASS),
- ECOMMA
- ),
- ELAND
- );
-
- result = makediadicnode(
- result,
- create_objectnode(expr->data.newexception.pointertemp),
- ECOMMA
- );
- }
- } else {
- expr->data.newexception.initexpr = CExcept_TempTransExpr(expr->data.newexception.initexpr);
- expr->data.newexception.tryexpr = CExcept_TempTransExpr(expr->data.newexception.tryexpr);
-
- if (isArray) {
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = expr->data.newexception.initexpr;
- } else {
- stmt = CExcept_InsertPrevStatement(ST_IFNGOTO);
- stmt->expr = expr->data.newexception.initexpr;
- label = newlabel();
- stmt->label = label;
- }
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.newexception.tryexpr;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- ea->type = EAT_DELETEPOINTER;
- ea->data.delete_pointer.pointerobject = expr->data.newexception.pointertemp;
- ea->data.delete_pointer.deletefunc = expr->data.newexception.deletefunc;
- stmt->dobjstack = ea;
-
- if (!isArray) {
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label;
- label->stmt = stmt;
- stmt->dobjstack = cexcept_eabefore;
- }
-
- cexcept_prevstmt = stmt;
- result = create_objectnode(expr->data.newexception.pointertemp);
- }
-
- result->rtype = expr->rtype;
- return result;
-}
-
-static ENode *CExcept_TransInitTryCatch(ENode *expr, Boolean isCond) {
- CLabel *label1;
- CLabel *label2;
- CLabel *label3;
- Object *catch_info_object;
- Statement *stmt;
- ExceptionAction *ea;
-
- cexcept_hastrycatch = 1;
-
- if (isCond) {
- CError_ASSERT(1877, !cexcept_expandtrycatch);
-
- cexcept_serialize = 1;
- expr->data.itc.initexpr = CExcept_TempTransExprCond(expr->data.itc.initexpr);
- expr->data.itc.tryexpr = CExcept_TempTransExprCond(expr->data.itc.tryexpr);
- expr->data.itc.catchexpr = CExcept_TempTransExprCond(expr->data.itc.catchexpr);
- expr->data.itc.result = CExcept_TempTransExprCond(expr->data.itc.result);
- return expr;
- }
-
- expr->data.itc.initexpr = CExcept_TempTransExpr(expr->data.itc.initexpr);
- expr->data.itc.tryexpr = CExcept_TempTransExpr(expr->data.itc.tryexpr);
- expr->data.itc.catchexpr = CExcept_TempTransExpr(expr->data.itc.catchexpr);
- expr->data.itc.result = CExcept_TempTransExpr(expr->data.itc.result);
-
- if (!cexcept_expandtrycatch)
- return expr;
-
- label1 = newlabel();
- label2 = newlabel();
- label3 = newlabel();
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
-
- stmt = CExcept_InsertPrevStatement(ST_IFNGOTO);
- stmt->expr = expr->data.itc.initexpr;
- stmt->label = label3;
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_CATCHBLOCK;
- ea->data.catch_block.catch_label = label2;
- ea->data.catch_block.catch_info_object = catch_info_object;
- ea->prev = stmt->dobjstack;
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->flags = StmtFlag_1;
- stmt->label = label1;
- label1->stmt = stmt;
- stmt->dobjstack = ea;
-
- stmt = CFunc_InsertStatement(ST_BEGINCATCH, stmt);
- stmt->expr = create_objectrefnode(catch_info_object);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.itc.tryexpr;
-
- stmt = CFunc_InsertStatement(ST_GOTO, stmt);
- stmt->label = label3;
-
- CError_ASSERT(1928, stmt->dobjstack == ea);
-
- stmt->dobjstack = ea->prev;
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->prev = stmt->dobjstack;
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->flags = StmtFlag_1;
- stmt->label = label2;
- label2->stmt = stmt;
- stmt->dobjstack = ea;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = expr->data.itc.catchexpr;
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = funccallexpr(Xthrw_func, nullnode(), nullnode(), nullnode(), NULL);
-
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- stmt->label = label3;
- label3->stmt = stmt;
-
- CError_ASSERT(1968, stmt->dobjstack == ea);
-
- stmt->dobjstack = ea->prev;
-
- cexcept_prevstmt = stmt;
- return expr->data.itc.result;
-}
-
-static ENode *CExcept_TempTransFuncCall(ENode *expr, Boolean isCond) {
- ENodeList *tempArg;
- ENodeList **argArray;
- ENodeList *args;
- ExceptionAction *ea;
- Statement *stmt;
- DtorTemp *dtorTemp;
- ENode *tempNode;
-
- tempArg = NULL;
- if ((args = expr->data.funccall.args)) {
- tempNode = args->node;
- if (tempNode->type == ETEMP) {
- if (tempNode->data.temp.needs_dtor)
- tempArg = args;
- } else if (args->next) {
- tempNode = args->next->node;
- if (tempNode->type == ETEMP) {
- if (tempNode->data.temp.needs_dtor)
- tempArg = args->next;
- }
- }
- }
-
- if (tempArg) {
- if (isCond) {
- ENodeList *arg = args;
- SInt32 i = 0;
- while (arg) {
- arg = arg->next;
- i++;
- }
-
- argArray = lalloc(sizeof(ENodeList *) * i);
- for (args = expr->data.funccall.args, i = 0; args; args = args->next)
- argArray[i++] = args;
-
- while (i > 0) {
- i--;
- if (argArray[i] != tempArg)
- argArray[i]->node = CExcept_TempTransExprCond(argArray[i]->node);
- }
- } else {
- while (args) {
- if (args != tempArg)
- args->node = CExcept_TempTransExpr(args->node);
- args = args->next;
- }
- }
-
- dtorTemp = lalloc(sizeof(DtorTemp));
- dtorTemp->next = cexcept_dtortemps;
- cexcept_dtortemps = dtorTemp;
-
- dtorTemp->object = CExcept_GetETEMPObject(tempNode);
- dtorTemp->temp = NULL;
-
- if (
- !IS_TYPE_CLASS(tempNode->data.temp.type) ||
- !(dtorTemp->dtor = CClass_Destructor(TYPE_CLASS(tempNode->data.temp.type)))
- )
- CError_FATAL(2046);
-
- tempNode->type = EOBJREF;
- tempNode->data.objref = dtorTemp->object;
-
- if (isCond) {
- Type *type24 = expr->rtype;
- dtorTemp->temp = create_temp_object(TYPE(&stchar));
-
- expr = makediadicnode(
- expr,
- makediadicnode(create_objectnode(dtorTemp->temp), intconstnode(TYPE(&stchar), 1), EASS),
- ECOMMA
- );
-
- expr = makediadicnode(
- expr,
- create_objectrefnode(dtorTemp->object),
- ECOMMA
- );
- expr->rtype = type24;
-
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(
- create_objectnode(dtorTemp->temp),
- intconstnode(TYPE(&stchar), 0),
- EASS
- );
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DESTROYLOCALCOND;
- ea->data.destroy_local_cond.local = dtorTemp->object;
- ea->data.destroy_local_cond.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
- ea->data.destroy_local_cond.cond = dtorTemp->temp;
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
- } else {
- stmt = CExcept_InsertPrevStatement(ST_EXPRESSION);
- stmt->expr = expr;
- cexcept_prevstmt = stmt;
-
- ea = lalloc(sizeof(ExceptionAction));
- ea->prev = cexcept_eabefore;
- cexcept_eabefore = ea;
-
- ea->type = EAT_DESTROYLOCAL;
- ea->data.destroy_local.local = dtorTemp->object;
- ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1);
-
- ea = lalloc(sizeof(ExceptionAction));
- *ea = *cexcept_eabefore;
- ea->prev = cexcept_eaafter;
- cexcept_eaafter = ea;
-
- expr = lalloc(sizeof(ENode));
- *expr = *stmt->expr;
- expr->type = EOBJREF;
- expr->data.objref = tempArg->node->data.objref;
- }
- return expr;
- } else {
- if (isCond) {
- SInt32 i = 0;
- while (args) {
- args = args->next;
- i++;
- }
-
- argArray = lalloc(sizeof(ENodeList *) * i);
- for (args = expr->data.funccall.args, i = 0; args; args = args->next)
- argArray[i++] = args;
-
- while (i > 0) {
- i--;
- argArray[i]->node = CExcept_TempTransExprCond(argArray[i]->node);
- }
-
- expr->data.funccall.funcref = CExcept_TempTransExprCond(expr->data.funccall.funcref);
- } else {
- while (args) {
- args->node = CExcept_TempTransExpr(args->node);
- args = args->next;
- }
-
- expr->data.funccall.funcref = CExcept_TempTransExpr(expr->data.funccall.funcref);
- }
-
- return expr;
- }
-}
-
-static ENode *CExcept_TempTransExprCond(ENode *expr) {
- switch (expr->type) {
- case ETEMP:
- return CExcept_TempTrans_ETEMP(expr);
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- return CExcept_TransNewException(expr, 1);
- case EINITTRYCATCH:
- return CExcept_TransInitTryCatch(expr, 1);
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CExcept_TempTransExprCond(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CExcept_TempTransExprCond(expr->data.nullcheck.condexpr);
- return expr;
- case ECOND:
- expr->data.cond.cond = CExcept_TempTransExprCond(expr->data.cond.cond);
- expr->data.cond.expr1 = CExcept_TempTransExprCond(expr->data.cond.expr1);
- expr->data.cond.expr2 = CExcept_TempTransExprCond(expr->data.cond.expr2);
- return expr;
- case ELAND:
- case ELOR:
- expr->data.diadic.left = CExcept_TempTransExprCond(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- return expr;
- case EFUNCCALL:
- case EFUNCCALLP:
- return CExcept_TempTransFuncCall(expr, 1);
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case ECOMMA:
- case EROTL:
- case EROTR:
- expr->data.diadic.left = CExcept_TempTransExprCond(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- return expr;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case ETYPCON:
- case EBITFIELD:
- expr->data.monadic = CExcept_TempTransExprCond(expr->data.monadic);
- return expr;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ELABEL:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
- default:
- CError_FATAL(2236);
- return expr;
- }
-}
-
-static ENode *CExcept_TempTransExpr(ENode *expr) {
- switch (expr->type) {
- case ETEMP:
- return CExcept_TempTrans_ETEMP(expr);
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- return CExcept_TransNewException(expr, 0);
- case EINITTRYCATCH:
- return CExcept_TransInitTryCatch(expr, 0);
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CExcept_TempTransExpr(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CExcept_TempTransExprCond(expr->data.nullcheck.condexpr);
- return expr;
- case ECOND:
- expr->data.cond.cond = CExcept_TempTransExpr(expr->data.cond.cond);
- expr->data.cond.expr1 = CExcept_TempTransExprCond(expr->data.cond.expr1);
- expr->data.cond.expr2 = CExcept_TempTransExprCond(expr->data.cond.expr2);
- return expr;
- case ELAND:
- case ELOR:
- case ECOMMA:
- expr->data.diadic.left = CExcept_TempTransExpr(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExprCond(expr->data.diadic.right);
- return expr;
- case EFUNCCALL:
- case EFUNCCALLP:
- return CExcept_TempTransFuncCall(expr, 0);
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EROTL:
- case EROTR:
- expr->data.diadic.left = CExcept_TempTransExpr(expr->data.diadic.left);
- expr->data.diadic.right = CExcept_TempTransExpr(expr->data.diadic.right);
- return expr;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case ETYPCON:
- case EBITFIELD:
- expr->data.monadic = CExcept_TempTransExpr(expr->data.monadic);
- return expr;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EMFPOINTER:
- case EPRECOMP:
- case ELABEL:
- case EOBJLIST:
- case EMEMBER:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
- default:
- CError_FATAL(2350);
- return expr;
- }
-}
-
-static Statement *CExcept_DtorTransform(Statement *stmt) {
- DtorTemp *dtorTemp;
- Statement *curStmt;
- CLabel *lastLabel;
-
- dtorTemp = cexcept_dtortemps;
- curStmt = stmt;
- while (dtorTemp) {
- if (
- cexcept_eaafter &&
- (cexcept_eaafter->type == EAT_DESTROYLOCAL || cexcept_eaafter->type == EAT_DESTROYLOCALCOND) &&
- cexcept_eaafter->data.destroy_local.local == dtorTemp->object
- )
- {
- cexcept_eaafter = cexcept_eaafter->prev;
- } else {
- CError_FATAL(2374);
- }
-
- if (dtorTemp->temp) {
- curStmt = CFunc_InsertStatement(ST_IFNGOTO, curStmt);
- curStmt->expr = create_objectnode(dtorTemp->temp);
- curStmt->dobjstack = cexcept_eaafter;
- lastLabel = curStmt->label = newlabel();
- }
-
- curStmt = CFunc_InsertStatement(ST_EXPRESSION, curStmt);
- curStmt->expr = CABI_DestroyObject(dtorTemp->dtor, create_objectrefnode(dtorTemp->object), CABIDestroy1, 1, 0);
- curStmt->dobjstack = cexcept_eaafter;
-
- if (dtorTemp->temp) {
- curStmt = CFunc_InsertStatement(ST_LABEL, curStmt);
- curStmt->label = lastLabel;
- lastLabel->stmt = curStmt;
- }
-
- dtorTemp = dtorTemp->next;
- }
-
- return curStmt;
-}
-
-static void CExcept_TempTransform(Statement *stmt, Boolean flag1, Boolean flag2) {
- Statement *prevStmt;
- Statement *iter;
- Statement copy;
- Object *tempObj;
-
- prevStmt = cexcept_prevstmt;
- cexcept_dtortemps = NULL;
- cexcept_serialize = 0;
- cexcept_expandtrycatch = 0;
- cexcept_hastrycatch = 0;
- stmt->expr = CExcept_TempTransExpr(stmt->expr);
-
- if (cexcept_hastrycatch) {
- cexcept_expandtrycatch = 1;
- if (cexcept_serialize) {
- CInline_SerializeStatement(stmt);
- cexcept_prevstmt = stmt;
- } else {
- cexcept_prevstmt = prevStmt;
- }
-
- iter = prevStmt;
- while (1) {
- CError_ASSERT(2425, iter);
-
- switch (iter->type) {
- case ST_RETURN:
- CError_ASSERT(2429, iter->expr != NULL);
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- iter->expr = CExcept_TempTransExpr(iter->expr);
- }
-
- if (iter == stmt)
- break;
- cexcept_prevstmt = iter;
- iter = iter->next;
- }
- }
-
- if (cexcept_dtortemps) {
- if (!flag1) {
- if (flag2) {
- ENode *expr = stmt->expr;
- CError_ASSERT(2456, !IS_TYPE_CLASS(expr->rtype) || !CClass_Destructor(TYPE_CLASS(expr->rtype)));
-
- tempObj = create_temp_object(expr->rtype);
- stmt->expr = makediadicnode(create_objectnode(tempObj), expr, EASS);
- }
-
- copy = *stmt;
- stmt->type = ST_EXPRESSION;
- stmt = CExcept_DtorTransform(stmt);
- stmt = CFunc_InsertStatement(copy.type, stmt);
- stmt->label = copy.label;
-
- if (flag2)
- stmt->expr = create_objectnode(tempObj);
- else
- stmt->expr = nullnode();
- } else {
- CExcept_DtorTransform(stmt);
- }
- }
-}
-
-static void CExcept_CleanupExceptionActions(Statement *stmt) {
- Statement *iter;
- ENode *expr;
- ExceptionAction *ea;
-
- cexcept_prevstmt = stmt;
- for (iter = stmt; iter; iter = iter->next) {
- cexcept_eabefore = cexcept_eaafter = ea = iter->dobjstack;
-
- if (iter->flags & StmtFlag_2) {
- cexcept_eabefore = ea->prev;
- } else if (iter->type == ST_EXPRESSION) {
- expr = iter->expr;
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.left;
- if (ENODE_IS(expr, EINDIRECT))
- expr = expr->data.monadic;
-
- if (
- ENODE_IS(expr, EFUNCCALL) &&
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- CClass_IsConstructor(expr->data.funccall.funcref->data.objref) &&
- iter->dobjstack &&
- iter->dobjstack->type == EAT_DESTROYLOCAL &&
- expr->data.funccall.args &&
- ENODE_IS(expr->data.funccall.args->node, EOBJREF) &&
- expr->data.funccall.args->node->data.objref == iter->dobjstack->data.destroy_local.local
- )
- cexcept_eabefore = cexcept_eabefore->prev;
- }
-
- switch (iter->type) {
- case ST_EXPRESSION:
- CExcept_TempTransform(iter, 1, 0);
- break;
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CExcept_TempTransform(iter, 0, 1);
- break;
- case ST_RETURN:
- if (iter->expr) {
- CExcept_TempTransform(
- iter,
- 0,
- CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) != 1
- );
- }
- break;
- }
-
- iter->dobjstack = cexcept_eabefore;
- cexcept_prevstmt = iter;
- }
-}
-
-static void CExcept_InsertSpecificationActions(Statement *stmt, ExceptSpecList *exspecs) {
- Statement *iter;
- Statement *last;
- ExceptionAction *ea_spec;
- ExceptionAction *ea;
- ExceptSpecList *spec_iter;
- SInt32 i;
- Object *catch_info_object;
- CLabel *label;
-
- ea_spec = lalloc(sizeof(ExceptionAction));
- memclrw(ea_spec, sizeof(ExceptionAction));
- ea_spec->type = EAT_SPECIFICATION;
-
- for (iter = stmt; iter; iter = iter->next) {
- if ((ea = iter->dobjstack)) {
- while (1) {
- if (ea->type == EAT_SPECIFICATION)
- break;
- if (ea->prev == NULL) {
- ea->prev = ea_spec;
- break;
- }
- ea = ea->prev;
- }
- } else {
- iter->dobjstack = ea_spec;
- }
- }
-
- last = stmt;
- while (last->next)
- last = last->next;
-
- if (last->type != ST_GOTO && last->type != ST_RETURN) {
- last = CFunc_InsertStatement(ST_RETURN, last);
- last->expr = NULL;
- last->dobjstack = NULL;
- if (TYPE_FUNC(cscope_currentfunc->type)->functype != &stvoid && (copts.pedantic || copts.cplusplus))
- CError_Warning(CErrorStr184);
- }
-
- last = CFunc_InsertStatement(ST_LABEL, last);
- last->label = newlabel();
- last->label->stmt = last;
- last->flags = StmtFlag_1;
- last->dobjstack = NULL;
-
- catch_info_object = create_temp_object(TYPE(&catchinfostruct));
-
- if (!exspecs->type)
- exspecs = NULL;
-
- i = 0;
- spec_iter = exspecs;
- while (spec_iter) {
- spec_iter = spec_iter->next;
- i++;
- }
-
- ea_spec->data.specification.unexp_ids = i;
- ea_spec->data.specification.unexp_id = galloc(sizeof(Object *) * i);
- ea_spec->data.specification.unexp_label = last->label;
- ea_spec->data.specification.unexp_info_object = catch_info_object;
-
- i = 0;
- while (exspecs) {
- ea_spec->data.specification.unexp_id[i] = CExcept_TypeID(exspecs->type, exspecs->qual);
- exspecs = exspecs->next;
- i++;
- }
-
- last = CFunc_InsertStatement(ST_EXPRESSION, last);
- last->expr = funccallexpr(Xunex_func, create_objectrefnode(catch_info_object), NULL, NULL, NULL);
-
- ea = lalloc(sizeof(ExceptionAction));
- memclrw(ea, sizeof(ExceptionAction));
- ea->type = EAT_ACTIVECATCHBLOCK;
- ea->data.active_catch_block.catch_info_object = catch_info_object;
- ea->data.active_catch_block.call_dtor = 1;
- last->dobjstack = ea;
-
- last = CFunc_InsertStatement(ST_LABEL, last);
- last->label = label = newlabel();
- last->label->stmt = last;
- last->dobjstack = NULL;
-
- last = CFunc_InsertStatement(ST_GOTO, last);
- last->label = label;
-}
-
-static void CExcept_HasFuncCallCallBack(ENode *expr) {
- ENode *funcref = expr->data.funccall.funcref;
- if (ENODE_IS(funcref, EOBJREF)) {
- Object *func = funcref->data.objref;
- if (CExcept_CanThrowException(func, func->datatype == DVFUNC && !(expr->flags & ENODE_FLAG_80)))
- cexcept_canthrow = 1;
- } else {
- cexcept_canthrow = 1;
- }
-}
-
-static Boolean CExcept_CanThrowCheck(Object *func, Statement *stmt) {
- cexcept_canthrow = 0;
-
- while (stmt) {
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_ASM:
- break;
- case ST_RETURN:
- if (!stmt->expr)
- break;
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- CExpr_SearchExprTree(stmt->expr, CExcept_HasFuncCallCallBack, 2, EFUNCCALL, EFUNCCALLP);
- break;
- default:
- CError_FATAL(2687);
- }
- stmt = stmt->next;
- }
-
- if (!cexcept_canthrow) {
- TYPE_FUNC(cscope_currentfunc->type)->flags |= FUNC_NOTHROW;
- return 0;
- } else {
- return 1;
- }
-}
-
-void CExcept_ExceptionTansform(Statement *stmt) {
- cexcept_uniqueobjs = NULL;
- CExcept_CleanupExceptionActions(stmt);
-
- if (cscope_currentfunc && CExcept_CanThrowCheck(cscope_currentfunc, stmt)) {
- CError_ASSERT(2716, IS_TYPE_FUNC(cscope_currentfunc->type));
- if (TYPE_FUNC(cscope_currentfunc->type)->exspecs && copts.exceptions)
- CExcept_InsertSpecificationActions(stmt, TYPE_FUNC(cscope_currentfunc->type)->exspecs);
- }
-}
diff --git a/compiler_and_linker/unsorted/CExpr.c b/compiler_and_linker/unsorted/CExpr.c
deleted file mode 100644
index 484f56d..0000000
--- a/compiler_and_linker/unsorted/CExpr.c
+++ /dev/null
@@ -1,4971 +0,0 @@
-#include "compiler/CExpr.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CIRTransform.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CInt64.h"
-#include "compiler/CObjC.h"
-#include "compiler/CObjCModern.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CRTTI.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PPCError.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-Boolean (*name_obj_check)(HashNameNode *, Object *);
-Boolean disallowgreaterthan;
-
-// forward declarations
-static ENode *makeaddnode(ENode *left, ENode *right);
-static ENode *makesubnode(ENode *left, ENode *right);
-
-ENode *CExpr_RewriteConst(ENode *expr) {
- Object *obj;
-
-restart:
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EOBJREF)) {
- obj = expr->data.monadic->data.objref;
- if (obj->datatype == DALIAS) {
- CExpr_AliasTransform(expr->data.monadic);
- goto restart;
- }
-
- if ((obj->qual & Q_INLINE_DATA) && expr->rtype == obj->type) {
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- expr->type = EINTCONST;
- expr->data.intval = obj->u.data.u.intconst;
- break;
- case TYPEPOINTER:
- expr->type = EINTCONST;
- expr->data.intval = obj->u.data.u.intconst;
- expr->rtype = TYPE(&stunsignedlong);
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = obj->type;
- break;
- case TYPEFLOAT:
- expr->type = EFLOATCONST;
- if (obj->u.data.u.floatconst)
- expr->data.floatval = *obj->u.data.u.floatconst;
- else
- expr->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), cint64_zero);
- break;
- default:
- CError_FATAL(105);
- }
- }
- }
-
- return expr;
-}
-
-void optimizecomm(ENode *expr) {
- ENode *right;
- ENode *left;
-
- if (ENODE_IS((right = expr->data.diadic.right), EINTCONST))
- return;
- if (ENODE_IS((left = expr->data.diadic.left), EINTCONST)) {
- swap:
- expr->data.diadic.right = left;
- expr->data.diadic.left = right;
- return;
- }
-
- if (ENODE_IS(left, EFLOATCONST))
- return;
- if (ENODE_IS(right, EFLOATCONST))
- goto swap;
-
- if (expr->rtype->type > TYPEFLOAT)
- return;
-
- if (left->cost > right->cost)
- goto swap;
-}
-
-static void checkadditive(ENode *expr) {
- switch (expr->rtype->type) {
- case TYPEINT:
- if (expr->rtype == TYPE(&stbool))
- break;
- case TYPEFLOAT:
- return;
- case TYPEENUM:
- if (copts.cplusplus)
- break;
- return;
- case TYPEPOINTER:
- if (TPTR_TARGET(expr->rtype)->size == 0)
- CDecl_CompleteType(TPTR_TARGET(expr->rtype));
- if (TPTR_TARGET(expr->rtype)->size == 0)
- break;
- return;
- case TYPEARRAY:
- if (ENODE_IS(expr, EOBJREF))
- return;
- }
-
- CError_Error(CErrorStr376, expr->rtype, ENODE_QUALS(expr));
-}
-
-static void CExpr_CompareConvert(ENode **leftp, char *opname, ENode **rightp, Boolean flag) {
- ENode *left;
- ENode *right;
- CInt64 val;
-
- left = *leftp;
- right = *rightp;
-
- switch (left->rtype->type) {
- case TYPEINT:
- break;
- case TYPEFLOAT:
- if (left->rtype != right->rtype)
- CExpr_ArithmeticConversion(leftp, rightp);
- return;
- case TYPEENUM:
- left->rtype = TYPE_ENUM(left->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr377,
- left->rtype, ENODE_QUALS(left),
- opname,
- right->rtype, ENODE_QUALS(right));
- left = nullnode();
- }
-
- switch (right->rtype->type) {
- case TYPEINT:
- break;
- case TYPEFLOAT:
- CExpr_ArithmeticConversion(leftp, rightp);
- return;
- case TYPEENUM:
- right->rtype = TYPE_ENUM(right->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr377,
- left->rtype, ENODE_QUALS(left),
- opname,
- right->rtype, ENODE_QUALS(right));
- right = nullnode();
- }
-
- if (left->rtype == right->rtype) {
- *leftp = left;
- *rightp = right;
- return;
- }
-
- if (left->rtype->size == right->rtype->size) {
- if (is_unsigned(left->rtype) == is_unsigned(right->rtype)) {
- left->rtype = right->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- } else {
- if (ENODE_IS(right, EINTCONST) && left->rtype->size <= right->rtype->size && (is_unsigned(left->rtype) == is_unsigned(right->rtype) || is_unsigned(left->rtype))) {
- val = CMach_CalcIntDiadic(left->rtype, right->data.intval, '+', cint64_zero);
- val = CMach_CalcIntDiadic(right->rtype, val, '+', cint64_zero);
- if (CInt64_Equal(val, right->data.intval)) {
- right->rtype = left->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- }
-
- if (ENODE_IS(left, EINTCONST) && left->rtype->size >= right->rtype->size && (is_unsigned(left->rtype) == is_unsigned(right->rtype) || is_unsigned(right->rtype))) {
- val = CMach_CalcIntDiadic(right->rtype, left->data.intval, '+', cint64_zero);
- val = CMach_CalcIntDiadic(left->rtype, val, '+', cint64_zero);
- if (CInt64_Equal(val, left->data.intval)) {
- left->rtype = right->rtype;
- *leftp = left;
- *rightp = right;
- return;
- }
- }
- }
-
- *leftp = left;
- *rightp = right;
- CExpr_ArithmeticConversion(leftp, rightp);
-}
-
-static ENode *CExpr_ConstResult(ENode *expr, SInt32 value) {
- ENode *constnode;
-
- if (IS_TYPE_FLOAT(expr->rtype)) {
- constnode = intconstnode(TYPE(&stsignedint), value);
- constnode->type = EFLOATCONST;
- constnode->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedint), constnode->data.intval);
- constnode->rtype = expr->rtype;
- } else {
- constnode = intconstnode(expr->rtype, value);
- }
-
- if (CInline_ExpressionHasSideEffect(expr))
- return makediadicnode(expr, constnode, ECOMMA);
- else
- return constnode;
-}
-
-static ENode *makemultnode(ENode *left, ENode *right) {
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(left))
- return CExpr_ConstResult(right, 0);
- if (iszero(right))
- return CExpr_ConstResult(left, 0);
-
- if (CExpr_IsOne(right))
- return left;
- if (CExpr_IsOne(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '*', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '*', right->data.floatval);
- return left;
- }
-
- left = makediadicnode(left, right, EMUL);
- optimizecomm(left);
- if (IS_TYPE_INT(left->rtype) && left->rtype->size > 2) {
- left->cost++;
- if (left->cost > 200)
- left->cost = 200;
- }
-
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
-
- return left;
-}
-
-static ENode *makedivnode(ENode *left, ENode *right, Boolean no_warning) {
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right) && IS_TYPE_INT(right->rtype)) {
- if (!no_warning)
- CError_Warning(CErrorStr139);
- return right;
- }
-
- if (CExpr_IsOne(right))
- return left;
-
- if (iszero(left) && IS_TYPE_INT(left->rtype))
- return CExpr_ConstResult(right, 0);
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '/', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '/', right->data.floatval);
- return left;
- }
-
- left = makediadicnode(left, right, EDIV);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
-
- return left;
-}
-
-static short canadd2(ENode *expr, CInt64 value) {
- Float tmp;
-
- if (CInt64_IsZero(&value))
- return 1;
-
- switch (expr->type) {
- case EINTCONST:
- expr->data.intval = CMach_CalcIntDiadic(expr->rtype, expr->data.intval, '+', value);
- return 1;
- case EFLOATCONST:
- tmp = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), value);
- expr->data.floatval = CMach_CalcFloatDiadic(expr->rtype, expr->data.floatval, '+', tmp);
- return 1;
- case EADD:
- if (canadd2(expr->data.diadic.left, value))
- return 1;
- if (canadd2(expr->data.diadic.right, value))
- return 1;
- return 0;
- case ESUB:
- if (canadd2(expr->data.diadic.left, value))
- return 1;
- if (canadd2(expr->data.diadic.right, CInt64_Neg(value)))
- return 1;
- return 0;
- case ETYPCON:
- if (IS_TYPE_POINTER_ONLY(expr->rtype) && ENODE_IS(expr->data.monadic, EINTCONST)) {
- expr->data.monadic->data.intval = CMach_CalcIntDiadic(TYPE(&stunsignedlong), expr->data.monadic->data.intval, '+', value);
- return 1;
- }
- return 0;
- default:
- return 0;
- }
-}
-
-short canadd(ENode *expr, SInt32 value) {
- CInt64 value64;
- CInt64_SetLong(&value64, value);
- return canadd2(expr, value64);
-}
-
-static ENode *addconst(ENode *expr, SInt32 value) {
- ENode *right;
-
- if (canadd(expr, value))
- return expr;
-
- if (stsignedint.size < 4 && (value > 0x7FFF || value < -0x8000))
- right = intconstnode(TYPE(&stsignedlong), value);
- else
- right = intconstnode(TYPE(&stsignedint), value);
-
- CExpr_ArithmeticConversion(&expr, &right);
- expr = makediadicnode(expr, right, EADD);
- return expr;
-}
-
-static ENode *integralpointerpromote(ENode *expr) {
- Boolean uns;
- Type *type;
-
- if (!IS_TYPE_INT(expr->rtype))
- expr = forceintegral(expr);
-
- if (expr->rtype->size != 4) {
- type = TYPE(&stunsignedlong);
- if (is_unsigned(type) != (uns = is_unsigned(expr->rtype))) {
- if (uns) {
- if (stunsignedlong.size == 4) {
- type = TYPE(&stunsignedlong);
- } else if (stunsignedint.size == 4) {
- type = TYPE(&stunsignedint);
- } else {
- CError_FATAL(480);
- }
- } else {
- if (stsignedlong.size == 4) {
- type = TYPE(&stsignedlong);
- } else if (stsignedint.size == 4) {
- type = TYPE(&stsignedint);
- } else {
- CError_FATAL(486);
- }
- }
- }
-
- if (ENODE_IS(expr, EINTCONST))
- expr->data.intval = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval);
- else
- expr = makemonadicnode(expr, ETYPCON);
-
- expr->rtype = type;
- }
-
- return expr;
-}
-
-static ENode *padd(ENode *left, ENode *right) {
- Type *innertype;
- SInt32 innersize;
- ENode *expr;
-
- right = integralpointerpromote(right);
- innertype = TPTR_TARGET(left->rtype);
- innersize = innertype->size;
- if (innersize == 0) {
- CDecl_CompleteType(innertype);
- innersize = innertype->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- expr = makemultnode(
- right,
- intconstnode((innersize > 0x7FFF) ? TYPE(&stsignedlong) : TYPE(&stsignedint), innersize));
-
- if (ENODE_IS(expr, EINTCONST) && canadd2(left, expr->data.intval))
- return left;
-
- if (ENODE_IS(left, EADD) && ENODE_IS(left->data.diadic.right, EINTCONST)) {
- left->data.diadic.left = makediadicnode(left->data.diadic.left, expr, EADD);
- return left;
- }
-
- expr = makediadicnode(left, expr, EADD);
- expr->rtype = left->rtype;
- expr->flags = left->flags;
- return expr;
-}
-
-static ENode *psub(ENode *left, ENode *right) {
- Type *innertype;
- SInt32 innersize;
- ENode *expr;
-
- if (IS_TYPE_POINTER(right->rtype)) {
- innersize = TPTR_TARGET(left->rtype)->size;
- if (innersize == 0) {
- CDecl_CompleteType(TPTR_TARGET(left->rtype));
- innersize = TPTR_TARGET(left->rtype)->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- if (!is_typeequal(left->rtype, right->rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- return left;
- }
-
- if (ENODE_IS(left, ETYPCON) && ENODE_IS(left->data.monadic, EINTCONST) && ENODE_IS(right, ETYPCON) && ENODE_IS(right->data.monadic, EINTCONST)) {
- left->data.monadic->rtype = right->data.monadic->rtype = CABI_GetPtrDiffTType();
- expr = makesubnode(left->data.monadic, right->data.monadic);
- if (innersize > 1)
- expr = makedivnode(expr, intconstnode(CABI_GetPtrDiffTType(), innersize), 11);
- return expr;
- }
-
- expr = makediadicnode(left, right, ESUB);
- expr->rtype = CABI_GetPtrDiffTType();
- if (innersize > 1)
- expr = makediadicnode(expr, intconstnode(CABI_GetPtrDiffTType(), innersize), EDIV);
- return expr;
- }
-
- right = integralpointerpromote(right);
- innertype = TPTR_TARGET(left->rtype);
- innersize = innertype->size;
- if (innersize == 0) {
- CDecl_CompleteType(innertype);
- innersize = innertype->size;
- if (innersize == 0) {
- CError_Error(CErrorStr146);
- return left;
- }
- }
-
- expr = makemultnode(right, intconstnode(CABI_GetPtrDiffTType(), innersize));
- if (ENODE_IS(expr, EINTCONST) && canadd2(left, CInt64_Neg(expr->data.intval)))
- return left;
-
- expr = makediadicnode(left, expr, ESUB);
- expr->rtype = left->rtype;
- expr->flags = left->flags;
- return expr;
-}
-
-static ENode *makeaddnode(ENode *left, ENode *right) {
- if (IS_TYPE_POINTER(left->rtype))
- return padd(left, right);
- if (IS_TYPE_POINTER(right->rtype))
- return padd(right, left);
-
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right))
- return left;
- if (iszero(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '+', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '+', right->data.floatval);
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && canadd2(right, left->data.intval))
- return right;
- if (ENODE_IS(right, EINTCONST) && canadd2(left, right->data.intval))
- return left;
-
- left = makediadicnode(left, right, EADD);
- optimizecomm(left);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
- return left;
-}
-
-static ENode *makesubnode(ENode *left, ENode *right) {
- if (ENODE_IS(right, EINTCONST) && !is_unsigned(right->rtype) && !IS_TYPE_FLOAT(left->rtype)) {
- right->data.intval = CInt64_Neg(right->data.intval);
- return makeaddnode(left, right);
- }
-
- if (IS_TYPE_POINTER(left->rtype))
- return psub(left, right);
-
- CExpr_ArithmeticConversion(&left, &right);
- if (iszero(right))
- return left;
- if (iszero(left)) {
- if (ENODE_IS(right, EINTCONST)) {
- right->data.intval = CInt64_Neg(right->data.intval);
- return right;
- }
- if (ENODE_IS(right, EFLOATCONST)) {
- right->data.floatval = CMach_CalcFloatMonadic(right->rtype, '-', right->data.floatval);
- return right;
- }
- return CExpr_UnaryFloatExpression(makemonadicnode(right, EMONMIN));
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '-', right->data.intval);
- return left;
- }
- if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->data.floatval = CMach_CalcFloatDiadic(left->rtype, left->data.floatval, '-', right->data.floatval);
- return left;
- }
-
- if (ENODE_IS(right, EINTCONST) && canadd2(left, CInt64_Neg(right->data.intval)))
- return left;
-
- left = makediadicnode(left, right, ESUB);
- if (IS_TYPE_FLOAT(left->rtype))
- left = CExpr_BinaryFloatExpression(left);
- return left;
-}
-
-ENode *checkreference(ENode *expr) {
- if (!IS_TYPE_REFERENCE(expr->rtype))
- return expr;
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- return expr;
-}
-
-static ENode *pointer_generation2(ENode *expr) {
- switch (expr->type) {
- case EINDIRECT:
- switch (expr->rtype->type) {
- case TYPEARRAY:
- switch (expr->data.monadic->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- expr->type = ETYPCON;
- expr->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- return expr;
- default:
- expr->data.monadic->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- expr->data.monadic->flags = expr->flags;
- return expr->data.monadic;
- }
- case TYPEFUNC:
- expr = expr->data.monadic;
- if (ENODE_IS(expr, EOBJREF) && expr->data.objref->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- return expr;
- }
- }
- return expr;
-}
-
-ENode *pointer_generation(ENode *expr) {
- return CExpr_RewriteConst(pointer_generation2(expr));
-}
-
-ENode *CExpr_PointerGeneration(ENode *expr) {
- switch (expr->type) {
- case EINDIRECT:
- switch (expr->rtype->type) {
- case TYPEARRAY:
- expr->data.monadic->rtype = CDecl_NewPointerType(TPTR_TARGET(expr->rtype));
- return expr->data.monadic;
- case TYPEFUNC:
- return expr->data.monadic;
- }
- }
- return expr;
-}
-
-static void CExpr_ConstPointerCheck(ENode *expr, Type *type, short qual) {
- Type *exprtype;
- Type *b;
- Type *a;
- short exprqual;
-
- exprtype = expr->rtype;
- if (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_POINTER_ONLY(exprtype)) {
- exprqual = expr->flags;
-
- if (TPTR_TARGET(type) == &stvoid) {
- exprqual = CParser_GetCVTypeQualifiers(TPTR_TARGET(exprtype), exprqual);
- } else {
- a = TPTR_TARGET(type);
- b = TPTR_TARGET(exprtype);
- while (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b)) {
- if (CParser_IsMoreCVQualified(TPTR_QUAL(b), TPTR_QUAL(a))) {
- CError_Warning(CErrorStr220, expr->rtype, ENODE_QUALS(expr), type, qual);
- return;
- }
- a = TPTR_TARGET(a);
- b = TPTR_TARGET(b);
- }
- }
-
- if (CParser_IsMoreCVQualified(exprqual, qual)) {
- CError_Warning(CErrorStr220, expr->rtype, ENODE_QUALS(expr), type, (UInt32) qual);
- }
- }
-}
-
-ENode *oldassignmentpromotion(ENode *expr, Type *type, short qual, Boolean flag) {
- Boolean is_ref;
- UInt32 ref_qual;
- short orig_qual;
-
- is_ref = 0;
- if (!IS_TYPE_MEMBERPOINTER(type)) {
- if (IS_TYPE_REFERENCE(type)) {
- if (ENODE_IS(expr, ECOND))
- expr = CExpr_LValue(expr, 0, 0);
- expr = pointer_generation2(expr);
- ref_qual = CParser_GetCVTypeQualifiers(expr->rtype, expr->flags);
- is_ref = 1;
- } else {
- expr = pointer_generation(expr);
- }
- }
-
- if (ENODE_IS(expr, EMEMBER))
- expr = getpointertomemberfunc(expr, type, 1);
-
- if (!is_ref)
- CExpr_ConstPointerCheck(expr, type, qual);
- else
- CExpr_ConstPointerCheck(expr, TPTR_TARGET(type), qual);
-
- if (!(assign_check(expr, type, orig_qual = qual, 1, 0, flag)))
- return expr;
-
- if (is_ref) {
- if (temp_reference_init) {
- switch (TPTR_TARGET(type)->type) {
- case TYPEPOINTER:
- qual = TPTR_QUAL(TPTR_TARGET(type));
- }
- if (!(qual & Q_CONST))
- CError_Warning(CErrorStr228);
- } else {
- if (ref_qual && ref_qual > CParser_GetCVTypeQualifiers(TPTR_TARGET(type), orig_qual))
- CError_Warning(CErrorStr259);
- }
- }
-
- return assign_node;
-}
-
-ENode *argumentpromotion(ENode *expr, Type *type, short qual, Boolean flag) {
- ENode *tmp;
- ENodeList *list;
-
- if (IS_TYPE_CLASS(type) && CClass_ReferenceArgument(TYPE_CLASS(type))) {
- if ((tmp = CExpr_IsTempConstruction(expr, type, NULL)))
- return tmp;
-
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- list->node = expr;
- tmp = CExpr_ConstructObject(
- TYPE_CLASS(type),
- create_temp_node(type),
- list, 1, 1, 1, 1, 0);
- return getnodeaddress(tmp, 0);
- }
-
- return CExpr_AssignmentPromotion(expr, type, qual, flag);
-}
-
-ENode *classargument(ENode *expr) {
- ENodeList *list;
-
- if (CClass_CopyConstructor(TYPE_CLASS(expr->rtype))) {
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- list->node = expr;
- return CExpr_ConstructObject(
- TYPE_CLASS(expr->rtype),
- create_temp_node(expr->rtype),
- list, 1, 1, 1, 1, 0);
- }
-
- return expr;
-}
-
-ENodeList *CExpr_ScanExpressionList(Boolean is_parens) {
- ENodeList *list;
- ENodeList *current;
-
- if (is_parens && tk == ')')
- return NULL;
-
- list = current = lalloc(sizeof(ENodeList));
-
- while (1) {
- current->next = NULL;
- current->node = assignment_expression();
- if (copts.old_argmatch && !ENODE_IS(current->node, EMEMBER))
- current->node = pointer_generation(current->node);
-
- if (is_parens) {
- if (tk == ')')
- break;
- } else {
- if (tk == ']')
- break;
- }
-
- if (tk != ',') {
- CError_ErrorSkip(CErrorStr116);
- break;
- }
-
- tk = lex();
- current->next = lalloc(sizeof(ENodeList));
- current = current->next;
- }
-
- return list;
-}
-
-static ENode *skipcommaexpr(ENode *expr) {
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.right;
- return expr;
-}
-
-ENode *CExpr_DoExplicitConversion(Type *type, UInt32 qual, ENodeList *list) {
- Object *obj;
- ENode *tmp;
-
- if (!IS_TYPE_CLASS(type)) {
- if (!list)
- return do_typecast(nullnode(), type, qual);
- if (list->next)
- CError_Error(CErrorStr356);
- return do_typecast(pointer_generation(list->node), type, qual);
- }
-
- CDecl_CompleteType(type);
- if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, type, 0);
-
- CanCreateObject(type);
- if (!list && CClass_IsPODClass(TYPE_CLASS(type))) {
- obj = CParser_NewGlobalDataObject(NULL);
- obj->name = CParser_GetUniqueName();
- obj->nspace = cscope_root;
- obj->type = type;
- obj->qual = qual;
- obj->sclass = TK_STATIC;
- CInit_DeclareData(obj, NULL, NULL, type->size);
-
- tmp = makemonadicnode(create_temp_node(type), EINDIRECT);
- tmp->rtype = type;
- tmp->flags = qual & ENODE_FLAG_QUALS;
- return makediadicnode(tmp, create_objectnode(obj), EASS);
- }
-
- return CExpr_ConstructObject(TYPE_CLASS(type), create_temp_node(type), list, 1, 1, 1, 1, 1);
-}
-
-static ENode *CExpr_TemplArgDepCast(Type *type, UInt32 qual, ENodeList *args) {
- ENode *expr = CExpr_NewTemplDepENode(TDE_CAST);
- expr->data.templdep.u.cast.args = args;
- expr->data.templdep.u.cast.type = type;
- expr->data.templdep.u.cast.qual = qual;
- return expr;
-}
-
-static ENode *CExpr_ParseExplicitConversion(Type *type, UInt32 qual) {
- ENodeList *args;
- ENodeList *scan;
-
- if (IS_TEMPL_CLASS(type) && !CParser_CheckTemplateClassUsage(TEMPL_CLASS(type), 1))
- type = TYPE(&stsignedint);
-
- if (tk == '(')
- tk = lex();
- else
- CError_Error(CErrorStr114);
-
- args = CExpr_ScanExpressionList(1);
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- tk = lex();
- if (CTemplTool_IsTemplateArgumentDependentType(type))
- return CExpr_TemplArgDepCast(type, qual, args);
-
- for (scan = args; scan; scan = scan->next) {
- if (CTemplTool_IsTemplateArgumentDependentExpression(scan->node))
- return CExpr_TemplArgDepCast(type, qual, args);
- }
-
- return CExpr_DoExplicitConversion(type, qual, args);
-}
-
-static ENode *CExpr_MemberVarAccess(BClassList *path, ObjMemberVar *var, ENode *expr) {
- ENode *accessnode;
- BClassList *varpath;
-
- CError_ASSERT(1152, path);
-
- if (TYPE_CLASS(path->type)->sominfo)
- return CSOM_MemberVarAccess(path, var, expr);
-
- varpath = NULL;
- if (var->has_path)
- varpath = OBJ_MEMBER_VAR_PATH(var)->path;
- accessnode = CExpr_GetClassAccessNode(path, varpath, expr, NULL, var->access, 1);
- if (!accessnode)
- return nullnode();
-
- return CClass_AccessMember(accessnode, var->type, var->qual, var->offset);
-}
-
-static Boolean CExpr_IsTemplateFunc(Object *obj) {
- return IS_TEMPL_FUNC(obj->type);
-}
-
-static ENode *CExpr_ExplicitTemplateArgCheck(NameResult *pr) {
- NameSpaceObjectList *list;
- NameSpaceObjectList *newhead;
- NameSpaceObjectList *newlist;
- ENode *expr;
-
- if (pr->obj_10) {
- if (pr->obj_10->otype != OT_OBJECT || !CExpr_IsTemplateFunc(OBJECT(pr->obj_10)))
- return NULL;
-
- list = lalloc(sizeof(NameSpaceObjectList));
- memclrw(list, sizeof(NameSpaceObjectList));
- list->object = pr->obj_10;
- } else if (pr->nsol_14) {
- for (list = pr->nsol_14; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && CExpr_IsTemplateFunc(OBJECT(list->object))) {
- newhead = newlist = galloc(sizeof(NameSpaceObjectList));
- *newlist = *list;
- newlist->next = NULL;
- while ((list = list->next)) {
- if (list->object->otype == OT_OBJECT && CExpr_IsTemplateFunc(OBJECT(list->object))) {
- newlist->next = galloc(sizeof(NameSpaceObjectList));
- newlist = newlist->next;
- *newlist = *list;
- newlist->next = NULL;
- }
- }
- list = newhead;
- break;
- }
- }
- if (!list)
- return NULL;
- } else {
- return NULL;
- }
-
- expr = CExpr_NewENode(EOBJLIST);
- expr->rtype = OBJECT(list->object)->type;
- expr->data.objlist.list = list;
- expr->data.objlist.templargs = CTempl_ParseUncheckTemplArgs(NULL, 0);
-
- tk = lex();
- return expr;
-}
-
-ENode *CExpr_MakeNameLookupResultExpr(NameResult *pr) {
- ENode *expr;
-
- if (pr->obj_10) {
- switch (pr->obj_10->otype) {
- case OT_OBJECT:
- CClass_CheckObjectAccess(pr->bcl_18, OBJECT(pr->obj_10));
- return create_objectnode(OBJECT(pr->obj_10));
- case OT_ENUMCONST:
- CClass_CheckEnumAccess(pr->bcl_18, OBJ_ENUM_CONST(pr->obj_10));
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = OBJ_ENUM_CONST(pr->obj_10)->type;
- expr->data.intval = OBJ_ENUM_CONST(pr->obj_10)->val;
- return expr;
- case OT_MEMBERVAR:
- CError_Error(CErrorStr221);
- return nullnode();
- default:
- CError_FATAL(1268);
- }
- }
-
- if (pr->nsol_14) {
- expr = CExpr_NewENode(EOBJLIST);
- expr->rtype = OBJECT(pr->nsol_14->object)->type;
- expr->data.objlist.list = pr->nsol_14;
- return expr;
- }
-
- CError_FATAL(1278);
- return NULL;
-}
-
-static Type *CExpr_NewPTMType(EMemberInfo *member, Object *obj) {
- TypeMemberPointer *ptm;
- TypeMemberFunc *tmethod;
- BClassList *path;
-
- ptm = galloc(sizeof(TypeMemberPointer));
- memclrw(ptm, sizeof(TypeMemberPointer));
- ptm->type = TYPEMEMBERPOINTER;
-
- if (member->list->object->otype == OT_MEMBERVAR) {
- path = member->path;
- while (path->next)
- path = path->next;
- ptm->size = 4;
- ptm->ty2 = path->type;
- ptm->ty1 = OBJ_MEMBER_VAR(member->list->object)->type;
- } else {
- if (!obj) {
- CError_ASSERT(1306, member->list->object->otype == OT_OBJECT);
- obj = OBJECT(member->list->object);
- CError_ASSERT(1308, IS_TYPE_FUNC(obj->type));
- }
-
- tmethod = galloc(sizeof(TypeMemberFunc));
- memclrw(tmethod, sizeof(TypeMemberFunc));
- *tmethod = *TYPE_METHOD(obj->type);
-
- CError_ASSERT(1312, tmethod->args);
-
- tmethod->args = tmethod->args->next;
- CDecl_MakePTMFuncType(TYPE_FUNC(tmethod));
- tmethod->flags &= ~FUNC_DEFINED;
-
- ptm->size = 12;
- ptm->ty2 = TYPE(tmethod->theclass);
- ptm->ty1 = TYPE(tmethod);
- }
-
- return TYPE(ptm);
-}
-
-static ENode *CExpr_ParseNameResultExpr(NameResult *pr, ENode *expr, Boolean flag1, Boolean flag2) {
- ENode *result;
- ENode *ta_expr;
- ObjEnumConst *oec;
- TemplateAction *act;
- EMemberInfo *member;
- NameSpaceObjectList *list;
- Object *obj;
- TypeFunc *tfunc;
- SInt32 val;
-
- if (pr->type) {
- if (copts.cplusplus) {
- if (IS_TYPE_TEMPLATE(pr->type)) {
- if (TYPE_TEMPLATE(pr->type)->dtype == TEMPLDEP_ARGUMENT && TYPE_TEMPLATE(pr->type)->u.pid.type == TPT_NONTYPE) {
- result = CExpr_NewTemplDepENode(TDE_PARAM);
- result->data.templdep.u.pid = TYPE_TEMPLATE(pr->type)->u.pid;
- tk = lex();
- return result;
- }
- if (TYPE_TEMPLATE(pr->type)->dtype == TEMPLDEP_QUALNAME && !pr->x20) {
- result = CExpr_NewTemplDepENode(TDE_QUALNAME);
- result->data.templdep.u.qual.type = TYPE_TEMPLATE(pr->type)->u.qual.type;
- result->data.templdep.u.qual.name = TYPE_TEMPLATE(pr->type)->u.qual.name;
- tk = lex();
- return result;
- }
- }
- tk = lex();
- return CExpr_ParseExplicitConversion(pr->type, pr->qual);
- }
- CError_ErrorSkip(CErrorStr141);
- tk = lex();
- return nullnode();
- }
-
- if (pr->obj_10) {
- switch (pr->obj_10->otype) {
- case OT_OBJECT:
- if (OBJECT(pr->obj_10)->nspace && OBJECT(pr->obj_10)->nspace->theclass && (OBJECT(pr->obj_10)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- result = CExpr_NewTemplDepENode(TDE_OBJ);
- result->data.templdep.u.obj = OBJECT(pr->obj_10);
- tk = lex();
- return result;
- }
- if (!expr || !IS_TEMPL_FUNC(OBJECT(pr->obj_10)->type)) {
- if (!IS_TYPE_NONSTATIC_METHOD(OBJECT(pr->obj_10)->type)) {
- tk = lex();
- if (tk == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr)))
- return ta_expr;
- if (OBJECT(pr->obj_10)->datatype == DLOCAL && OBJECT(pr->obj_10)->u.var.info->func != cscope_currentfunc) {
- CError_Error(CErrorStr330);
- return nullnode();
- }
- if (OBJECT(pr->obj_10)->datatype == DEXPR) {
- result = CInline_CopyExpression(OBJECT(pr->obj_10)->u.expr, CopyMode0);
- if (IS_TYPE_POINTER_ONLY(result->rtype) && ENODE_IS(result, EINTCONST)) {
- result = makemonadicnode(result, ETYPCON);
- result->data.monadic->rtype = TYPE(&stunsignedlong);
- }
- return result;
- }
- CClass_CheckObjectAccess(pr->bcl_18, OBJECT(pr->obj_10));
- if (tk == '(' && flag2 && OBJECT(pr->obj_10)->datatype == DFUNC && copts.cplusplus && !pr->x1D && !IS_TYPEFUNC_METHOD(TYPE_FUNC(OBJECT(pr->obj_10)->type))) {
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(pr->obj_10)->type;
- result->data.objlist.list = galloc(sizeof(NameSpaceObjectList));
- result->data.objlist.list->next = pr->nsol_14;
- result->data.objlist.list->object = pr->obj_10;
- result->data.objlist.name = OBJECT(pr->obj_10)->name;
- return result;
- }
-
- result = create_objectnode(OBJECT(pr->obj_10));
- if (expr) {
- while (ENODE_IS(expr, EINDIRECT))
- expr = expr->data.monadic;
- switch (expr->type) {
- case EINTCONST:
- case EOBJREF:
- case EOBJLIST:
- break;
- default:
- result = makecommaexpression(expr, result);
- }
- }
- return result;
- }
- if (CClass_IsDestructor(OBJECT(pr->obj_10))) {
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
- if (!expr && (!cscope_currentfunc || !cscope_currentclass || !cscope_is_member_func)) {
- CError_Error(CErrorStr221);
- return nullnode();
- }
- if (pr->isambig)
- CError_Error(CErrorStr188);
-
- if ((expr = CExpr_GetClassAccessNode(pr->bcl_18, NULL, expr, OBJECT(pr->obj_10), pr->obj_10->access, 1))) {
- tk = lex();
- return CABI_DestroyObject(OBJECT(pr->obj_10), expr->data.monadic, 1, pr->x1D, 0);
- }
- }
- }
- break;
- case OT_ENUMCONST:
- CClass_CheckEnumAccess(pr->bcl_18, OBJ_ENUM_CONST(pr->obj_10));
- oec = OBJ_ENUM_CONST(pr->obj_10);
- if (CInt64_IsZero(&oec->val) && IS_TYPE_ENUM(oec->type) && TYPE_ENUM(oec->type)->nspace && TYPE_ENUM(oec->type)->nspace->theclass && (TYPE_ENUM(oec->type)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- val = 0;
- expr = NULL;
- for (act = TEMPL_CLASS(TYPE_ENUM(oec->type)->nspace->theclass)->actions; act; act = act->next) {
- if (act->type == TAT_ENUMERATOR) {
- if (act->u.enumerator.initexpr) {
- expr = act->u.enumerator.initexpr;
- val = 0;
- } else {
- val++;
- }
- if (act->u.enumerator.objenumconst == oec) {
- CError_ASSERT(1521, expr);
- expr = CInline_CopyExpression(expr, CopyMode0);
- if (val)
- expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), val), EADD);
- tk = lex();
- return expr;
- }
- }
- }
- }
- result = lalloc(sizeof(ENode));
- result->type = EINTCONST;
- result->cost = 0;
- result->flags = 0;
- result->rtype = OBJ_ENUM_CONST(pr->obj_10)->type;
- result->data.intval = OBJ_ENUM_CONST(pr->obj_10)->val;
- tk = lex();
- return result;
- case OT_MEMBERVAR:
- if (!flag1 || expr || !pr->x1D) {
- if (pr->isambig)
- CError_Error(CErrorStr188);
- result = checkreference(CExpr_MemberVarAccess(pr->bcl_18, OBJ_MEMBER_VAR(pr->obj_10), expr));
- tk = lex();
- return result;
- }
- break;
- default:
- CError_FATAL(1552);
- }
-
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
- member->path = pr->bcl_18;
- member->expr = expr;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
- if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) {
- CError_ASSERT(1564, ENODE_IS(ta_expr, EOBJLIST));
- member->list = ta_expr->data.objlist.list;
- member->templargs = ta_expr->data.objlist.templargs;
- } else {
- member->list = galloc(sizeof(NameSpaceObjectList));
- member->list->next = NULL;
- member->list->object = pr->obj_10;
- }
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
-
- if (pr->nsol_14) {
- if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) {
- CError_ASSERT(1591, ENODE_IS(ta_expr, EOBJLIST));
- for (list = ta_expr->data.objlist.list; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(OBJECT(list->object)->type)) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
-
- member->path = pr->bcl_18;
- member->expr = expr;
- member->list = ta_expr->data.objlist.list;
- member->templargs = ta_expr->data.objlist.templargs;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
- }
- return ta_expr;
- }
-
- for (list = pr->nsol_14; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(OBJECT(list->object)->type)) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
-
- member->path = pr->bcl_18;
- member->expr = expr;
- member->list = pr->nsol_14;
- member->pr_1D = pr->x1D;
- member->isambig = pr->isambig;
-
- result = CExpr_NewENode(EMEMBER);
- result->data.emember = member;
- result->rtype = &stvoid;
- return result;
- }
- }
-
- if (tk == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr)))
- return ta_expr;
-
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(pr->nsol_14->object)->type;
- result->data.objlist.list = pr->nsol_14;
- if (tk == '(' && copts.cplusplus && flag2 && !pr->x1D && pr->nsol_14->object->otype == OT_OBJECT)
- result->data.objlist.name = OBJECT(pr->nsol_14->object)->name;
- return result;
- }
-
- if (pr->name_4) {
- if (copts.cplusplus && flag2) {
- if (lookahead() == '(') {
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = &stvoid;
- result->data.objlist.name = pr->name_4;
- tk = lex();
- return result;
- }
- CError_Error(CErrorStr140, pr->name_4->name);
- tk = lex();
- return nullnode();
- }
-
- if (lookahead() != '(') {
- CError_Error(CErrorStr140, pr->name_4->name);
- tk = lex();
- return nullnode();
- }
-
- if (copts.checkprotos)
- CError_Error(CErrorStr178);
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = TYPE(&stsignedint);
- tfunc->args = &oldstyle;
- CDecl_SetFuncFlags(tfunc, 0);
-
- obj = CParser_NewFunctionObject(NULL);
- obj->name = pr->name_4;
- obj->sclass = TK_EXTERN;
- obj->nspace = cscope_root;
- obj->type = TYPE(tfunc);
-
- CScope_AddGlobalObject(obj);
- tk = lex();
- return create_objectrefnode(obj);
- }
-
- CError_FATAL(1711);
- return NULL;
-}
-
-static ENode *CExpr_ParseRotate(Boolean is_right) {
- ENode *expr1;
- ENode *expr2;
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
-
- tk = lex();
- expr1 = assignment_expression();
-
- if (tk != ',') {
- CError_Error(CErrorStr116);
- return nullnode();
- }
-
- tk = lex();
- expr2 = assignment_expression();
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- if (!IS_TYPE_INT(expr1->rtype))
- expr1 = forceintegral(expr1);
- expr2 = integralpromote(expr2);
-
- tk = lex();
- if (iszero(expr1) || iszero(expr2))
- return expr1;
-
- return makediadicnode(expr1, expr2, is_right ? EROTR : EROTL);
-}
-
-static ENode *CExpr_ParseNextArg(void) {
- NameSpaceObjectList *list;
- NameResult pr;
- ENode *expr;
- SInt32 rounded_size;
-
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return nullnode();
- }
-
- list = CScope_FindObjectList(&pr, tkidentifier);
- if (!list) {
- CError_Error(CErrorStr140, tkidentifier->name);
- return nullnode();
- }
-
- if (list->object->otype != OT_OBJECT || OBJECT(list->object)->datatype != DLOCAL) {
- CError_Error(CErrorStr140, tkidentifier->name);
- return nullnode();
- }
-
- rounded_size = CMach_RoundedSizeOf(OBJECT(list->object));
- expr = CExpr_MakeObjRefNode(OBJECT(list->object), 1);
- expr = makediadicnode(expr, intconstnode(CABI_GetPtrDiffTType(), rounded_size), EADD);
- expr->rtype = TYPE(&void_ptr);
-
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- return expr;
- } else {
- tk = lex();
- return expr;
- }
-}
-
-static ENode *CExpr_ParseVecStep(void) {
- ENode *expr;
- Type *type;
- SInt32 value;
- DeclInfo di;
-
- expr = intconstnode(TYPE(&stsignedint), 0);
- if ((tk = lex()) == '(') {
- if (tk == '(' && islookaheaddeclaration()) {
- tk = lex();
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr121);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- type = di.thetype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
- } else {
- expr = unary_expression();
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EBITFIELD))
- CError_Error(CErrorStr144);
- type = expr->rtype;
- }
-
- CDecl_CompleteType(type);
- if (IS_TYPE_VECTOR(type)) {
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- value = 16;
- break;
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- value = 8;
- break;
- default:
- value = 4;
- }
- expr = intconstnode(TYPE(&stsignedint), value);
- } else {
- PPCError_Error(PPCErrorStr104, "vec_step", "vec_step", type, 0);
- }
- } else {
- CError_Error(CErrorStr114);
- }
-
- return expr;
-}
-
-static SInt32 CExpr_BuiltInComputeAlign(Type *type) {
- return CMach_GetTypeAlign(type);
-}
-
-static SInt32 CExpr_AtomTypeID(IntegralType what) {
- switch (what) {
- case IT_BOOL: return 1;
- case IT_CHAR: return 2;
- case IT_SCHAR: return 3;
- case IT_UCHAR: return 4;
- case IT_WCHAR_T: return 5;
- case IT_SHORT: return 6;
- case IT_USHORT: return 7;
- case IT_INT: return 8;
- case IT_UINT: return 9;
- case IT_LONG: return 10;
- case IT_ULONG: return 10;
- case IT_LONGLONG: return 12;
- case IT_ULONGLONG: return 13;
- case IT_FLOAT: return 14;
- case IT_SHORTDOUBLE: return 15;
- case IT_DOUBLE: return 16;
- case IT_LONGDOUBLE: return 17;
- case IT_17: return 32;
- case IT_18: return 33;
- case IT_19: return 34;
- case IT_20: return 35;
- case IT_21: return 36;
- case IT_22: return 37;
- case IT_23: return 38;
- case IT_24: return 39;
- default:
- CError_FATAL(1976);
- return 0;
- }
-}
-
-static SInt32 CExpr_BuiltInComputeType(Type *type) {
- switch (type->type) {
- case TYPEINT:
- return 0x100 | CExpr_AtomTypeID(TYPE_INTEGRAL(type)->integral);
- case TYPEFLOAT:
- return 0x200 | CExpr_AtomTypeID(TYPE_INTEGRAL(type)->integral);
- case TYPEENUM:
- return 0x400 | (CExpr_BuiltInComputeType(TYPE_ENUM(type)->enumtype) & 0xFF);
- case TYPEPOINTER:
- return 0x800;
- case TYPEARRAY:
- return 0x1000;
- case TYPESTRUCT:
- return 0x2000;
- case TYPECLASS:
- return 0x2000;
- case TYPEMEMBERPOINTER:
- return 0x4000;
- case TYPEFUNC:
- return 0x8000;
- default:
- CError_Error(CErrorStr146);
- case TYPEVOID:
- return 0;
- }
-}
-
-static SInt32 CExpr_BuiltInClassifyType(Type *type) {
- switch (type->type) {
- case TYPEVOID: return 0;
- case TYPEFUNC: return 10;
- case TYPEENUM: return 3;
- case TYPEINT: return 1;
- case TYPEFLOAT: return 8;
- case TYPEPOINTER: case TYPEMEMBERPOINTER: return 5;
- case TYPEARRAY: return 14;
- case TYPESTRUCT: return 12;
- case TYPECLASS: return 12;
- case TYPEBITFIELD: return -1;
- case TYPETEMPLATE: return -1;
- default: return -1;
- }
-}
-
-static SInt32 CExpr_BuiltInComputeVArgType(Type *type) {
- switch (type->type) {
- case TYPEINT:
- case TYPEENUM:
- return 0;
- case TYPEFLOAT:
- return 1;
- default:
- return 2;
- }
-}
-
-static Type *CExpr_ParseTypeExpression(Boolean *outflag) {
- ENode *expr;
- Type *type;
- DeclInfo di;
-
- tk = lex();
- if (tk == '(' && islookaheaddeclaration()) {
- tk = lex();
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr121);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- type = di.thetype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
- } else {
- expr = unary_expression();
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EBITFIELD))
- CError_Error(CErrorStr144);
-
- if (outflag)
- *outflag = ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval);
-
- type = expr->rtype;
- }
-
- CDecl_CompleteType(type);
- return type;
-}
-
-static ENode *CExpr_ParseBuiltin(SInt32 (*parser)(Type *)) {
- ENode *expr;
- expr = intconstnode(TYPE(&stsignedint), 0);
- CInt64_SetLong(&expr->data.intval, parser(CExpr_ParseTypeExpression(NULL)));
- return expr;
-}
-
-static ENode *CExpr_ParseBuiltin_isintconst(void) {
- ENode *expr;
- expr = intconstnode(TYPE(&stsignedint), 0);
-
- tk = lex();
- if (tk != '(')
- CError_ErrorSkip(CErrorStr121);
- else
- tk = lex();
-
- if (ENODE_IS(expression(), EINTCONST))
- CInt64_SetLong(&expr->data.intval, 1);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- return expr;
-}
-
-static ENode *primary_expression(Boolean flag) {
- NameResult pr;
- ENode *expr;
-
- switch (tk) {
- case TK_TRUE:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&stbool);
- CInt64_SetULong(&expr->data.intval, 1);
- tk = lex();
- return expr;
- case TK_FALSE:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&stbool);
- CInt64_SetULong(&expr->data.intval, 0);
- tk = lex();
- return expr;
- case TK_INTCONST:
- expr = lalloc(sizeof(ENode));
- expr->type = EINTCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = atomtype();
- expr->data.intval = tkintconst;
- tk = lex();
- return expr;
- case TK_FLOATCONST:
- expr = lalloc(sizeof(ENode));
- expr->type = EFLOATCONST;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = atomtype();
- expr->data.floatval = tkfloatconst;
- tk = lex();
- return expr;
- case TK_STRING:
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewArrayType(ispascalstring ? TYPE(&stunsignedchar) : TYPE(&stchar), tksize);
- expr->data.string.size = tksize;
- expr->data.string.data = tkstring;
- expr->data.string.ispascal = ispascalstring;
- if (copts.const_strings)
- expr->flags = ENODE_FLAG_CONST;
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- tk = lex();
- return expr;
- case TK_STRING_WIDE:
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewArrayType(CParser_GetWCharType(), tksize);
- expr->data.string.size = tksize;
- expr->data.string.data = tkstring;
- expr->data.string.ispascal = ispascalstring;
- if (copts.const_strings)
- expr->flags = ENODE_FLAG_CONST;
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- tk = lex();
- return expr;
- case TK_THIS:
- case TK_SELF:
- expr = CClass_CreateThisSelfExpr();
- if (!expr)
- expr = nullnode();
- tk = lex();
- return expr;
- case TK_AT_SELECTOR:
- return CObjC_ParseSelectorExpression();
- case TK_AT_ENCODE:
- return CObjC_ParseEncodeExpression();
- case TK_AT_PROTOCOL:
- return CObjC_ParseProtocolExpression();
- case '@':
- if (copts.objective_c)
- return CObjC_ParseAtExpression();
- break;
- case '(':
- tk = lex();
- expr = s_expression();
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
- if (ENODE_IS(expr, EASS))
- expr->flags = expr->flags | ENODE_FLAG_80;
- return expr;
- case '[':
- if (copts.objective_c)
- return CObjC_ParseMessageExpression();
- break;
- case TK_IDENTIFIER:
- if (tkidentifier->name[0] == '_' && tkidentifier->name[1] == '_') {
- if (!strcmp(tkidentifier->name, "__builtin_align"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeAlign);
- if (!strcmp(tkidentifier->name, "__builtin_ntype"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeType);
- if (!strcmp(tkidentifier->name, "__builtin_type") || !strcmp(tkidentifier->name, "__builtin_vargtype"))
- return CExpr_ParseBuiltin(CExpr_BuiltInComputeVArgType);
- if (!strcmp(tkidentifier->name, "__builtin_classify_type"))
- return CExpr_ParseBuiltin(CExpr_BuiltInClassifyType);
- if (!strcmp(tkidentifier->name, "__builtin_next_arg"))
- return CExpr_ParseNextArg();
- }
- if (copts.altivec_model && !strcmp("vec_step", tkidentifier->name))
- return CExpr_ParseVecStep();
- case '~':
- case TK_OPERATOR:
- case TK_INHERITED:
- case TK_COLON_COLON:
- if (CScope_ParseExprName(&pr))
- return CExpr_ParseNameResultExpr(&pr, NULL, flag, 1);
- tk = lex();
- return nullnode();
- }
-
- CError_ErrorSkip(CErrorStr141);
- return nullnode();
-}
-
-static ENode *CExpr_SimpleExplicitConversion(void) {
- DeclInfo di;
-
- memclrw(&di, sizeof(DeclInfo));
-
- if (!copts.cpp_extensions && tk != TK_UU_TYPEOF_UU && tk != TK_TYPENAME && lookahead() != '(')
- CError_Error(CErrorStr114);
-
- CParser_GetDeclSpecs(&di, 0);
- return CExpr_ParseExplicitConversion(di.thetype, di.qual);
-}
-
-static ENode *CExpr_NewPTMFCall(void) {
- tk = lex();
- CExpr_ScanExpressionList(1);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- } else {
- CError_FATAL(2465);
- return nullnode();
- }
-}
-
-static ENode *call_ptmf(ENode *expr) {
- Type *rettype;
- ENodeList *args;
- ENodeList *list1;
- ENodeList *list2;
- Object *callobj;
-
- rettype = TYPE_FUNC(TPTR_TARGET(expr->data.mfpointer.mfpointer->rtype))->functype;
- tk = lex();
- args = CExpr_ScanExpressionList(1);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return nullnode();
- }
-
- if (IS_TYPE_STRUCT(rettype) || IS_TYPE_CLASS(rettype) || IS_TYPE_12BYTES_MEMBERPOINTER(rettype))
- callobj = rt_ptmf_scall4;
- else
- callobj = rt_ptmf_scall;
-
- list1 = lalloc(sizeof(ENodeList));
- list1->next = args;
- list1->node = expr->data.mfpointer.accessnode->data.monadic;
-
- list2 = lalloc(sizeof(ENodeList));
- list2->next = list1;
- list2->node = expr->data.mfpointer.mfpointer->data.monadic;
-
- if (!copts.old_argmatch) {
- CError_ASSERT(2568, IS_TYPE_POINTER_ONLY(list2->node->rtype));
- list2->node->rtype = TYPE(&void_ptr);
- }
-
- expr = CExpr_GenericPtmfCall(
- callobj,
- TYPE_FUNC(TPTR_TARGET(expr->data.mfpointer.mfpointer->rtype)),
- list2);
- tk = lex();
- return expr;
-}
-
-static ENode *CExpr_DummyDestr(ENode *expr) {
- SInt32 state;
- NameResult pr;
- DeclInfo di;
- NameSpace *nspace;
-
- CPrep_TokenStreamGetState(&state);
- nspace = cscope_current;
- if ((tk = lex()) == TK_COLON_COLON) {
- nspace = cscope_root;
- tk = lex();
- } else if (tk != '~' && tk != TK_IDENTIFIER && !(tk >= TK_AUTO && tk <= TK_BYREF)) {
- CPrep_TokenStreamSetCurState(&state);
- return NULL;
- }
-
-loop:
- if (tk == '~')
- goto is_tilde;
- if (tk == TK_IDENTIFIER) {
- if (CScope_FindTypeName(nspace, tkidentifier, &pr)) {
- tk = lex();
- if (pr.nspace_0) {
- if (tk == TK_COLON_COLON) {
- tk = lex();
- nspace = pr.nspace_0;
- goto loop;
- }
- } else if (IS_TYPE_CLASS(pr.type) && tk == TK_COLON_COLON) {
- tk = lex();
- nspace = TYPE_CLASS(pr.type)->nspace;
- goto loop;
- } else {
- if (!is_typesame(pr.type, expr->rtype))
- CError_Error(CErrorStr146);
- if (tk == TK_COLON_COLON && ((tk = lex()) == '~') && ((tk = lex()) == TK_IDENTIFIER)) {
- parse_dtor:
- if (CScope_FindTypeName(nspace, tkidentifier, &pr) && !pr.nspace_0) {
- if (!is_typesame(pr.type, expr->rtype))
- CError_Error(CErrorStr146);
- tk = lex();
- goto parsed;
- }
- }
- }
- }
- } else if (tk >= TK_AUTO && tk <= TK_BYREF) {
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass || di.qual || !is_typesame(di.thetype, expr->rtype))
- CError_Error(CErrorStr146);
- if (tk == TK_COLON_COLON && ((tk = lex()) == '~')) {
- is_tilde:
- if ((tk = lex()) == TK_IDENTIFIER)
- goto parse_dtor;
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- if (di.storageclass || !is_typesame(di.thetype, expr->rtype))
- CError_Error(CErrorStr146);
- goto parsed;
- }
- }
-
- CError_Error(CErrorStr141);
- return NULL;
-
-parsed:
- if (tk == '(') {
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- CError_Error(CErrorStr114);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = &stvoid;
- return expr;
-}
-
-static ENode *postfix_expression(Boolean flag) {
- NameResult pr;
- Conversion conv;
- ENode *expr;
- ENode *subexpr;
- ENode *funcexpr;
- ENodeList *args;
- ENode *copy;
- ENode *tmp;
- StructMember *member;
-
- if (copts.cplusplus) {
- switch (tk) {
- case TK_VOID:
- case TK_CHAR:
- case TK_SHORT:
- case TK_INT:
- case TK_LONG:
- case TK_FLOAT:
- case TK_DOUBLE:
- case TK_SIGNED:
- case TK_UNSIGNED:
- case TK_UNK_113:
- case TK_UNK_114:
- case TK_UNK_115:
- case TK_UNK_116:
- case TK_UNK_117:
- case TK_UNK_118:
- case TK_UNK_119:
- case TK_UNK_11A:
- case TK_UU_TYPEOF_UU:
- case TK_BOOL:
- case TK_WCHAR_T:
- case TK_TYPENAME:
- expr = CExpr_SimpleExplicitConversion();
- break;
- default:
- expr = primary_expression(flag);
- break;
- case TK_CONST_CAST:
- expr = CRTTI_Parse_const_cast();
- break;
- case TK_DYNAMIC_CAST:
- expr = CRTTI_Parse_dynamic_cast();
- break;
- case TK_REINTERPRET_CAST:
- expr = CRTTI_Parse_reinterpret_cast();
- break;
- case TK_STATIC_CAST:
- expr = CRTTI_Parse_static_cast();
- break;
- case TK_TYPEID:
- expr = CRTTI_ParseTypeID();
- break;
- }
- } else {
- expr = primary_expression(flag);
- }
-
-loop:
- switch (tk) {
- case '[':
- expr = pointer_generation(expr);
- tk = lex();
- subexpr = expression();
- if (copts.cplusplus && CExpr_CheckOperator('[', expr, subexpr, &conv)) {
- if ((expr = conv.x0)) {
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- goto loop;
- }
-
- CError_ASSERT(2753, expr = conv.left);
- CError_ASSERT(2754, subexpr = conv.right);
- }
-
- if (IS_TYPE_POINTER(expr->rtype)) {
- expr = padd(expr, subexpr);
- } else if (IS_TYPE_POINTER(subexpr->rtype)) {
- expr = padd(subexpr, expr);
- } else {
- CError_Error(CErrorStr148);
- goto dont_do_indirect;
- }
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- dont_do_indirect:
- if (tk != ']')
- CError_ErrorSkip(CErrorStr125);
- else
- tk = lex();
- goto loop;
-
- case '(':
- funcexpr = CExpr_PointerGeneration(expr);
- if (copts.cplusplus) {
- if (CExpr_CheckOperator('(', funcexpr, NULL, &conv)) {
- CError_ASSERT(2775, expr = conv.x0);
- goto loop;
- }
- if (ENODE_IS(funcexpr, EMFPOINTER)) {
- expr = checkreference(call_ptmf(funcexpr));
- goto loop;
- }
- }
-
- tk = lex();
- args = CExpr_ScanExpressionList(1);
- if (tk != ')')
- CError_Error(CErrorStr115);
-
- if (ENODE_IS(funcexpr, ETEMPLDEP)) {
- expr = CExpr_NewENode(EFUNCCALL);
- expr->rtype = &sttemplexpr;
- expr->data.funccall.funcref = funcexpr;
- expr->data.funccall.args = args;
- expr->data.funccall.functype = &rt_func;
- tk = lex();
- } else {
- expr = checkreference(CExpr_MakeFunctionCall(funcexpr, args));
- tk = lex();
- }
- goto loop;
-
- case TK_ARROW:
- expr = pointer_generation(expr);
- if (copts.cplusplus) {
- while (IS_TYPE_CLASS(expr->rtype) && CExpr_CheckOperator(TK_ARROW, expr, NULL, &conv)) {
- CError_ASSERT(2810, subexpr = conv.x0);
- expr = pointer_generation(subexpr);
- }
- }
-
- if (!IS_TYPE_POINTER(expr->rtype)) {
- CError_ErrorSkip(CErrorStr148);
- return expr;
- }
-
- if (copts.cplusplus && copts.objective_c && CObjC_IsType_id(expr->rtype)) {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- if ((subexpr = CObjC_CheckModernSendMessage(NULL, expr)))
- return subexpr;
- } else {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(expr->rtype);
- }
- case '.':
- expr = pointer_generation(expr);
- if (IS_TYPE_CLASS(expr->rtype)) {
- CDecl_CompleteType(expr->rtype);
- if (TYPE_CLASS(expr->rtype)->objcinfo && copts.cplusplus && (subexpr = CObjC_CheckModernSendMessage(TYPE_CLASS(expr->rtype), expr)))
- return subexpr;
-
- if (!(TYPE_CLASS(expr->rtype)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, expr->rtype, 0);
-
- if ((tk = lex()) == TK_TEMPLATE && (tk = lex()) != TK_IDENTIFIER)
- CError_Error(CErrorStr107);
-
- if (CScope_ParseMemberName(TYPE_CLASS(expr->rtype), &pr, 0)) {
- if (pr.x1C) {
- if ((tk = lex()) == '(') {
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- CError_Error(CErrorStr114);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = &stvoid;
- } else {
- expr = checkreference(CExpr_ParseNameResultExpr(&pr, expr, 0, 0));
- }
- }
- goto loop;
- }
- if (!IS_TYPE_STRUCT(expr->rtype) || TYPE_STRUCT(expr->rtype)->stype > STRUCT_TYPE_MAX) {
- if (copts.cplusplus && (subexpr = CExpr_DummyDestr(expr)))
- return subexpr;
- CError_ErrorSkip(CErrorStr149);
- return expr;
- }
- if (!ENODE_IS(expr, EINDIRECT)) {
- subexpr = CExpr_NewETEMPNode(expr->rtype, 1);
- copy = lalloc(sizeof(ENode));
- *copy = *subexpr;
-
- tmp = makemonadicnode(subexpr, EINDIRECT);
- tmp->rtype = expr->rtype;
-
- tmp = makediadicnode(tmp, expr, EASS);
- tmp = makediadicnode(tmp, copy, ECOMMA);
- tmp->rtype = copy->rtype;
-
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = expr->rtype;
- expr = tmp;
- }
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return expr;
- }
-
- member = ismember(TYPE_STRUCT(expr->rtype), tkidentifier);
- if (!member) {
- if (!expr->rtype->size)
- CError_Error(CErrorStr136, expr->rtype, 0);
- else
- CError_Error(CErrorStr150, tkidentifier->name);
- return expr;
- }
-
- if (!IS_TYPE_POINTER(expr->data.monadic->rtype)) {
- CError_ErrorSkip(CErrorStr149);
- return expr;
- }
-
- expr = checkreference(CClass_AccessMember(expr, member->type, member->qual, member->offset));
- tk = lex();
- goto loop;
-
- case TK_INCREMENT:
- tmp = pointer_generation(expr);
- if (copts.cplusplus && CExpr_CheckOperator(TK_INCREMENT, tmp, nullnode(), &conv)) {
- if ((expr = conv.x0)) {
- tk = lex();
- goto loop;
- }
- CError_ASSERT(2952, tmp = conv.left);
- }
- tmp = CExpr_LValue(tmp, 1, 1);
- if (tmp->rtype == TYPE(&stbool)) {
- expr = CExpr_TempModifyExpr(tmp);
- tk = lex();
- } else {
- checkadditive(tmp);
- expr = makemonadicnode(tmp, EPOSTINC);
- tk = lex();
- }
- goto loop;
-
- case TK_DECREMENT:
- tmp = pointer_generation(expr);
- if (copts.cplusplus && CExpr_CheckOperator(TK_DECREMENT, tmp, nullnode(), &conv)) {
- if ((expr = conv.x0)) {
- tk = lex();
- goto loop;
- }
- CError_ASSERT(2976, tmp = conv.left);
- }
- tmp = CExpr_LValue(tmp, 1, 1);
- checkadditive(tmp);
- expr = makemonadicnode(tmp, EPOSTDEC);
- tk = lex();
- goto loop;
- }
-
- return expr;
-}
-
-static ENode *CExpr_ParseSizeof(void) {
- Type *type;
- ENode *expr;
-
- type = CExpr_ParseTypeExpression(NULL);
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)
- CError_Error(CErrorStr286);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- expr = CExpr_NewTemplDepENode(TDE_SIZEOF);
- expr->data.templdep.u.typeexpr.type = type;
- return expr;
- }
-
- if (type->size == 0) {
- if (copts.gcc_extensions && (IS_TYPE_FUNC(type) || IS_TYPE_VOID(type)))
- return intconstnode(CABI_GetSizeTType(), 1);
-
- if (IS_TYPE_CLASS(type) || IS_TYPE_STRUCT(type))
- CError_Error(CErrorStr136, type, 0);
- else
- CError_Error(CErrorStr146);
- }
-
- return intconstnode(CABI_GetSizeTType(), type->size);
-}
-
-SInt32 scansizeof(void) {
- ENode *expr;
-
- expr = CExpr_ParseSizeof();
- if (!ENODE_IS(expr, EINTCONST)) {
- CError_Error(CErrorStr190);
- return 0;
- }
-
- return CInt64_GetULong(&expr->data.intval);
-}
-
-static ENode *CExpr_ParseAlignof(void) {
- Type *type;
- ENode *expr;
- SInt16 align;
-
- type = CExpr_ParseTypeExpression(NULL);
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)
- CError_Error(CErrorStr364);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- expr = CExpr_NewTemplDepENode(TDE_ALIGNOF);
- expr->data.templdep.u.typeexpr.type = type;
- return expr;
- }
-
- if (type->size == 0) {
- if (IS_TYPE_CLASS(type) || IS_TYPE_STRUCT(type))
- CError_Error(CErrorStr136, type, 0);
- else
- CError_Error(CErrorStr146);
- }
-
- align = CMach_GetTypeAlign(type);
- if (align == 0)
- align = 1;
-
- return intconstnode(CABI_GetSizeTType(), align);
-}
-
-SInt32 scanalignof(void) {
- ENode *expr;
-
- expr = CExpr_ParseAlignof();
- if (!ENODE_IS(expr, EINTCONST)) {
- CError_Error(CErrorStr190);
- return 0;
- }
-
- return CInt64_GetULong(&expr->data.intval);
-}
-
-static ENode *logicalexpression(ENode *expr) {
- if (copts.cplusplus && copts.booltruefalse)
- expr->rtype = TYPE(&stbool);
- else
- expr->rtype = TYPE(&stsignedint);
- return expr;
-}
-
-ENode *getnodeaddress(ENode *expr, Boolean flag) {
- ENode *result;
- Object *obj;
-
- if (!ENODE_IS(expr, EINDIRECT)) {
- expr = CExpr_LValue(expr, flag, flag);
- if (!ENODE_IS(expr, EINDIRECT)) {
- if (!flag)
- CError_Error(CErrorStr142);
- return nullnode();
- }
- } else {
- if (flag &&
- ENODE_IS(expr->data.monadic, EOBJREF) &&
- expr->data.monadic->data.objref->name == this_name_node &&
- cscope_currentfunc &&
- cscope_currentclass &&
- expr->data.monadic->data.objref == CClass_ThisSelfObject())
- CError_Error(CErrorStr189);
- }
-
- result = lalloc(sizeof(ENode));
- *result = *expr;
-restart:
- switch (result->data.monadic->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- result->type = ETYPCON;
- if (IS_TYPE_POINTER_ONLY(result->rtype))
- result->flags = TPTR_QUAL(result->rtype) & ENODE_FLAG_QUALS;
- result->rtype = CDecl_NewPointerType(result->rtype);
- return result;
- case EOBJREF:
- obj = result->data.monadic->data.objref;
- if (obj->datatype == DALIAS) {
- CExpr_AliasTransform(result->data.monadic);
- goto restart;
- }
- if (obj->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- obj->flags = obj->flags | OBJECT_FLAGS_2;
- if (flag && !copts.cplusplus && obj->sclass == TK_REGISTER)
- CError_Error(CErrorStr163);
- break;
- case EFUNCCALL:
- if (flag && !IS_TYPE_POINTER_ONLY(result->data.monadic->data.funccall.functype->functype))
- CError_Warning(CErrorStr142);
- break;
- case EBITFIELD:
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- switch (result->rtype->type) {
- case TYPEPOINTER:
- result->data.monadic->rtype = CDecl_NewPointerType(result->rtype);
- result->data.monadic->flags = result->flags;
- break;
- default:
- result->data.monadic->rtype = CDecl_NewPointerType(result->rtype);
- result->data.monadic->flags = result->flags;
- }
-
- return result->data.monadic;
-}
-
-static ENode *CExpr_MakeStaticMemberList(NameSpaceObjectList *list) {
- NameSpaceObjectList *newlist;
- NameSpaceObjectList *n;
- ENode *result;
-
- newlist = NULL;
- while (list) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_STATIC_METHOD(OBJECT(list->object)->type)) {
- n = galloc(sizeof(NameSpaceObjectList));
- *n = *list;
- n->next = newlist;
- newlist = n;
- }
- list = list->next;
- }
-
- if (!newlist) {
- CError_Warning(CErrorStr331);
- return nullnode();
- }
-
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(newlist->object)->type;
- result->data.objlist.list = newlist;
- return result;
-}
-
-static ENode *CExpr_MakePTDM(ENode *expr) {
- ENode *result;
-
- CError_ASSERT(3414, ENODE_IS(expr, EMEMBER) && expr->data.emember->list->object->otype == OT_MEMBERVAR);
-
- result = nullnode();
- result->rtype = CExpr_NewPTMType(expr->data.emember, NULL);
- CInt64_SetLong(&result->data.intval, OBJ_MEMBER_VAR(expr->data.emember->list->object)->offset + 1);
- return result;
-}
-
-ENode *getpointertomemberfunc(ENode *expr, Type *type, Boolean flag) {
- NameSpaceObjectList *list;
- Object *obj;
- Object *dataobj;
- Type *ptmtype;
- TypeMemberFunc *tmethod;
- OLinkList *olist;
- SInt32 data[3];
-
- CError_ASSERT(3442, ENODE_IS(expr, EMEMBER));
-
- if (expr->data.emember->expr && !copts.cpp_extensions)
- CError_Error(CErrorStr141);
-
- if (!copts.cpp_extensions) {
- if (!(expr->data.emember->x11 && expr->data.emember->pr_1D)) {
- if (type && IS_TYPE_MEMBERPOINTER(type))
- CError_Warning(CErrorStr331);
- }
- }
-
- if (expr->data.emember->list->next) {
- if (type) {
- if (IS_TYPE_MEMBERPOINTER(type)) {
- type = TYPE_MEMBER_POINTER(type)->ty1;
- for (list = expr->data.emember->list; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && is_memberpointerequal(OBJECT(list->object)->type, type)) {
- obj = OBJECT(list->object);
- break;
- }
- }
- if (!list) {
- CError_Error(CErrorStr146);
- return nullnode();
- }
- } else {
- return CExpr_MakeStaticMemberList(expr->data.emember->list);
- }
- } else {
- obj = OBJECT(expr->data.emember->list->object);
- }
- } else {
- obj = OBJECT(expr->data.emember->list->object);
- }
-
- while (obj->datatype == DALIAS)
- obj = obj->u.alias.object;
-
- CError_ASSERT(3503, obj->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(obj->type));
-
- if (TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)
- CError_Error(CErrorStr190);
-
- ptmtype = CExpr_NewPTMType(expr->data.emember, obj);
- tmethod = TYPE_METHOD(obj->type);
- dataobj = CParser_NewGlobalDataObject(NULL);
- dataobj->name = CParser_GetUniqueName();
- dataobj->nspace = cscope_root;
- dataobj->type = ptmtype;
- dataobj->sclass = TK_STATIC;
-
- if (flag) {
- data[0] = 0;
- if (obj->datatype == DVFUNC) {
- olist = NULL;
- data[1] = tmethod->vtbl_index;
- data[2] = tmethod->theclass->vtable->offset;
- } else {
- data[1] = -1;
- data[2] = 0;
- olist = galloc(sizeof(OLinkList));
- olist->next = NULL;
- olist->obj = obj;
- olist->somevalue = 0;
- olist->offset = 8;
- }
- CInit_DeclareData(dataobj, data, olist, dataobj->type->size);
- }
-
- return create_objectnode(dataobj);
-}
-
-static ENode *getpointertomember(ENode *expr) {
- CError_ASSERT(3554, ENODE_IS(expr, EMEMBER));
-
- if (expr->data.emember->expr)
- CError_Error(CErrorStr141);
-
- expr->data.emember->x11 = 1;
- if (!expr->data.emember->list->next) {
- if (expr->data.emember->list->object->otype == OT_MEMBERVAR)
- return CExpr_MakePTDM(expr);
- else
- return getpointertomemberfunc(expr, NULL, 1);
- }
-
- return expr;
-}
-
-ENode *CExpr_New_ELOGNOT_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, ELOGNOT, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('!', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3593, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- expr = forceintegral(expr);
- break;
- case TYPEMEMBERPOINTER:
- expr = CExpr_ConvertToCondition(expr);
- break;
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-
- switch (expr->type) {
- case EINTCONST:
- expr->data.intval = CInt64_Not(expr->data.intval);
- break;
- case EFLOATCONST:
- expr->type = EINTCONST;
- CInt64_SetLong(&expr->data.intval, CMach_FloatIsZero(expr->data.floatval));
- break;
- default:
- expr = makemonadicnode(expr, ELOGNOT);
- }
-
- return logicalexpression(expr);
-}
-
-ENode *CExpr_New_EMONMIN_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, EMONMIN, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('-', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3652, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- expr = integralpromote(expr);
- if (ENODE_IS(expr, EINTCONST)) {
- expr->data.intval = CMach_CalcIntMonadic(expr->rtype, '-', expr->data.intval);
- return expr;
- }
- return makemonadicnode(expr, EMONMIN);
- case TYPEFLOAT:
- if (ENODE_IS(expr, EFLOATCONST)) {
- expr->data.floatval = CMach_CalcFloatMonadic(expr->rtype, '-', expr->data.floatval);
- return expr;
- }
- return CExpr_UnaryFloatExpression(makemonadicnode(expr, EMONMIN));
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-}
-
-ENode *CExpr_New_EBINNOT_Node(ENode *input) {
- ENode *expr;
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(input->rtype))
- return CTempl_MakeTemplDepExpr(NULL, EBINNOT, input);
-
- expr = pointer_generation(input);
- if (copts.cplusplus && CExpr_CheckOperator('~', expr, NULL, &conv)) {
- if ((input = conv.x0))
- return input;
- CError_ASSERT(3702, expr = conv.left);
- }
-
- expr = integralpromote(expr);
-
- if (ENODE_IS(expr, EINTCONST)) {
- expr->data.intval = CMach_CalcIntMonadic(expr->rtype, '~', expr->data.intval);
- return expr;
- }
- return makemonadicnode(expr, EBINNOT);
-}
-
-ENode *unary_expression(void) {
- ENode *expr;
- ENode *tmp;
- Conversion conv;
-
- switch (tk) {
- case TK_COLON_COLON:
- switch (lookahead()) {
- case TK_NEW:
- tk = lex();
- return scannew(1);
- case TK_DELETE:
- tk = lex();
- return scandelete(1);
- }
- return postfix_expression(0);
-
- case TK_NEW:
- return scannew(0);
- case TK_DELETE:
- return scandelete(0);
- case TK_INCREMENT:
- tk = lex();
- if (copts.cplusplus) {
- expr = pointer_generation(cast_expression());
- if (CExpr_CheckOperator(TK_INCREMENT, expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3748, expr = conv.left);
- }
- } else {
- expr = pointer_generation(unary_expression());
- }
- expr = CExpr_LValue(expr, 1, 1);
- if (expr->rtype == TYPE(&stbool)) {
- tmp = nullnode();
- tmp->rtype = TYPE(&stbool);
- CInt64_SetLong(&tmp->data.intval, 1);
- return makediadicnode(expr, tmp, EASS);
- } else {
- checkadditive(expr);
- return makemonadicnode(expr, EPREINC);
- }
- case TK_DECREMENT:
- tk = lex();
- if (copts.cplusplus) {
- expr = pointer_generation(cast_expression());
- if (CExpr_CheckOperator(TK_DECREMENT, expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3776, expr = conv.left);
- }
- } else {
- expr = pointer_generation(unary_expression());
- }
- expr = CExpr_LValue(expr, 1, 1);
- checkadditive(expr);
- return makemonadicnode(expr, EPREDEC);
-
- case '&':
- if (copts.cplusplus) {
- switch ((tk = lex())) {
- case TK_IDENTIFIER:
- case TK_INHERITED:
- case TK_COLON_COLON:
- expr = postfix_expression(1);
- if (ENODE_IS(expr, EMEMBER))
- return getpointertomember(expr);
- break;
- default:
- expr = cast_expression();
- }
-
- if (CExpr_CheckOperator('&', expr, NULL, &conv)) {
- CError_ASSERT(3809, conv.x0);
- return conv.x0;
- }
- } else {
- tk = lex();
- expr = cast_expression();
- }
-
- if (copts.mpwc_relax && !copts.cplusplus && IS_TYPE_ARRAY(expr->rtype) && ENODE_IS(expr, EINDIRECT))
- return pointer_generation(expr);
- if (ENODE_IS(expr, EOBJLIST))
- return expr;
-
- if (IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
- tmp = CExpr_NewTemplDepENode(TDE_ADDRESS_OF);
- tmp->data.templdep.u.monadic = expr;
- return tmp;
- }
-
- return getnodeaddress(expr, 1);
-
- case '*':
- tk = lex();
- expr = pointer_generation(cast_expression());
- if (copts.cplusplus && CExpr_CheckOperator('*', expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3840, expr = conv.left);
- }
-
- if (!IS_TYPE_POINTER(expr->rtype)) {
- CError_Error(CErrorStr148);
- return expr;
- }
-
- tmp = makemonadicnode(expr, EINDIRECT);
- CDecl_CompleteType(tmp->rtype = TPTR_TARGET(tmp->rtype));
- return tmp;
-
- case '+':
- tk = lex();
- expr = pointer_generation(cast_expression());
- if (copts.cplusplus && CExpr_CheckOperator('+', expr, NULL, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(3852, expr = conv.left);
- }
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- return integralpromote(expr);
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- return expr;
- default:
- CError_Error(CErrorStr144);
- return expr;
- }
-
- case '-':
- tk = lex();
- return CExpr_New_EMONMIN_Node(cast_expression());
- case '~':
- tk = lex();
- return CExpr_New_EBINNOT_Node(cast_expression());
- case '!':
- tk = lex();
- return CExpr_New_ELOGNOT_Node(cast_expression());
-
- case TK_SIZEOF:
- return CExpr_ParseSizeof();
- case TK_UU_ALIGNOF_UU:
- return CExpr_ParseAlignof();
-
- case TK_LOGICAL_AND:
- if (copts.ANSIstrict)
- break;
-
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return nullnode();
- }
-
- expr = lalloc(sizeof(ENode));
- expr->type = ELABEL;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = TYPE(&void_ptr);
- expr->data.label = findlabel();
- if (!expr->data.label) {
- expr->data.label = newlabel();
- expr->data.label->name = tkidentifier;
- expr->data.label->next = Labels;
- Labels = expr->data.label;
- }
- tk = lex();
- return expr;
- }
-
- return postfix_expression(0);
-}
-
-ENode *do_castnullcheck(ENode *condexpr, ENode *nullcheckexpr) {
- ENode *result;
-
- if (isnotzero(nullcheckexpr))
- return condexpr;
-
- result = lalloc(sizeof(ENode));
- *result = *condexpr;
- result->type = ENULLCHECK;
- result->data.nullcheck.nullcheckexpr = lalloc(sizeof(ENode));
- *result->data.nullcheck.nullcheckexpr = *nullcheckexpr;
- result->data.nullcheck.condexpr = condexpr;
- result->data.nullcheck.precompid = CParser_GetUniqueID();
-
- nullcheckexpr->type = EPRECOMP;
- nullcheckexpr->data.precompid = result->data.nullcheck.precompid;
-
- return result;
-}
-
-ENode *CExpr_SafeClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean pathcheckflag) {
- ENode *result;
-
- result = CClass_ClassPointerCast(expr, a, b, typconflag, 1, pathcheckflag);
- if (result != expr) {
- if (!(ENODE_IS(result, ETYPCON) && result->data.monadic == expr))
- result = do_castnullcheck(result, expr);
- }
- return result;
-}
-
-ENode *PointerToMemberCast(ENode *expr, TypeMemberPointer *tm1, TypeMemberPointer *tm2, Boolean flag) {
- BClassList *path;
- Boolean negate;
- short depth;
- Boolean isambig;
- SInt32 pathoffset;
- CInt64 pathoffset64;
- ENode *tmp;
-
- CError_ASSERT(3984, IS_TYPE_CLASS(tm1->ty2));
- CError_ASSERT(3985, IS_TYPE_CLASS(tm2->ty2));
-
- if (tm1->ty2 == tm2->ty2) {
- expr->rtype = TYPE(tm2);
- return expr;
- }
-
- negate = 0;
- path = CClass_GetBasePath(TYPE_CLASS(tm2->ty2), TYPE_CLASS(tm1->ty2), &depth, &isambig);
- if (!path) {
- path = CClass_GetBasePath(TYPE_CLASS(tm1->ty2), TYPE_CLASS(tm2->ty2), &depth, &isambig);
- if (!path)
- goto failed;
- negate = 1;
- }
-
- if (isambig)
- CError_Error(CErrorStr188);
-
- if ((pathoffset = CClass_GetPathOffset(path)) < 0)
- goto failed;
- if (negate)
- pathoffset = -pathoffset;
-
- if (flag)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
-
- if (tm1->size != tm2->size) {
- failed:
- CError_Error(CErrorStr247, tm1, 0, tm2, 0);
- return nullnode();
- }
-
- if (!pathoffset) {
- expr->rtype = TYPE(tm2);
- return expr;
- }
-
- if (tm1->size == 4u) {
- if (ENODE_IS(expr, EINTCONST)) {
- if (!CInt64_IsZero(&expr->data.intval)) {
- CInt64_SetLong(&pathoffset64, pathoffset);
- expr->data.intval = CInt64_Add(expr->data.intval, pathoffset64);
- }
- expr->rtype = TYPE(tm2);
- return expr;
- } else {
- expr->rtype = TYPE(&stunsignedlong);
- tmp = intconstnode(TYPE(&stunsignedlong), pathoffset);
- tmp = makediadicnode(expr, tmp, EADD);
- tmp = makemonadicnode(tmp, ETYPCON);
- tmp->rtype = TYPE(tm2);
- return do_castnullcheck(tmp, expr);
- }
- } else {
- tmp = create_temp_node(TYPE(&ptmstruct));
- expr = getnodeaddress(expr, 0);
- tmp = funccallexpr(rt_ptmf_cast, intconstnode(TYPE(&stsignedlong), pathoffset), expr, tmp, NULL);
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = TYPE(tm2);
- return tmp;
- }
-}
-
-ENode *CExpr_MemberPointerConversion(ENode *expr, TypeMemberPointer *type, Boolean flag1) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
- if (IS_TYPE_FUNC(type->ty1))
- expr = create_objectnode(rt_ptmf_null);
- expr->rtype = TYPE(type);
- } else if (ENODE_IS(expr, EMEMBER)) {
- expr = getpointertomemberfunc(expr, TYPE(type), flag1);
- }
-
- return expr;
-}
-
-static ENode *CExpr_MemberPointerCast(ENode *expr, TypeMemberPointer *type, UInt32 qual) {
- if (!IS_TYPE_MEMBERPOINTER(expr->rtype))
- expr = CExpr_MemberPointerConversion(expr, type, 1);
-
- if (!IS_TYPE_MEMBERPOINTER(expr->rtype)) {
- CError_Error(CErrorStr164);
- return nullnode();
- }
-
- expr = PointerToMemberCast(expr, TYPE_MEMBER_POINTER(expr->rtype), type, 0);
- expr->flags = qual & ENODE_FLAG_QUALS;
- return expr;
-}
-
-ENode *do_typecast(ENode *expr, Type *type, UInt32 qual) {
- TypePointer *tptr;
- ENode *tmp;
- short flags;
-
- if (!copts.old_argmatch)
- return CExpr_Convert(expr, type, qual, 1, 0);
-
- if (copts.cpp_extensions && is_typesame(expr->rtype, type) && !ENODE_IS(expr, EOBJLIST)) {
- expr->rtype = type;
- expr->flags &= ~ENODE_FLAG_QUALS;
- expr->flags |= qual & ENODE_FLAG_QUALS;
- return expr;
- }
-
- switch (type->type) {
- case TYPEARRAY:
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return expr;
- case TYPEMEMBERPOINTER:
- if (!IS_TYPE_CLASS(expr->rtype))
- return CExpr_MemberPointerCast(expr, TYPE_MEMBER_POINTER(type), qual);
- }
-
- flags = qual & ENODE_FLAG_QUALS;
-
- if (ENODE_IS(expr, EOBJLIST))
- return CExpr_AssignmentPromotion(expr, type, qual & ENODE_FLAG_QUALS, 1);
-
- if (ENODE_IS(expr, EOBJREF) && IS_TYPE_NONSTATIC_METHOD(expr->data.objref->type)) {
- CError_Error(CErrorStr221);
- return nullnode();
- }
-
- if (type == &stvoid) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_REFERENCE(type)) {
- tmp = getnodeaddress(expr, 0);
- tptr = galloc(sizeof(TypePointer));
- *tptr = *TYPE_POINTER(type);
- tptr->qual &= ~Q_REFERENCE;
-
- tmp = do_typecast(tmp, TYPE(tptr), qual);
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = TPTR_TARGET(type);
- tmp->flags = flags;
- return tmp;
- }
-
- if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type)) {
- if (expr->rtype->size == 0)
- CDecl_CompleteType(expr->rtype);
-
- if (expr->rtype == type && !CClass_CopyConstructor(TYPE_CLASS(type)))
- return expr;
-
- if (user_assign_check(expr, type, qual, 1, 1, 1)) {
- assign_node->flags = flags;
- return assign_node;
- }
-
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return nullnode();
- }
-
- if (IS_TYPE_STRUCT(type) && copts.cplusplus && is_typesame(expr->rtype, type)) {
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (type == TYPE(&stbool)) {
- expr = CExpr_ConvertToBool(expr, 1);
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_ENUM(type)) {
- tmp = do_typecast(expr, TYPE_ENUM(type)->enumtype, qual);
- if (!ENODE_IS(tmp, EINTCONST))
- tmp = makemonadicnode(tmp, ETYPCON);
- tmp->rtype = type;
- tmp->flags = flags;
- return tmp;
- }
-
- if (IS_TYPE_INT_OR_FLOAT(type)) {
- if (ENODE_IS(expr, ETYPCON) && expr->rtype->type == type->type && expr->rtype->size == type->size) {
- if (is_unsigned(expr->rtype) == is_unsigned(type) && ENODE_QUALS(expr) == qual) {
- expr->rtype = type;
- expr->flags = expr->flags | ENODE_FLAG_80;
- return expr;
- }
- }
-
- if (IS_TYPE_ENUM(expr->rtype))
- expr = forceintegral(expr);
-
- if (IS_TYPE_INT_OR_FLOAT(expr->rtype)) {
- expr = promote(expr, type);
- expr->flags = flags;
- return expr;
- }
-
- if (!(IS_TYPE_POINTER_ONLY(expr->rtype) && !IS_TYPE_FLOAT(type)))
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
-
- if (ENODE_IS(expr, ETYPCON) && ENODE_IS(tmp = expr->data.monadic, EINTCONST)) {
- tmp->rtype = type;
- tmp->flags = flags;
- tmp->data.intval = CExpr_IntConstConvert(type, TYPE(&stunsignedlong), tmp->data.intval);
- return tmp;
- }
-
- if (type->size != 4) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (IS_TYPE_POINTER(type)) {
- if (IS_TYPE_POINTER(expr->rtype)) {
- if (IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(type)))
- expr = CExpr_SafeClassPointerCast(expr, TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), 1, 0);
-
- if (!ENODE_IS(expr, ETYPCON))
- expr = makemonadicnode(expr, ETYPCON);
-
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if (!IS_TYPE_INT(expr->rtype)) {
- if (!IS_TYPE_ENUM(expr->rtype)) {
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return expr;
- }
- expr = forceintegral(expr);
- }
-
- if (expr->rtype->size != 4) {
- if (!ENODE_IS(expr, EINTCONST))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
-
- if ((tmp = CodeGen_HandleTypeCast(expr, type, qual)))
- return tmp;
-
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return nullnode();
-}
-
-static Boolean isvectorconst(ENode *node) {
- if (ENODE_IS3(node, ECOMMA, EINTCONST, EFLOATCONST))
- return 1;
- else
- return 0;
-}
-
-ENode *cast_expression(void) {
- ENode *expr;
- ENode *tmp;
- ENodeList *args;
- MWVector128 vec;
- DeclInfo di;
-
- if (!(tk == '(' && islookaheaddeclaration()))
- return unary_expression();
- tk = lex();
-
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 0);
- scandeclarator(&di);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- if (di.name)
- CError_Error(CErrorStr164);
-
- if (copts.altivec_model && tk == '(' && IS_TYPE_VECTOR(di.thetype)) {
- tk = lex();
- expr = s_expression();
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- if (CodeGen_CollapseVectorExpression(expr, &vec, di.thetype)) {
- tmp = lalloc(sizeof(ENode));
- tmp->type = EVECTOR128CONST;
- if ((tmp->cost = expr->cost) == 0)
- tmp->cost = 1;
- tmp->flags = ENODE_QUALS(expr);
- tmp->rtype = di.thetype;
- tmp->data.vector128val = vec;
- } else {
- tmp = makemonadicnode(expr, ETYPCON);
- }
- tmp->rtype = di.thetype;
- tmp->flags = expr->flags;
- return tmp;
- }
-
- if (tk == '{' && (!copts.ANSIstrict || copts.c9x) && !IS_TYPE_VECTOR(di.thetype))
- return CInit_AutoObject(NULL, di.thetype, di.qual);
-
- expr = cast_expression();
- if (copts.cplusplus && (CTemplTool_IsTemplateArgumentDependentType(di.thetype) ||
- CTemplTool_IsTemplateArgumentDependentExpression(expr))) {
- args = lalloc(sizeof(ENodeList));
- args->next = NULL;
- args->node = expr;
- return CExpr_TemplArgDepCast(di.thetype, di.qual, args);
- }
-
- if (!IS_TYPE_REFERENCE(di.thetype))
- expr = pointer_generation(expr);
- return do_typecast(expr, di.thetype, di.qual);
-}
-
-static ENode *pm_expression(void) {
- ENode *left;
- ENode *right;
- ENode *tmp;
- Type *type;
- UInt32 qual;
- short flags;
- Conversion conv;
-
- left = cast_expression();
-restart:
- switch (tk) {
- case TK_ARROW_STAR:
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(cast_expression());
-
- if (CExpr_CheckOperator(TK_ARROW_STAR, left, right, &conv)) {
- CError_ASSERT(4457, left = conv.x0);
- goto restart;
- }
-
- if (!IS_TYPE_POINTER(left->rtype)) {
- CError_Error(CErrorStr148);
- return left;
- }
-
- left = makemonadicnode(left, EINDIRECT);
- left->rtype = TPTR_TARGET(left->rtype);
- goto common_part;
- case TK_DOT_STAR:
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(cast_expression());
- if (!ENODE_IS(left, EINDIRECT)) {
- CError_Error(CErrorStr142);
- return left;
- }
- common_part:
- if (!IS_TYPE_CLASS(left->rtype)) {
- CError_Error(CErrorStr149);
- return left;
- }
- if (!IS_TYPE_MEMBERPOINTER(right->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- if (left->rtype != TYPE_MEMBER_POINTER(right->rtype)->ty2) {
- if (CClass_IsBaseClass(TYPE_CLASS(left->rtype), TYPE_CLASS(TYPE_MEMBER_POINTER(right->rtype)->ty2), NULL, 1, 1)) {
- left->data.monadic = CClass_ClassPointerCast(
- left->data.monadic,
- TYPE_CLASS(left->rtype),
- TYPE_CLASS(TYPE_MEMBER_POINTER(right->rtype)->ty2),
- 0, 1, 1);
- left->rtype = TYPE_MEMBER_POINTER(right->rtype)->ty2;
- } else {
- CError_Error(CErrorStr146);
- return left;
- }
- }
- type = CClass_CombineClassAccessQualifiers(
- TYPE_MEMBER_POINTER(right->rtype)->ty1,
- ENODE_QUALS(right),
- left->flags,
- &qual);
- flags = qual;
- if (!IS_TYPE_FUNC(type)) {
- if (!ENODE_IS(right, EINTCONST)) {
- if (!canadd(left->data.monadic, -1)) {
- left->data.monadic = makediadicnode(left->data.monadic, nullnode(), EADD);
- CInt64_SetLong(&left->data.monadic->data.diadic.right->data.intval, -1);
- optimizecomm(left->data.monadic);
- }
- right->rtype = TYPE(&stunsignedlong);
- left->data.monadic = makediadicnode(left->data.monadic, right, EADD);
- optimizecomm(left->data.monadic);
- } else {
- right->data.intval = CInt64_Sub(right->data.intval, cint64_one);
- if (!canadd2(left->data.monadic, right->data.intval)) {
- right->rtype = TYPE(&stunsignedlong);
- left->data.monadic = makediadicnode(left->data.monadic, right, EADD);
- optimizecomm(left->data.monadic);
- }
- }
-
- if (IS_TYPE_BITFIELD(type)) {
- left->data.monadic = makemonadicnode(left->data.monadic, EBITFIELD);
- left->data.monadic->rtype = type;
- left->rtype = TYPE_BITFIELD(type)->bitfieldtype;
- } else {
- left->rtype = type;
- }
- left->flags = flags;
- left = checkreference(left);
- goto restart;
- } else {
- CError_ASSERT(4535, ENODE_IS(right, EINDIRECT));
- tmp = lalloc(sizeof(ENode));
- tmp->type = EMFPOINTER;
- tmp->cost = 4;
- tmp->flags = 0;
- tmp->rtype = &stvoid;
- tmp->data.mfpointer.accessnode = left;
- tmp->data.mfpointer.mfpointer = right;
- return tmp;
- }
- default:
- return left;
- }
-}
-
-ENode *CExpr_New_EMUL_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EMUL, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('*', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4566, left = conv.left);
- CError_ASSERT(4567, right = conv.right);
- }
-
- return makemultnode(left, right);
-}
-
-ENode *CExpr_New_EDIV_Node(ENode *left, ENode *right, Boolean no_warning) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EDIV, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('/', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4592, left = conv.left);
- CError_ASSERT(4593, right = conv.right);
- }
-
- return makedivnode(left, right, no_warning);
-}
-
-ENode *CExpr_New_EMODULO_Node(ENode *left, ENode *right, Boolean no_warning) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EMODULO, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('%', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4618, left = conv.left);
- CError_ASSERT(4619, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right)) {
- if (!no_warning)
- CError_Warning(CErrorStr139);
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '%', right->data.intval);
- return left;
- }
-
- if (iszero(left))
- return makediadicnode(right, left, ECOMMA);
-
- if (CExpr_IsOne(right)) {
- right = nullnode();
- right->rtype = left->rtype;
- return makediadicnode(left, right, ECOMMA);
- }
-
- return makediadicnode(left, right, EMODULO);
-}
-
-ENode *CExpr_New_EADD_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EADD, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('+', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4665, left = conv.left);
- CError_ASSERT(4666, right = conv.right);
- }
-
- return makeaddnode(left, right);
-}
-
-ENode *CExpr_New_ESUB_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESUB, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('-', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4690, left = conv.left);
- CError_ASSERT(4691, right = conv.right);
- }
-
- return makesubnode(left, right);
-}
-
-ENode *CExpr_New_ESHL_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESHL, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_SHL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4715, left = conv.left);
- CError_ASSERT(4716, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
-
- if (iszero(left) || iszero(right)) {
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_SHL, right->data.intval);
- return left;
- }
-
- return makediadicnode(left, right, ESHL);
-}
-
-ENode *CExpr_New_ESHR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ESHR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_SHR, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4752, left = conv.left);
- CError_ASSERT(4753, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
-
- if (iszero(left) || iszero(right)) {
- return left;
- }
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_SHR, right->data.intval);
- return left;
- }
-
- return makediadicnode(left, right, ESHR);
-}
-
-static ENode *pointercompare(ENodeType nt, ENode *left, ENode *right) {
- Type *ltype;
- Type *rtype;
-
- ltype = left->rtype;
- rtype = right->rtype;
- if (IS_TYPE_POINTER_ONLY(ltype) && IS_TYPE_POINTER_ONLY(rtype)) {
- ltype = TPTR_TARGET(left->rtype);
- rtype = TPTR_TARGET(right->rtype);
- if (IS_TYPE_CLASS(ltype) && IS_TYPE_CLASS(rtype)) {
- if (ltype != rtype) {
- if (ltype == TPTR_TARGET(left->rtype)) {
- if (CClass_IsBaseClass(TYPE_CLASS(ltype), TYPE_CLASS(rtype), NULL, 0, 1)) {
- left = CExpr_SafeClassPointerCast(left, TYPE_CLASS(ltype), TYPE_CLASS(rtype), 0, 1);
- } else if (CClass_IsBaseClass(TYPE_CLASS(rtype), TYPE_CLASS(ltype), NULL, 0, 1)) {
- right = CExpr_SafeClassPointerCast(right, TYPE_CLASS(rtype), TYPE_CLASS(ltype), 0, 1);
- } else {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- } else {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- }
- } else if (!is_typeequal(left->rtype, right->rtype)) {
- if (!copts.objective_c || !CObjC_IsCompatibleType(left->rtype, right->rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- }
- } else if (nt == EEQU || nt == ENOTEQU) {
- if (IS_TYPE_INT(ltype)) {
- if (!(ENODE_IS(left, EINTCONST) && CInt64_IsZero(&left->data.intval)))
- CError_Error(CErrorStr144);
- CError_ASSERT(4847, IS_TYPE_POINTER_ONLY(rtype));
- left->rtype = TYPE(&stunsignedlong);
- } else if (IS_TYPE_INT(rtype)) {
- if (!(ENODE_IS(right, EINTCONST) && CInt64_IsZero(&right->data.intval)))
- CError_Error(CErrorStr144);
- CError_ASSERT(4855, IS_TYPE_POINTER_ONLY(ltype));
- right->rtype = TYPE(&stunsignedlong);
- } else if (!is_typeequal(ltype, rtype)) {
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
- } else {
- if (!is_typeequal(ltype, rtype))
- CError_Error(CErrorStr245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right));
- }
-
- return logicalexpression(makediadicnode(left, right, nt));
-}
-
-static ENode *unsigncheck(ENode *expr, Boolean flag1, Boolean flag2) {
- if (is_unsigned(expr->data.diadic.left->rtype)) {
- if (ENODE_IS(expr->data.diadic.left, EINTCONST) && CInt64_IsZero(&expr->data.diadic.left->data.intval)) {
- flag1 = !flag1;
- } else if (!(ENODE_IS(expr->data.diadic.right, EINTCONST) && CInt64_IsZero(&expr->data.diadic.right->data.intval))) {
- return logicalexpression(expr);
- }
-
- if (flag1 && flag2) {
- expr->type = EEQU;
- return logicalexpression(expr);
- }
- if (!flag1 && !flag2) {
- expr->type = ENOTEQU;
- return logicalexpression(expr);
- }
- return CExpr_ConstResult(logicalexpression(expr), !flag1);
- }
- return logicalexpression(expr);
-}
-
-ENode *CExpr_New_ELESS_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELESS, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('<', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4929, left = conv.left);
- CError_ASSERT(4930, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ELESS, left, right);
-
- CExpr_CompareConvert(&left, "<", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '<', right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, '<', right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, ELESS), 1, 0);
- }
-
- return left;
-}
-
-ENode *CExpr_New_ELESSEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELESSEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LESS_EQUAL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(4976, left = conv.left);
- CError_ASSERT(4977, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ELESSEQU, left, right);
-
- CExpr_CompareConvert(&left, "<=", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LESS_EQUAL, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LESS_EQUAL, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, ELESSEQU), 1, 1);
- }
-
- return left;
-}
-
-ENode *CExpr_New_EGREATER_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EGREATER, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('>', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5023, left = conv.left);
- CError_ASSERT(5024, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EGREATER, left, right);
-
- CExpr_CompareConvert(&left, ">", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '>', right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, '>', right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, EGREATER), 0, 0);
- }
-
- return left;
-}
-
-ENode *CExpr_New_EGREATEREQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EGREATEREQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_GREATER_EQUAL, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5070, left = conv.left);
- CError_ASSERT(5071, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EGREATEREQU, left, right);
-
- CExpr_CompareConvert(&left, ">=", &right, 0);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_GREATER_EQUAL, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_GREATER_EQUAL, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = unsigncheck(makediadicnode(left, right, EGREATEREQU), 0, 1);
- }
-
- return left;
-}
-
-ENode *memberpointercompare(ENodeType nt, ENode *left, ENode *right) {
- Object *func;
- ENodeList *arg;
-
- if (!IS_TYPE_MEMBERPOINTER(left->rtype)) {
- if (!(IS_TYPE_INT(left->rtype) && ENODE_IS(left, EINTCONST) && CInt64_IsZero(&left->data.intval))) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else if (!IS_TYPE_MEMBERPOINTER(right->rtype)) {
- if (!(IS_TYPE_INT(right->rtype) && ENODE_IS(right, EINTCONST) && CInt64_IsZero(&right->data.intval))) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else if (!is_typeequal(left->rtype, right->rtype)) {
- left = PointerToMemberCast(left, TYPE_MEMBER_POINTER(left->rtype), TYPE_MEMBER_POINTER(right->rtype), 1);
- }
-
- if ((ENODE_IS(left, EINTCONST) || !IS_TYPE_FUNC(TYPE_MEMBER_POINTER(left->rtype)->ty1)) && (ENODE_IS(right, EINTCONST) || !IS_TYPE_FUNC(TYPE_MEMBER_POINTER(right->rtype)->ty1))) {
- left->rtype = TYPE(&stunsignedlong);
- right->rtype = TYPE(&stunsignedlong);
- return logicalexpression(makediadicnode(left, right, nt));
- }
-
- arg = lalloc(sizeof(ENodeList));
- if (ENODE_IS(left, EINTCONST) || ENODE_IS(right, EINTCONST)) {
- func = rt_ptmf_test;
- if (ENODE_IS(left, EINTCONST))
- arg->node = getnodeaddress(right, 0);
- else
- arg->node = getnodeaddress(left, 0);
- arg->next = NULL;
- } else {
- func = rt_ptmf_cmpr;
- arg->next = lalloc(sizeof(ENodeList));
- arg->node = getnodeaddress(left, 0);
- arg->next->node = getnodeaddress(right, 0);
- arg->next->next = NULL;
- }
-
- left = lalloc(sizeof(ENode));
- left->type = EFUNCCALL;
- left->rtype = TYPE(&stsignedlong);
- left->cost = 4;
- left->data.funccall.funcref = create_objectrefnode(func);
- left->data.funccall.args = arg;
- left->data.funccall.functype = TYPE_FUNC(func->type);
- left->flags = TYPE_FUNC(func->type)->qual & ENODE_FLAG_QUALS;
-
- if (nt == EEQU)
- left = makemonadicnode(left, ELOGNOT);
-
- return left;
-}
-
-ENode *CExpr_New_EEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_EQ, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5201, left = conv.left);
- CError_ASSERT(5202, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(EEQU, left, right);
- if (IS_TYPE_MEMBERPOINTER(left->rtype) || IS_TYPE_MEMBERPOINTER(right->rtype))
- return memberpointercompare(EEQU, left, right);
-
- CExpr_CompareConvert(&left, "==", &right, 1);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LOGICAL_EQ, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- left->type = EINTCONST;
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LOGICAL_EQ, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = makediadicnode(left, right, EEQU);
- optimizecomm(left);
- }
-
- return logicalexpression(left);
-}
-
-ENode *CExpr_New_ENOTEQU_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ENOTEQU, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_NE, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5261, left = conv.left);
- CError_ASSERT(5262, right = conv.right);
- }
-
- if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype))
- return pointercompare(ENOTEQU, left, right);
- if (IS_TYPE_MEMBERPOINTER(left->rtype) || IS_TYPE_MEMBERPOINTER(right->rtype))
- return memberpointercompare(ENOTEQU, left, right);
-
- CExpr_CompareConvert(&left, "!=", &right, 1);
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, TK_LOGICAL_NE, right->data.intval);
- left->rtype = CParser_GetBoolType();
- } else if (ENODE_IS(left, EFLOATCONST) && ENODE_IS(right, EFLOATCONST)) {
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(left->rtype, left->data.floatval, TK_LOGICAL_NE, right->data.floatval));
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- } else {
- left = makediadicnode(left, right, ENOTEQU);
- optimizecomm(left);
- }
-
- return logicalexpression(left);
-}
-
-ENode *CExpr_New_EAND_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EAND, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('&', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5321, left = conv.left);
- CError_ASSERT(5322, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(left) || CExpr_AllBitsSet(right))
- return left;
- if (iszero(right) || CExpr_AllBitsSet(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '&', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EAND);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_EXOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EXOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('^', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5360, left = conv.left);
- CError_ASSERT(5361, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right))
- return left;
- if (iszero(left))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '^', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EXOR);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_EOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, EOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator('|', left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5399, left = conv.left);
- CError_ASSERT(5400, right = conv.right);
- }
-
- left = integralpromote(left);
- right = integralpromote(right);
- CExpr_ArithmeticConversion(&left, &right);
-
- if (iszero(right) || CExpr_AllBitsSet(left))
- return left;
- if (iszero(left) || CExpr_AllBitsSet(right))
- return right;
-
- if (ENODE_IS(left, EINTCONST) && ENODE_IS(right, EINTCONST)) {
- left->data.intval = CMach_CalcIntDiadic(left->rtype, left->data.intval, '|', right->data.intval);
- return left;
- }
-
- left = makediadicnode(left, right, EOR);
- optimizecomm(left);
- return left;
-}
-
-ENode *CExpr_New_ELAND_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELAND, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_AND, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5438, left = conv.left);
- CError_ASSERT(5439, right = conv.right);
- }
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- left = CExpr_ConvertToCondition(left);
- break;
- default:
- CError_Error(CErrorStr144);
- left = nullnode();
- }
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- right = CExpr_ConvertToCondition(right);
- break;
- default:
- CError_Error(CErrorStr144);
- right = nullnode();
- }
-
- if (iszero(left)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- }
-
- if (isnotzero(left)) {
- if (iszero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- } else if (isnotzero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- } else {
- left = makemonadicnode(right, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- } else {
- if (isnotzero(right)) {
- left = makemonadicnode(left, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- } else if (iszero(right)) {
- right->type = EINTCONST;
- right->rtype = CParser_GetBoolType();
- CInt64_SetLong(&right->data.intval, 0);
- return makecommaexpression(left, right);
- } else {
- left = makediadicnode(left, right, ELAND);
- left->rtype = CParser_GetBoolType();
- return left;
- }
- }
-}
-
-ENode *CExpr_New_ELOR_Node(ENode *left, ENode *right) {
- Conversion conv;
-
- if (IS_TYPE_TEMPLDEPEXPR(left->rtype) || IS_TYPE_TEMPLDEPEXPR(right->rtype))
- return CTempl_MakeTemplDepExpr(left, ELOR, right);
-
- left = pointer_generation(left);
- right = pointer_generation(right);
- if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_OR, left, right, &conv)) {
- if (conv.x0)
- return conv.x0;
- CError_ASSERT(5543, left = conv.left);
- CError_ASSERT(5544, right = conv.right);
- }
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- left = CExpr_ConvertToCondition(left);
- break;
- default:
- CError_Error(CErrorStr144);
- left = nullnode();
- }
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- case TYPEARRAY:
- break;
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- right = CExpr_ConvertToCondition(right);
- break;
- default:
- CError_Error(CErrorStr144);
- right = nullnode();
- }
-
- if (isnotzero(left)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- }
-
- if (iszero(left)) {
- if (iszero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 0);
- return left;
- } else if (isnotzero(right)) {
- left->type = EINTCONST;
- left->rtype = CParser_GetBoolType();
- CInt64_SetLong(&left->data.intval, 1);
- return left;
- } else {
- left = makemonadicnode(right, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- } else {
- if (isnotzero(right)) {
- right->type = EINTCONST;
- right->rtype = CParser_GetBoolType();
- CInt64_SetLong(&right->data.intval, 1);
- } else if (iszero(right)) {
- left = makemonadicnode(left, ELOGNOT);
- left->rtype = CParser_GetBoolType();
- return makemonadicnode(left, ELOGNOT);
- }
- left = makediadicnode(left, right, ELOR);
- left->rtype = CParser_GetBoolType();
- return left;
- }
-}
-
-ENode *CExpr_NewDyadicNode(ENode *left, ENodeType nt, ENode *right) {
- switch (nt) {
- default:
- CError_FATAL(5642);
- case EADD: return CExpr_New_EADD_Node(left, right);
- case ESUB: return CExpr_New_ESUB_Node(left, right);
- case EMUL: return CExpr_New_EMUL_Node(left, right);
- case EDIV: return CExpr_New_EDIV_Node(left, right, 1);
- case EMODULO: return CExpr_New_EMODULO_Node(left, right, 1);
- case EAND: return CExpr_New_EAND_Node(left, right);
- case EXOR: return CExpr_New_EXOR_Node(left, right);
- case EOR: return CExpr_New_EOR_Node(left, right);
- case ESHL: return CExpr_New_ESHL_Node(left, right);
- case ESHR: return CExpr_New_ESHR_Node(left, right);
- case ELESS: return CExpr_New_ELESS_Node(left, right);
- case EGREATER: return CExpr_New_EGREATER_Node(left, right);
- case ELESSEQU: return CExpr_New_ELESSEQU_Node(left, right);
- case EGREATEREQU: return CExpr_New_EGREATEREQU_Node(left, right);
- case EEQU: return CExpr_New_EEQU_Node(left, right);
- case ENOTEQU: return CExpr_New_ENOTEQU_Node(left, right);
- case ELAND: return CExpr_New_ELAND_Node(left, right);
- case ELOR: return CExpr_New_ELOR_Node(left, right);
- }
-}
-
-typedef struct DyadicInfo {
- ENodeType t;
- UInt8 prec;
-} DyadicInfo;
-
-static Boolean CExpr_GetDyadicInfo(short token, DyadicInfo *info) {
- switch (token) {
- case '*':
- info->t = EMUL;
- info->prec = 20;
- return 1;
- case '/':
- info->t = EDIV;
- info->prec = 20;
- return 1;
- case '%':
- info->t = EMODULO;
- info->prec = 20;
- return 1;
- case '+':
- info->t = EADD;
- info->prec = 19;
- return 1;
- case '-':
- info->t = ESUB;
- info->prec = 19;
- return 1;
- case TK_SHL:
- info->t = ESHL;
- info->prec = 18;
- return 1;
- case TK_SHR:
- info->t = ESHR;
- info->prec = 18;
- return 1;
- case '<':
- info->t = ELESS;
- info->prec = 17;
- return 1;
- case TK_LESS_EQUAL:
- info->t = ELESSEQU;
- info->prec = 17;
- return 1;
- case '>':
- if (disallowgreaterthan)
- return 0;
- info->t = EGREATER;
- info->prec = 17;
- return 1;
- case TK_GREATER_EQUAL:
- info->t = EGREATEREQU;
- info->prec = 17;
- return 1;
- case TK_LOGICAL_EQ:
- info->t = EEQU;
- info->prec = 16;
- return 1;
- case TK_LOGICAL_NE:
- info->t = ENOTEQU;
- info->prec = 16;
- return 1;
- case '&':
- info->t = EAND;
- info->prec = 15;
- return 1;
- case '^':
- info->t = EXOR;
- info->prec = 14;
- return 1;
- case '|':
- info->t = EOR;
- info->prec = 13;
- return 1;
- case TK_LOGICAL_AND:
- info->t = ELAND;
- info->prec = 12;
- return 1;
- case TK_LOGICAL_OR:
- info->t = ELOR;
- info->prec = 11;
- return 1;
- default:
- return 0;
- }
-}
-
-static ENode *CExpr_ParseDyadicExpression(ENode *left, UInt8 prec, Boolean no_warning) {
- ENode *right;
- Boolean is_eland_or_elor;
- Boolean save_dgt;
- Boolean cont;
- DyadicInfo left_info;
- DyadicInfo right_info;
-
- save_dgt = disallowgreaterthan;
- if (!left) {
- disallowgreaterthan = 0;
- left = pm_expression();
- disallowgreaterthan = save_dgt;
- }
-
- do {
- if (!CExpr_GetDyadicInfo(tk, &left_info))
- return left;
-
- switch (left_info.t) {
- case ELAND:
- CExpr_CheckUnwantedAssignment(left);
- if (iszero(left))
- no_warning = 1;
- is_eland_or_elor = 1;
- break;
- case ELOR:
- CExpr_CheckUnwantedAssignment(left);
- if (isnotzero(left))
- no_warning = 1;
- is_eland_or_elor = 1;
- break;
- default:
- is_eland_or_elor = 0;
- }
-
- tk = lex();
- disallowgreaterthan = 0;
- right = pm_expression();
- disallowgreaterthan = save_dgt;
- inner_loop:
- if (CExpr_GetDyadicInfo(tk, &right_info)) {
- if (left_info.prec >= right_info.prec) {
- cont = (prec >= right_info.prec);
- } else {
- right = CExpr_ParseDyadicExpression(right, left_info.prec, no_warning);
- goto inner_loop;
- }
- } else {
- cont = 1;
- }
-
- if (is_eland_or_elor)
- CExpr_CheckUnwantedAssignment(right);
-
- switch (left_info.t) {
- case EDIV:
- left = CExpr_New_EDIV_Node(left, right, no_warning);
- break;
- case EMODULO:
- left = CExpr_New_EMODULO_Node(left, right, no_warning);
- break;
- default:
- left = CExpr_NewDyadicNode(left, left_info.t, right);
- }
- } while (!cont);
-
- return left;
-}
-
-static Boolean CExpr_IsBlockMoveType(Type *type) {
- switch (type->type) {
- case TYPESTRUCT:
- case TYPECLASS:
- return 1;
- case TYPEMEMBERPOINTER:
- return type->size != 4;
- default:
- return 0;
- }
-}
-
-ENode *CExpr_New_ECOND_Node(ENode *cond, ENode *expr1, ENode *expr2) {
- ENode *result;
- ENodeList *args;
- short cost;
- Conversion conv;
-
- cond = CExpr_ConvertToCondition(pointer_generation(cond));
- expr1 = pointer_generation(expr1);
- expr2 = pointer_generation(expr2);
-
- if (!IS_TYPE_INT_OR_FLOAT(cond->rtype) && !IS_TYPE_POINTER_ONLY(cond->rtype)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- cost = cond->cost + 1;
- if (expr1->cost > expr2->cost)
- cost += expr1->cost;
- else
- cost += expr2->cost;
- if (expr2->cost > cost)
- cost = expr2->cost;
- if (cost > 200)
- cost = 200;
-
- result = CExpr_NewENode(ECOND);
- result->cost = cost;
- result->rtype = expr1->rtype;
- result->flags = expr1->flags | expr2->flags;
- result->data.cond.cond = cond;
- if (ENODE_IS(expr1, EFUNCCALL) && expr1->rtype == &stvoid && (expr1->flags & ENODE_FLAG_VOLATILE) != 0) {
- result->rtype = expr2->rtype;
- result->flags = expr2->flags;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
- if (ENODE_IS(expr2, EFUNCCALL) && expr2->rtype == &stvoid && (expr2->flags & ENODE_FLAG_VOLATILE) != 0) {
- result->rtype = expr1->rtype;
- result->flags = expr1->flags;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
-
- if (
- ENODE_IS(expr1, EINDIRECT) &&
- ENODE_IS(expr2, EINDIRECT) &&
- is_typesame(expr1->rtype, expr2->rtype) &&
- ENODE_QUALS(expr1) == ENODE_QUALS(expr2) &&
- CExpr_IsBlockMoveType(expr1->rtype) &&
- !ENODE_IS(expr1->data.monadic, EBITFIELD) &&
- !ENODE_IS(expr2->data.monadic, EBITFIELD)
- ) {
- if (isnotzero(cond))
- return expr1;
- if (iszero(cond))
- return expr2;
- result->data.cond.expr1 = getnodeaddress(expr1, 0);
- result->data.cond.expr2 = getnodeaddress(expr2, 0);
- result->rtype = result->data.cond.expr1->rtype;
- result = makemonadicnode(result, EINDIRECT);
- result->rtype = TPTR_TARGET(result->rtype);
- return result;
- }
-
- if ((IS_TYPE_CLASS(expr1->rtype) || IS_TYPE_CLASS(expr2->rtype)) && !is_typesame(expr1->rtype, expr2->rtype)) {
- if (!copts.old_argmatch) {
- if (CExpr_CondOperatorMatch(expr1, expr2, &conv)) {
- CError_ASSERT(6246, !conv.x0);
- expr1 = conv.left;
- expr2 = conv.right;
- } else if (CExpr_CanImplicitlyConvert(expr1, expr2->rtype, ENODE_QUALS(expr2))) {
- if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1)))
- CError_Error(CErrorStr188);
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1))) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else {
- goto failed;
- }
-
- result->rtype = expr1->rtype;
- } else {
- args = lalloc(sizeof(ENodeList));
- args->node = expr1;
- args->next = lalloc(sizeof(ENodeList));
- args->next->node = expr2;
- args->next->next = NULL;
-
- if (CExpr_CheckOperatorConversion(':', expr1, expr2, args, &conv)) {
- CError_ASSERT(6274, !conv.x0);
- expr1 = conv.left;
- expr2 = conv.right;
- }
-
- result->rtype = expr1->rtype;
- }
- }
-
- switch (expr1->rtype->type) {
- case TYPEENUM:
- if (expr1->rtype == expr2->rtype)
- break;
- expr1 = forceintegral(expr1);
- case TYPEINT:
- if (IS_TYPE_POINTER_ONLY(expr2->rtype) || IS_TYPE_MEMBERPOINTER(expr2->rtype)) {
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- result->rtype = expr2->rtype;
- break;
- }
- case TYPEFLOAT:
- if (expr1->rtype != expr2->rtype) {
- CExpr_ArithmeticConversion(&expr1, &expr2);
- result->rtype = expr1->rtype;
- }
- break;
- case TYPEPOINTER:
- if (ENODE_IS(expr2, EINTCONST) && CInt64_IsZero(&expr2->data.intval)) {
- expr2->rtype = TYPE(&stunsignedlong);
- break;
- }
- if (IS_TYPE_POINTER_ONLY(expr2->rtype)) {
- if (IS_TYPE_CLASS(TPTR_TARGET(expr1->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(expr2->rtype))) {
- if (TPTR_TARGET(expr1->rtype) != TPTR_TARGET(expr2->rtype)) {
- if (CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr1->rtype)), TYPE_CLASS(TPTR_TARGET(expr2->rtype)), NULL, 0, 1)) {
- expr1 = CExpr_SafeClassPointerCast(
- expr1,
- TYPE_CLASS(TPTR_TARGET(expr1->rtype)),
- TYPE_CLASS(TPTR_TARGET(expr2->rtype)),
- 0, 1);
- expr1->rtype = expr2->rtype;
- } else if (CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr2->rtype)), TYPE_CLASS(TPTR_TARGET(expr1->rtype)), NULL, 0, 1)) {
- expr2 = CExpr_SafeClassPointerCast(
- expr2,
- TYPE_CLASS(TPTR_TARGET(expr2->rtype)),
- TYPE_CLASS(TPTR_TARGET(expr1->rtype)),
- 0, 1);
- expr2->rtype = expr1->rtype;
- } else {
- goto failed;
- }
- }
- result->rtype = expr1->rtype;
- break;
- }
- if (TPTR_TARGET(expr2->rtype) == &stvoid)
- result->rtype = expr2->rtype;
- }
- if (!is_typeequal(expr1->rtype, expr2->rtype)) {
- if (!copts.objective_c)
- goto failed;
- if (!CObjC_IsCompatibleType(expr1->rtype, expr2->rtype))
- goto failed;
- expr1->rtype = expr2->rtype = CObjC_GetObjCType_id(1);
- }
- break;
- case TYPEVOID:
- if (!is_typeequal(expr1->rtype, expr2->rtype))
- goto failed;
- break;
- case TYPESTRUCT:
- case TYPECLASS:
- if (!is_typeequal(expr1->rtype, expr2->rtype))
- goto failed;
- result->rtype = expr1->rtype;
- break;
- case TYPEMEMBERPOINTER:
- if (IS_TYPE_MEMBERPOINTER(expr2->rtype) && TYPE_MEMBER_POINTER(expr1->rtype)->ty2 == TYPE_MEMBER_POINTER(expr2->rtype)->ty2) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr1, expr2->rtype, ENODE_QUALS(expr2))) {
- if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1)))
- CError_Error(CErrorStr188);
- expr1 = CExpr_Convert(expr1, expr2->rtype, ENODE_QUALS(expr2), 0, 1);
- } else if (CExpr_CanImplicitlyConvert(expr2, expr1->rtype, ENODE_QUALS(expr1))) {
- expr2 = CExpr_Convert(expr2, expr1->rtype, ENODE_QUALS(expr1), 0, 1);
- } else {
- goto failed;
- }
- result->rtype = expr1->rtype;
- break;
- default:
- failed:
- CError_Error(CErrorStr245, expr1->rtype, ENODE_QUALS(expr1), expr2->rtype, ENODE_QUALS(expr2));
- return nullnode();
- }
-
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- if (isnotzero(cond))
- result = expr1;
- else if (iszero(cond))
- result = expr2;
- return result;
-}
-
-static ENode *conditional_expression(void) {
- ENode *cond;
- ENode *expr1;
- ENode *expr2;
- ENode *result;
- Boolean is_templdep_cond;
-
- is_templdep_cond = 0;
- cond = CExpr_ParseDyadicExpression(NULL, 0, 0);
- if (tk != '?')
- return cond;
-
- cond = pointer_generation(cond);
- if (!IS_TYPE_TEMPLDEPEXPR(cond->rtype)) {
- cond = CExpr_ConvertToCondition(cond);
- if (!IS_TYPE_INT_OR_FLOAT(cond->rtype) && !IS_TYPE_POINTER_ONLY(cond->rtype)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- } else {
- is_templdep_cond = 1;
- }
-
- tk = lex();
- expr1 = expression();
- if (tk != ':')
- CError_ErrorSkip(CErrorStr141);
- else
- tk = lex();
-
- expr2 = (copts.cplusplus && !copts.ARMconform) ? assignment_expression() : conditional_expression();
-
- if (is_templdep_cond || IS_TYPE_TEMPLDEPEXPR(expr1->rtype) || IS_TYPE_TEMPLDEPEXPR(expr2->rtype)) {
- result = CExpr_NewENode(ECOND);
- result->rtype = &sttemplexpr;
- result->data.cond.cond = cond;
- result->data.cond.expr1 = expr1;
- result->data.cond.expr2 = expr2;
- return result;
- }
-
- return CExpr_New_ECOND_Node(cond, expr1, expr2);
-}
-
-static ENode *CExpr_MakeOpAssNode(ENode *left, ENode *right, ENodeType nt) {
- if (left->rtype != right->rtype) {
- switch (right->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- right->rtype = TYPE_ENUM(right->rtype)->enumtype;
- break;
- default:
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- }
- if (IS_TYPE_FLOAT(left->rtype)) {
- if (IS_TYPE_INT(right->rtype) || (IS_TYPE_FLOAT(right->rtype) && left->rtype->size >= right->rtype->size))
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- } else if (IS_TYPE_INT(left->rtype)) {
- if (IS_TYPE_INT(right->rtype) && (left->rtype->size > right->rtype->size || (left->rtype->size == right->rtype->size && is_unsigned(left->rtype) == is_unsigned(right->rtype))))
- right = CExpr_AssignmentPromotion(right, left->rtype, 0, 1);
- }
- }
-
- return makediadicnode(left, right, nt);
-}
-
-static ENode *makeassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- ENode *tmp;
- ENode *funcexpr;
- ENodeList *args;
- Conversion conv;
-
- tk = lex();
- right = assignment_expression();
- if (copts.cplusplus) {
- if (copts.old_argmatch && !ENODE_IS(right, EMEMBER))
- right = pointer_generation(right);
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- if (!conv.x0) {
- if (nt == EASS)
- goto continue_anyway;
- CError_FATAL(6531);
- }
- return conv.x0;
- }
- if (IS_TYPE_CLASS(left->rtype) && CClass_AssignmentOperator(TYPE_CLASS(left->rtype)))
- CError_Error(CErrorStr144);
- }
-continue_anyway:
- if (IS_TYPE_ARRAY(left->rtype)) {
- if (copts.gcc_extensions && nt == EASS && is_typesame(left->rtype, right->rtype)) {
- tmp = makediadicnode(left, right, nt);
- tmp->flags = left->flags;
- return tmp;
- }
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- left = CExpr_LValue(pointer_generation(left), 1, 1);
- if (nt != EASS) {
- if (!IS_TYPE_INT(right->rtype)) {
- if (!IS_TYPE_ENUM(right->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- right = forceintegral(right);
- }
- if (!IS_TYPE_INT(left->rtype)) {
- if (copts.cplusplus) {
- CError_Error(CErrorStr144);
- return left;
- }
- left = forceintegral(left);
- if (!IS_TYPE_INT(left->rtype)) {
- CError_Error(CErrorStr144);
- return left;
- }
- }
- return CExpr_MakeOpAssNode(left, right, nt);
- }
-
- if (IS_TYPE_CLASS(left->rtype) && TYPE_CLASS(left->rtype)->sominfo) {
- CError_Error(CErrorStr285);
- return left;
- }
-
- if (copts.warn_implicitconv && ENODE_IS(left, EINDIRECT) && ENODE_IS(left->data.monadic, EBITFIELD) && !ENODE_IS(right, EINTCONST)) {
- copts.warn_implicitconv = 0;
- right = CExpr_AssignmentPromotion(right, left->rtype, left->flags, 1);
- copts.warn_implicitconv = 1;
- } else {
- right = CExpr_AssignmentPromotion(right, left->rtype, left->flags, 1);
- }
-
- tmp = right;
- if (IS_TYPE_FLOAT(right->rtype) && ENODE_IS(right, ETYPCON) && right->rtype->size == right->data.monadic->rtype->size)
- tmp = right->data.monadic;
-
- if (
- ENODE_IS(left, EINDIRECT) &&
- ENODE_IS(left->data.monadic, EOBJREF) &&
- ENODE_IS(tmp, EINDIRECT) &&
- (ENODE_IS(funcexpr = right->data.monadic, EFUNCCALL) || ENODE_IS(funcexpr, EFUNCCALLP)) &&
- left->rtype == funcexpr->data.funccall.functype->functype &&
- CMach_GetFunctionResultClass(funcexpr->data.funccall.functype) == 1 &&
- (args = funcexpr->data.funccall.args)
- ) {
- switch (CABI_GetStructResultArgumentIndex(funcexpr->data.funccall.functype)) {
- case 0:
- break;
- case 1:
- if ((args = args->next))
- break;
- CError_FATAL(6625);
- default:
- CError_FATAL(6626);
- }
- if (ENODE_IS(args->node, ETEMP)) {
- if (!(IS_TYPE_CLASS(left->rtype) && CClass_Destructor(TYPE_CLASS(left->rtype)))) {
- args->node = getnodeaddress(left, 0);
- return right;
- }
- }
- }
-
- right = makediadicnode(left, right, nt);
- right->flags = left->flags;
- return right;
-}
-
-static ENode *makepassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- Boolean is_array;
- Conversion conv;
-
- is_array = IS_TYPE_ARRAY(left->rtype);
- left = pointer_generation(left);
- if (copts.cplusplus) {
- tk = lex();
- right = pointer_generation(assignment_expression());
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- CError_ASSERT(6669, conv.x0);
- return conv.x0;
- }
- left = CExpr_LValue(left, 1, 1);
- } else {
- left = CExpr_LValue(left, 1, 1);
- tk = lex();
- right = pointer_generation(assignment_expression());
- }
-
- if (is_array)
- CError_Error(CErrorStr144);
-
- switch (left->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- break;
- case TYPEENUM:
- if (copts.cplusplus) {
- CError_Error(CErrorStr144);
- return left;
- }
- left = forceintegral(left);
- break;
- default:
- CError_Error(CErrorStr144);
- return left;
- }
-
- if (IS_TYPE_ENUM(right->rtype))
- right = forceintegral(right);
-
- if (iszero(right))
- return left;
-
- if (IS_TYPE_POINTER_ONLY(left->rtype)) {
- if (IS_TYPE_INT(right->rtype)) {
- if (nt == ESUBASS) {
- left = psub(left, right);
- if (ENODE_IS(left, ESUB))
- left->type = ESUBASS;
- return left;
- } else {
- left = padd(left, right);
- if (ENODE_IS(left, EADD))
- left->type = EADDASS;
- return left;
- }
- }
- CError_Error(CErrorStr144);
- return left;
- } else {
- return CExpr_MakeOpAssNode(left, right, nt);
- }
-}
-
-static ENode *makemulassignmentnode(ENode *left, ENodeType nt, short token) {
- ENode *right;
- Boolean is_array;
- Conversion conv;
-
- is_array = IS_TYPE_ARRAY(left->rtype);
- left = pointer_generation(left);
- if (copts.cplusplus) {
- tk = lex();
- right = pointer_generation(assignment_expression());
- if (CExpr_CheckOperator(token, left, right, &conv)) {
- CError_ASSERT(6753, conv.x0);
- return conv.x0;
- }
- if (!IS_TYPE_INT(left->rtype) && !(IS_TYPE_FLOAT(left->rtype) && nt != EMODASS)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
- left = CExpr_LValue(left, 1, 1);
- } else {
- if (IS_TYPE_ENUM(left->rtype))
- left = forceintegral(left);
- if (!IS_TYPE_INT(left->rtype) && !(IS_TYPE_FLOAT(left->rtype) && nt != EMODASS)) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- left = CExpr_LValue(left, 1, 1);
- tk = lex();
- right = pointer_generation(assignment_expression());
- }
-
- if (is_array)
- CError_Error(CErrorStr144);
-
- if (IS_TYPE_ENUM(right->rtype))
- right = forceintegral(right);
-
- if (IS_TYPE_INT(left->rtype) && IS_TYPE_FLOAT(right->rtype) && nt == EMODASS) {
- CError_Error(CErrorStr144);
- return nullnode();
- }
-
- return CExpr_MakeOpAssNode(left, right, nt);
-}
-
-static ENode *CExpr_TransformOpAssign(ENode *expr) {
- switch (expr->type) {
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- if (expr->rtype == TYPE(&stbool)) {
- expr = CIRTrans_TransformOpAss(expr);
- if (ENODE_IS(expr, EASS)) {
- expr->data.diadic.right = makemonadicnode(expr->data.diadic.right, ELOGNOT);
- expr->data.diadic.right->rtype = TYPE(&stbool);
- expr->data.diadic.right = makemonadicnode(expr->data.diadic.right, ELOGNOT);
- }
- }
- }
-
- return expr;
-}
-
-ENode *assignment_expression(void) {
- ENode *expr;
-
- if (tk == TK_THROW)
- return CExcept_ScanThrowExpression();
-
- expr = conditional_expression();
- switch (tk) {
- case '=':
- return makeassignmentnode(expr, EASS, tk);
- case TK_ADD_ASSIGN:
- return CExpr_TransformOpAssign(makepassignmentnode(expr, EADDASS, tk));
- case TK_SUB_ASSIGN:
- return CExpr_TransformOpAssign(makepassignmentnode(expr, ESUBASS, tk));
- case TK_MULT_ASSIGN:
- expr = makemulassignmentnode(expr, EMULASS, tk);
- if (ENODE_IS(expr, EMULASS) && CExpr_IsOne(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_DIV_ASSIGN:
- expr = makemulassignmentnode(expr, EDIVASS, tk);
- if (ENODE_IS(expr, EDIVASS)) {
- if (iszero(expr->data.diadic.right) && !IS_TYPE_FLOAT(expr->rtype)) {
- CError_Warning(CErrorStr139);
- return expr->data.diadic.left;
- }
- if (CExpr_IsOne(expr->data.diadic.right))
- return expr->data.diadic.left;
- }
- return CExpr_TransformOpAssign(expr);
- case TK_MOD_ASSIGN:
- expr = makemulassignmentnode(expr, EMODASS, tk);
- if (ENODE_IS(expr, EMODASS)) {
- if (iszero(expr->data.diadic.right)) {
- CError_Warning(CErrorStr139);
- return expr->data.diadic.left;
- }
- }
- return CExpr_TransformOpAssign(expr);
- case TK_SHL_ASSIGN:
- expr = makeassignmentnode(expr, ESHLASS, tk);
- if (ENODE_IS(expr, ESHLASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_SHR_ASSIGN:
- expr = makeassignmentnode(expr, ESHRASS, tk);
- if (ENODE_IS(expr, ESHRASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_AND_ASSIGN:
- expr = makeassignmentnode(expr, EANDASS, tk);
- if (ENODE_IS(expr, EANDASS) && CExpr_AllBitsSet(expr->data.diadic.right))
- return expr->data.diadic.left;
- return expr;
- case TK_XOR_ASSIGN:
- expr = makeassignmentnode(expr, EXORASS, tk);
- if (ENODE_IS(expr, EXORASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- case TK_OR_ASSIGN:
- expr = makeassignmentnode(expr, EORASS, tk);
- if (ENODE_IS(expr, EORASS) && iszero(expr->data.diadic.right))
- return expr->data.diadic.left;
- return CExpr_TransformOpAssign(expr);
- default:
- return expr;
- }
-}
-
-ENode *conv_assignment_expression(void) {
- return pointer_generation(assignment_expression());
-}
-
-static Boolean CExpr_HasSideEffect(ENode *expr) {
- switch (expr->type) {
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EROTL:
- case EROTR:
- case EBITFIELD:
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case ETEMP:
- case EARGOBJ:
- case ELOCOBJ:
- case EOBJLIST:
- case EMEMBER:
- case EVECTOR128CONST:
- return 0;
- case ETYPCON:
- return IS_TYPE_VOID(expr->rtype);
- case EINDIRECT:
- switch (expr->data.monadic->type) {
- case EFUNCCALL:
- case EFUNCCALLP:
- return 1;
- default:
- return 0;
- }
- case ECOMMA:
- return CInline_ExpressionHasSideEffect(expr->data.diadic.right);
- case ECOND:
- return CInline_ExpressionHasSideEffect(expr->data.cond.expr1) || CInline_ExpressionHasSideEffect(expr->data.cond.expr2);
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EFORCELOAD:
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EFUNCCALL:
- case EFUNCCALLP:
- case EMFPOINTER:
- case ENULLCHECK:
- case EPRECOMP:
- case ELABEL:
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- case EINITTRYCATCH:
- case EINSTRUCTION:
- return 1;
- default:
- CError_FATAL(7056);
- return 0;
- }
-}
-
-void CExpr_CheckUnusedExpression(ENode *expr) {
- ENode *scan;
- ENodeList *arg;
-
- if (copts.warn_possunwant) {
- scan = expr;
- while (ENODE_IS(scan, ETYPCON))
- scan = scan->data.monadic;
- if (ENODE_IS(scan, EEQU)) {
- CError_Warning(CErrorStr208);
- return;
- }
- }
-
- if (copts.warn_no_side_effect) {
- if (!CExpr_HasSideEffect(expr)) {
- CError_Warning(CErrorStr369);
- return;
- }
- }
-
- if (copts.warn_resultnotused) {
- scan = expr;
- if (IS_TYPE_VOID(expr->rtype))
- return;
- if (ENODE_IS(expr, EINDIRECT))
- scan = expr->data.monadic;
-
- switch (scan->type) {
- case EFUNCCALL:
- case EFUNCCALLP:
- if (ENODE_IS(scan->data.funccall.funcref, EOBJREF) && scan->data.funccall.funcref->data.objref->name == asop_name_node)
- return;
- if (CMach_GetFunctionResultClass(scan->data.funccall.functype) == 1 && (arg = scan->data.funccall.args)) {
- switch (CABI_GetStructResultArgumentIndex(scan->data.funccall.functype)) {
- case 0:
- break;
- case 1:
- if ((arg = arg->next))
- break;
- CError_FATAL(7110);
- default:
- CError_FATAL(7111);
- }
-
- if (!ENODE_IS(arg->node, ETEMP))
- return;
- }
- CError_Warning(CErrorStr370);
- }
- }
-}
-
-ENode *s_expression(void) {
- ENode *left;
- ENode *right;
- Conversion conv;
-
- left = assignment_expression();
- while (tk == ',') {
- left = pointer_generation(left);
- tk = lex();
- right = pointer_generation(assignment_expression());
-
- if (copts.cplusplus && CExpr_CheckOperator(',', left, right, &conv)) {
- CError_ASSERT(7143, left = conv.x0);
- } else {
- CExpr_CheckUnusedExpression(left);
- left = makecommaexpression(left, right);
- left->rtype = right->rtype;
- }
- }
-
- return left;
-}
-
-ENode *expression(void) {
- return pointer_generation(s_expression());
-}
-
-CInt64 CExpr_IntegralConstExprType(Type **tint) {
- ENode *expr;
-
- expr = pointer_generation(conditional_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- *tint = expr->rtype;
- return expr->data.intval;
- case TYPEENUM:
- *tint = TYPE_ENUM(expr->rtype)->enumtype;
- return expr->data.intval;
- }
- }
-
- CError_Error(CErrorStr124);
- *tint = TYPE(&stchar);
- return cint64_zero;
-}
-
-ENode *CExpr_IntegralConstOrDepExpr(void) {
- ENode *expr;
-
- expr = pointer_generation(conditional_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- return expr;
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- return expr;
- default:
- CError_FATAL(7209);
- }
- }
-
- if (CTemplTool_IsTemplateArgumentDependentExpression(expr))
- return expr;
-
- CError_Error(CErrorStr124);
- expr = nullnode();
- expr->rtype = TYPE(&stchar);
- return expr;
-}
-
-CInt64 CExpr_IntegralConstExpr(void) {
- Type *throwaway;
- return CExpr_IntegralConstExprType(&throwaway);
-}
-
-void CExpr_CheckUnwantedAssignment(ENode *expr) {
- if (copts.warn_possunwant) {
- if (ENODE_IS(expr, EASS) && !(expr->flags & ENODE_FLAG_80))
- CError_Warning(CErrorStr207);
- }
-}
-
-Boolean CExpr_ParseAsmExpr(Object **objptr, CInt64 *valptr) {
- ENode *expr;
-
- if (objptr)
- *objptr = NULL;
- *valptr = cint64_zero;
-
- expr = pointer_generation(assignment_expression());
- if (ENODE_IS(expr, EINTCONST)) {
- *valptr = expr->data.intval;
- return 1;
- }
-
- if (objptr) {
- switch (expr->type) {
- case EINDIRECT:
- if (CInit_RelocInitCheck(expr->data.monadic, objptr, valptr, 1))
- return 1;
- break;
- case EOBJREF:
- *objptr = expr->data.objref;
- while ((*objptr)->datatype == DALIAS)
- *objptr = (*objptr)->u.alias.object;
- return 1;
- case EMEMBER:
- if (expr->data.emember->list->object->otype == OT_OBJECT) {
- if (expr->data.emember->list->next && expr->data.emember->list->next->object->otype == OT_OBJECT)
- CError_Error(CErrorStr199);
- *objptr = OBJECT(expr->data.emember->list->object);
- while ((*objptr)->datatype == DALIAS)
- *objptr = (*objptr)->u.alias.object;
- return 1;
- }
- break;
- case EOBJLIST:
- CError_Error(CErrorStr199);
- return 0;
- }
- }
-
- CError_Error(CErrorStr155);
- return 0;
-}
diff --git a/compiler_and_linker/unsorted/CExpr2.c b/compiler_and_linker/unsorted/CExpr2.c
deleted file mode 100644
index e5c662a..0000000
--- a/compiler_and_linker/unsorted/CExpr2.c
+++ /dev/null
@@ -1,4206 +0,0 @@
-#include "compiler/CExpr.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CInit.h"
-#include "compiler/CInt64.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CObjCModern.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateFunc.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-#ifdef __MWERKS__
-#undef va_start
-#undef va_arg
-#define va_start(ap, parm) ap = __va_start(parm)
-#define __va_start(parm) (va_list) (&parm + 1)
-//#define va_arg(ap, type) ((((type *) (ap = (va_list) (( ((long) ap + sizeof(type) - 1) & ~(sizeof(type)) ) + sizeof(type) ) ))[-1]))
-#define va_arg(ap, type) (*(((type *) (ap = (char *)((((unsigned long)ap + __builtin_align(type) - 1) & ~(__builtin_align(type) - 1) ) + sizeof(type)))) - 1))
-#endif
-
-ENode *assign_node;
-Boolean temp_reference_init;
-static SInt32 assign_value; // type?
-static ENode *firstarrayexpr;
-static Match5 user_std_match;
-static Boolean cexpr_hascall;
-static Boolean cexpr_esearch_bool[MAXEXPR];
-static Boolean cexpr_rsearch_bool[MAXEXPR];
-static CExprSearchCB cexpr_esearch_callback;
-static CExprReplaceCB cexpr_rsearch_callback;
-static Type *cexpr_left_conversion_type;
-static Type *cexpr_right_conversion_type;
-
-static FuncArg mon_arg = {NULL, NULL, NULL, NULL, 0, 0, 0, 0};
-static FuncArg diadic_arg2 = {NULL, NULL, NULL, NULL, 0, 0, 0, 0};
-static FuncArg diadic_arg1 = {&diadic_arg1, NULL, NULL, NULL, 0, 0, 0, 0};
-
-static void CExpr_RecSearchExprTree(ENode *expr) {
- ENodeList *list;
-
-restart:
- if (cexpr_esearch_bool[expr->type])
- cexpr_esearch_callback(expr);
-
- switch (expr->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- goto restart;
- 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:
- CExpr_RecSearchExprTree(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- goto restart;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case EARGOBJ:
- case ELOCOBJ:
- case ELABEL:
- case EOBJLIST:
- case EMEMBER:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return;
- case EFUNCCALL:
- case EFUNCCALLP:
- for (list = expr->data.funccall.args; list; list = list->next)
- CExpr_RecSearchExprTree(list->node);
- expr = expr->data.funccall.funcref;
- goto restart;
- case ENULLCHECK:
- CExpr_RecSearchExprTree(expr->data.nullcheck.nullcheckexpr);
- expr = expr->data.nullcheck.condexpr;
- goto restart;
- case EMFPOINTER:
- CExpr_RecSearchExprTree(expr->data.mfpointer.accessnode);
- expr = expr->data.mfpointer.mfpointer;
- goto restart;
- case ECOND:
- CExpr_RecSearchExprTree(expr->data.cond.cond);
- CExpr_RecSearchExprTree(expr->data.cond.expr1);
- expr = expr->data.cond.expr2;
- goto restart;
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- CExpr_RecSearchExprTree(expr->data.newexception.initexpr);
- expr = expr->data.newexception.tryexpr;
- goto restart;
- case EINITTRYCATCH:
- if (expr->data.itc.initexpr)
- CExpr_RecSearchExprTree(expr->data.itc.initexpr);
- if (expr->data.itc.tryexpr)
- CExpr_RecSearchExprTree(expr->data.itc.tryexpr);
- if (expr->data.itc.catchexpr)
- CExpr_RecSearchExprTree(expr->data.itc.catchexpr);
- if (expr->data.itc.result)
- CExpr_RecSearchExprTree(expr->data.itc.result);
- return;
- default:
- CError_FATAL(128);
- }
-}
-
-void CExpr_SearchExprTree(ENode *expr, CExprSearchCB callback, int count, ...) {
- va_list ap;
- short i;
-
- cexpr_esearch_callback = callback;
-
- va_start(ap, count);
- for (i = 0; i < MAXEXPR; i++)
- cexpr_esearch_bool[i] = 0;
- i = 0;
- while ((short) i < count) {
- cexpr_esearch_bool[va_arg(ap, int)] = 1;
- ++i;
- }
- va_end(ap);
-
- CExpr_RecSearchExprTree(expr);
-}
-
-static ENode *CExpr_RecSearchExprTreeReplace(ENode *expr) {
- ENodeList *list;
- ENode *replaced;
-
- if (cexpr_rsearch_bool[expr->type]) {
- replaced = cexpr_rsearch_callback(expr);
- if (!replaced)
- return expr;
- expr = replaced;
- }
-
- switch (expr->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr->data.monadic = CExpr_RecSearchExprTreeReplace(expr->data.monadic);
- return expr;
- 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:
- expr->data.diadic.left = CExpr_RecSearchExprTreeReplace(expr->data.diadic.left);
- expr->data.diadic.right = CExpr_RecSearchExprTreeReplace(expr->data.diadic.right);
- return expr;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case EARGOBJ:
- case ELOCOBJ:
- case ELABEL:
- case EMEMBER:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
- case EFUNCCALL:
- case EFUNCCALLP:
- for (list = expr->data.funccall.args; list; list = list->next)
- list->node = CExpr_RecSearchExprTreeReplace(list->node);
- expr->data.funccall.funcref = CExpr_RecSearchExprTreeReplace(expr->data.funccall.funcref);
- return expr;
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CExpr_RecSearchExprTreeReplace(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CExpr_RecSearchExprTreeReplace(expr->data.nullcheck.condexpr);
- return expr;
- case EMFPOINTER:
- expr->data.mfpointer.accessnode = CExpr_RecSearchExprTreeReplace(expr->data.mfpointer.accessnode);
- expr->data.mfpointer.mfpointer = CExpr_RecSearchExprTreeReplace(expr->data.mfpointer.mfpointer);
- return expr;
- case ECOND:
- expr->data.cond.cond = CExpr_RecSearchExprTreeReplace(expr->data.cond.cond);
- expr->data.cond.expr1 = CExpr_RecSearchExprTreeReplace(expr->data.cond.expr1);
- expr->data.cond.expr2 = CExpr_RecSearchExprTreeReplace(expr->data.cond.expr2);
- return expr;
- default:
- CError_FATAL(220);
- return NULL;
- }
-}
-
-ENode *CExpr_SearchExprTreeReplace(ENode *expr, CExprReplaceCB callback, int count, ...) {
- va_list ap;
- short i;
-
- cexpr_rsearch_callback = callback;
-
- va_start(ap, count);
- for (i = 0; i < MAXEXPR; i++)
- cexpr_rsearch_bool[i] = 0;
- i = 0;
- while ((short) i < count) {
- cexpr_rsearch_bool[va_arg(ap, int)] = 1;
- ++i;
- }
- va_end(ap);
-
- return CExpr_RecSearchExprTreeReplace(expr);
-}
-
-static void CExpr_HasFuncCallCallBack(ENode *expr) {
- cexpr_hascall = 1;
-}
-
-Boolean CExpr_HasFuncCall(ENode *expr) {
- cexpr_hascall = 0;
- CExpr_SearchExprTree(expr, CExpr_HasFuncCallCallBack, 2, EFUNCCALL, EFUNCCALLP);
- return cexpr_hascall;
-}
-
-void CExpr_AliasTransform(ENode *expr) {
- ENode *n;
-
- Object *obj = expr->data.objref;
- if (obj->u.alias.offset) {
- n = makediadicnode(
- create_objectrefnode(obj->u.alias.object),
- intconstnode(TYPE(&stunsignedlong), obj->u.alias.offset),
- EADD);
- *expr = *n;
- } else {
- expr->data.objref = obj->u.alias.object;
- }
-}
-
-ENode *CExpr_UnaryFloatExpression(ENode *expr) {
- return expr;
-}
-
-ENode *CExpr_BinaryFloatExpression(ENode *expr) {
- return expr;
-}
-
-ENode *CExpr_NewENode(ENodeType ty) {
- ENode *expr = lalloc(sizeof(ENode));
- memclrw(expr, sizeof(ENode));
- expr->type = ty;
- return expr;
-}
-
-ENode *CExpr_NewTemplDepENode(TemplDepSubType t) {
- ENode *expr = CExpr_NewENode(ETEMPLDEP);
- expr->rtype = &sttemplexpr;
- expr->data.templdep.subtype = t;
- return expr;
-}
-
-ENode *nullnode(void) {
- ENode *expr = CExpr_NewENode(EINTCONST);
- expr->rtype = (Type *) &stsignedlong;
- return expr;
-}
-
-ENode *intconstnode(Type *type, SInt32 value) {
- ENode *expr = CExpr_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, value);
- return expr;
-}
-
-ENode *stringconstnode(char *str) {
- ENode *expr;
- SInt32 size;
-
- size = strlen(str) + 1;
- expr = CExpr_NewENode(ESTRINGCONST);
- expr->rtype = CDecl_NewArrayType((Type *) &stchar, size);
- expr->data.string.size = size;
- expr->data.string.data = str;
- expr->data.string.ispascal = 0;
- if (copts.const_strings)
- expr->flags = Q_CONST;
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- return expr;
-}
-
-ENode *forceintegral(ENode *expr) {
- if (!IS_TYPE_ENUM(expr->rtype)) {
- CError_Error(CErrorStr144);
- return nullnode();
- } else {
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- return expr;
- }
-}
-
-ENode *makemonadicnode(ENode *inner, ENodeType ty) {
- ENode *expr = lalloc(sizeof(ENode));
- expr->type = ty;
- if ((expr->cost = inner->cost) == 0)
- expr->cost = 1;
- expr->flags = inner->flags & ENODE_FLAG_QUALS;
- expr->rtype = inner->rtype;
- expr->data.monadic = inner;
- return expr;
-}
-
-ENode *makediadicnode(ENode *left, ENode *right, ENodeType ty) {
- ENode *expr = lalloc(sizeof(ENode));
- expr->type = ty;
- expr->rtype = left->rtype;
- expr->data.diadic.left = left;
- expr->data.diadic.right = right;
-
- if (left->cost != right->cost) {
- expr->cost = right->cost;
- if (left->cost > expr->cost)
- expr->cost = left->cost;
- } else {
- expr->cost = right->cost + 1;
- if (expr->cost > 200)
- expr->cost = 200;
- }
-
- expr->flags = (left->flags | right->flags) & ENODE_FLAG_QUALS;
- return expr;
-}
-
-ENode *makecommaexpression(ENode *left, ENode *right) {
- ENode *expr;
-
- if (ENODE_IS(right, EINDIRECT) && !ENODE_IS(right->data.monadic, EBITFIELD)) {
- Boolean savecpp = copts.cplusplus;
- copts.cplusplus = 1;
- expr = makediadicnode(left, getnodeaddress(right, 0), ECOMMA);
- copts.cplusplus = savecpp;
- expr->rtype = expr->data.diadic.right->rtype;
- expr = makemonadicnode(expr, EINDIRECT);
- } else {
- expr = makediadicnode(left, right, ECOMMA);
- }
-
- expr->rtype = right->rtype;
- expr->flags = right->flags;
- return expr;
-}
-
-short iszero(ENode *expr) {
- switch (expr->type) {
- case EINTCONST:
- return CInt64_IsZero(&expr->data.intval);
- case EFLOATCONST:
- return CMach_FloatIsZero(expr->data.floatval);
- default:
- return 0;
- }
-}
-
-short isnotzero(ENode *expr) {
- Object *obj;
-
- switch (expr->type) {
- case EINTCONST:
- return !CInt64_IsZero(&expr->data.intval);
- case EFLOATCONST:
- return !CMach_FloatIsZero(expr->data.floatval);
- case ESTRINGCONST:
- case ETEMP:
- return 1;
- case EOBJREF:
- obj = expr->data.objref;
- break;
- case EADD:
- case ESUB:
- if (ENODE_IS(expr->data.diadic.left, EOBJREF) && ENODE_IS(expr->data.diadic.right, EINTCONST)) {
- obj = expr->data.diadic.left->data.objref;
- break;
- }
- if (ENODE_IS(expr->data.diadic.left, EINTCONST) && ENODE_IS(expr->data.diadic.right, EOBJREF)) {
- obj = expr->data.diadic.right->data.objref;
- break;
- }
- return 0;
- default:
- return 0;
- }
-
- switch (obj->datatype) {
- case DLOCAL:
- return 1;
- default:
- return 0;
- }
-}
-
-Boolean CExpr_IsOne(ENode *expr) {
- if (ENODE_IS(expr, EINTCONST))
- return CInt64_Equal(expr->data.intval, cint64_one);
- else if (ENODE_IS(expr, EFLOATCONST))
- return CMach_FloatIsOne(expr->data.floatval);
- else
- return 0;
-}
-
-Boolean CExpr_AllBitsSet(ENode *expr) {
- SInt32 v;
-
- if (ENODE_IS(expr, EINTCONST)) {
- switch (expr->rtype->size) {
- case 1:
- v = CInt64_GetULong(&expr->data.intval) & 0xFF;
- return v == 0xFF;
- case 2:
- v = CInt64_GetULong(&expr->data.intval) & 0xFFFF;
- return v == 0xFFFF;
- case 3:
- v = CInt64_GetULong(&expr->data.intval) & 0xFFFFFF;
- return v == 0xFFFFFF;
- case 4:
- v = CInt64_GetULong(&expr->data.intval) & 0xFFFFFFFF;
- return v == 0xFFFFFFFF;
- default:
- return CInt64_Equal(expr->data.intval, cint64_negone);
- }
- }
-
- return 0;
-}
-
-ENode *CExpr_NewETEMPNode(Type *type, Boolean assign_id) {
- ENode *expr = lalloc(sizeof(ENode));
- expr->type = ETEMP;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = CDecl_NewPointerType(type);
- expr->data.temp.type = type;
- expr->data.temp.uniqueid = assign_id ? CParser_GetUniqueID() : 0;
- expr->data.temp.needs_dtor = 0;
- return expr;
-}
-
-static ENode *CExpr_DerefETEMPCopy(ENode *expr) {
- ENode *copy;
-
- CError_ASSERT(636, IS_TYPE_POINTER_ONLY(expr->rtype));
-
- copy = lalloc(sizeof(ENode));
- *copy = *expr;
- copy = makemonadicnode(copy, EINDIRECT);
- copy->rtype = TYPE_POINTER(copy->rtype)->target;
- return copy;
-}
-
-ENode *CExpr_GetETEMPCopy(ENode *expr) {
- ENode *newnode;
- ENode *assnode;
- ENode *finalnode;
-
- newnode = CExpr_NewETEMPNode(expr->rtype, 1);
- newnode->flags = expr->flags;
-
- assnode = makediadicnode(CExpr_DerefETEMPCopy(newnode), expr, EASS);
- assnode->data.diadic.right = lalloc(sizeof(ENode));
- *assnode->data.diadic.right = *expr;
- *expr = *assnode;
-
- finalnode = makemonadicnode(newnode, EINDIRECT);
- finalnode->rtype = expr->rtype;
- return finalnode;
-}
-
-ENode *integralpromote(ENode *expr) {
- if (!IS_TYPE_INT(expr->rtype))
- expr = forceintegral(expr);
-
- if (TYPE_INTEGRAL(expr->rtype)->integral >= IT_INT)
- return expr;
-
- if (!ENODE_IS(expr, EINTCONST))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = (Type *) &stsignedint;
-
- return expr;
-}
-
-CInt64 CExpr_IntConstConvert(Type *a, Type *b, CInt64 val) {
- if (a == (Type *) &stbool)
- return CMach_CalcIntDiadic(b, val, TK_LOGICAL_NE, cint64_zero);
- else
- return CMach_CalcIntDiadic(a, val, '+', cint64_zero);
-}
-
-ENode *promote(ENode *expr, Type *type) {
- if (ENODE_IS(expr, EINTCONST)) {
- if (IS_TYPE_FLOAT(type)) {
- expr->type = EFLOATCONST;
- expr->data.floatval = CMach_CalcFloatConvertFromInt(expr->rtype, expr->data.intval);
- } else {
- expr->data.intval = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval);
- }
- expr->rtype = type;
- return expr;
- }
- if (ENODE_IS(expr, EFLOATCONST)) {
- if (IS_TYPE_FLOAT(type)) {
- expr->data.floatval = CMach_CalcFloatConvert(type, expr->data.floatval);
- expr->rtype = type;
- return expr;
- } else if (IS_TYPE_INT(type)) {
- expr->data.intval = CMach_CalcIntConvertFromFloat(type, expr->data.floatval);
- expr->type = EINTCONST;
- expr->rtype = type;
- return expr;
- }
- }
-
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- return expr;
-}
-
-void CExpr_ArithmeticConversion(ENode **left, ENode **right) {
- switch ((*left)->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- (*left)->rtype = TYPE_ENUM((*left)->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr144);
- (*left) = nullnode();
- }
-
- switch ((*right)->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- (*right)->rtype = TYPE_ENUM((*right)->rtype)->enumtype;
- break;
- default:
- CError_Error(CErrorStr144);
- (*right) = nullnode();
- }
-
- if (IS_TYPE_FLOAT((*left)->rtype) || IS_TYPE_FLOAT((*right)->rtype)) {
- if ((*left)->rtype != (*right)->rtype) {
- if (TYPE_INTEGRAL((*left)->rtype)->integral > TYPE_INTEGRAL((*right)->rtype)->integral)
- *right = promote(*right, (*left)->rtype);
- else
- *left = promote(*left, (*right)->rtype);
- }
- return;
- }
-
- *left = integralpromote(*left);
- *right = integralpromote(*right);
- if ((*left)->rtype != (*right)->rtype) {
- if (TYPE_INTEGRAL((*left)->rtype)->integral < TYPE_INTEGRAL((*right)->rtype)->integral) {
- ENode **tmp = left;
- left = right;
- right = tmp;
- }
-
- if ((*left)->rtype->size == (*right)->rtype->size && !is_unsigned((*left)->rtype) && is_unsigned((*right)->rtype)) {
- if ((*left)->rtype == (Type *) &stsignedlong) {
- *left = promote(*left, (Type *) &stunsignedlong);
- } else {
- CError_ASSERT(838, (*left)->rtype == (Type *) &stsignedlonglong);
- *left = promote(*left, (Type *) &stunsignedlonglong);
- }
- }
-
- *right = promote(*right, (*left)->rtype);
- }
-}
-
-static ENode *CExpr_GetEA(ENode *expr) {
- ENode *copy;
-
- for (;;) {
- switch (expr->type) {
- case EINDIRECT:
- expr = expr->data.monadic;
- for (;;) {
- switch (expr->type) {
- case EOBJREF:
- copy = lalloc(sizeof(ENode));
- *copy = *expr;
- return copy;
- case ECOMMA:
- expr = expr->data.diadic.right;
- continue;
- default:
- return CExpr_GetETEMPCopy(expr);
- }
- }
- break;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- expr = expr->data.monadic;
- continue;
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- expr = expr->data.monadic;
- continue;
- case ECOMMA:
- expr = expr->data.diadic.right;
- continue;
- default:
- return NULL;
- }
- }
-}
-
-ENode *CExpr_TempModifyExpr(ENode *expr) {
- Type *type;
- ENode *left;
- ENode *right;
- ENode *eanode;
- ENode *tempnode;
- ENode *indnode;
- ENode *truenode;
-
- type = expr->rtype;
- tempnode = CExpr_NewETEMPNode(type, 1);
- eanode = CExpr_GetEA(expr);
- if (!eanode) {
- CError_Error(CErrorStr142);
- return expr;
- }
-
- // tempnode = expr
- left = makemonadicnode(tempnode, EINDIRECT);
- left->rtype = type;
- left = makediadicnode(left, expr, EASS);
-
- // eanode = true
- indnode = makemonadicnode(eanode, EINDIRECT);
- indnode->rtype = type;
- truenode = nullnode();
- truenode->rtype = (Type *) &stbool;
- CInt64_SetLong(&truenode->data.intval, 1);
- right = makediadicnode(indnode, truenode, EASS);
-
- expr = makediadicnode(left, right, ECOMMA);
-
- indnode = makemonadicnode(tempnode, EINDIRECT);
- indnode->rtype = type;
- return makediadicnode(expr, indnode, ECOMMA);
-}
-
-Boolean CExpr_IsLValue(ENode *expr) {
- while (!ENODE_IS(expr, EINDIRECT)) {
- switch (expr->type) {
- case EPREINC:
- case EPREDEC:
- return copts.cplusplus;
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- if (!copts.cplusplus)
- return 0;
- expr = expr->data.diadic.left;
- continue;
- case ECOMMA:
- if (!copts.cplusplus)
- return 0;
- expr = expr->data.diadic.right;
- continue;
- case ECOND:
- if (
- copts.cplusplus &&
- is_typesame(expr->data.cond.expr1->rtype, expr->data.cond.expr2->rtype) &&
- (expr->data.cond.expr1->rtype->type != TYPEPOINTER || (UInt32) (expr->data.cond.expr1->flags & ENODE_FLAG_QUALS) == (expr->data.cond.expr2->flags & ENODE_FLAG_QUALS))
- ) {
- return CExpr_IsLValue(expr->data.cond.expr1) && CExpr_IsLValue(expr->data.cond.expr2);
- }
- return 0;
- default:
- return 0;
- }
- }
-
- expr = expr->data.monadic;
- switch (expr->type) {
- case ETEMP:
- return 0;
- case EFUNCCALL:
- if (expr->data.funccall.functype->functype->type != TYPEPOINTER || (expr->data.funccall.functype->flags & FUNC_IS_CTOR))
- return 0;
- default:
- return 1;
- }
-}
-
-ENode *CExpr_LValue(ENode *expr, Boolean flag1, Boolean flag2) {
- ENode *eanode;
- ENode *tmpnode;
-
-loop:
- switch (expr->type) {
- case ETYPCON:
- if (copts.pointercast_lvalue || !copts.ANSIstrict) {
- if (expr->rtype->type == TYPEPOINTER && expr->data.monadic->rtype->type == TYPEPOINTER) {
- switch (expr->data.monadic->type) {
- case EINDIRECT:
- case ETYPCON:
- expr->data.monadic->rtype = expr->rtype;
- expr->data.monadic->flags = expr->flags;
- expr = expr->data.monadic;
- goto loop;
- }
- }
- }
- break;
- case EINDIRECT:
- if (flag2) {
- if (!CExpr_IsLValue(expr))
- CError_Warning(CErrorStr142);
-
- if (
- ENODE_IS(expr->data.monadic, EOBJREF) &&
- expr->data.monadic->data.objref->name == this_name_node &&
- cscope_currentfunc &&
- cscope_currentclass &&
- expr->data.monadic->data.objref == CClass_ThisSelfObject())
- CError_Error(CErrorStr189);
- }
- if (flag1) {
- if (CParser_IsConst(expr->rtype, expr->flags & ENODE_FLAG_QUALS))
- CError_Error(CErrorStr179);
- }
- return expr;
- case EPREINC:
- case EPREDEC:
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case ECOMMA:
- if (copts.cplusplus) {
- if ((eanode = CExpr_GetEA(expr))) {
- tmpnode = makediadicnode(expr, eanode, ECOMMA);
- tmpnode->rtype = tmpnode->data.diadic.right->rtype;
- tmpnode = makemonadicnode(tmpnode, EINDIRECT);
- tmpnode->rtype = expr->rtype;
- return tmpnode;
- }
- CError_Error(CErrorStr190);
- return expr;
- }
- break;
- case ECOND:
- if (
- copts.cplusplus &&
- is_typesame(expr->data.cond.expr1->rtype, expr->data.cond.expr2->rtype) &&
- (expr->data.cond.expr1->rtype->type != TYPEPOINTER || (UInt32) (expr->data.cond.expr1->flags & ENODE_FLAG_QUALS) == (expr->data.cond.expr2->flags & ENODE_FLAG_QUALS))
- ) {
- expr->data.cond.expr1 = CExpr_LValue(expr->data.cond.expr1, flag1, flag2);
- expr->data.cond.expr2 = CExpr_LValue(expr->data.cond.expr2, flag1, flag2);
- if (ENODE_IS(expr->data.cond.expr1, EINDIRECT) && ENODE_IS(expr->data.cond.expr2, EINDIRECT)) {
- if (!ENODE_IS(expr->data.cond.expr1->data.monadic, EBITFIELD) && !ENODE_IS(expr->data.cond.expr2->data.monadic, EBITFIELD)) {
- expr->data.cond.expr1 = getnodeaddress(expr->data.cond.expr1, 0);
- expr->data.cond.expr2 = getnodeaddress(expr->data.cond.expr2, 0);
- expr->rtype = expr->data.cond.expr1->rtype;
- tmpnode = makemonadicnode(expr, EINDIRECT);
- tmpnode->rtype = TYPE_POINTER(tmpnode->rtype)->target;
- return tmpnode;
- }
- }
- }
- break;
- }
-
- if (flag2)
- CError_Error(CErrorStr142);
- return expr;
-}
-
-ENode *CExpr_MakeObjRefNode(Object *obj, Boolean flag) {
- ENode *expr;
-
- if (obj->sclass == TK_TYPEDEF) {
- CError_Error(CErrorStr141);
- return intconstnode((Type *) &void_ptr, 0);
- }
-
- expr = lalloc(sizeof(ENode));
- memclrw(expr, sizeof(ENode));
- expr->type = EOBJREF;
- expr->data.objref = obj;
- expr->rtype = CDecl_NewPointerType(obj->type);
-
- if (!IS_TYPE_FUNC(obj->type))
- expr->flags = obj->qual & ENODE_FLAG_QUALS;
- if (flag)
- obj->flags |= OBJECT_USED;
-
- return expr;
-}
-
-ENode *create_objectrefnode(Object *obj) {
- if (name_obj_check && !name_obj_check(NULL, obj))
- return intconstnode((Type *) &void_ptr, 0);
- return CExpr_MakeObjRefNode(obj, 1);
-}
-
-ENode *create_objectnode2(Object *obj) {
- ENode *expr;
-
- if (name_obj_check && !name_obj_check(NULL, obj))
- return nullnode();
-
- expr = makemonadicnode(CExpr_MakeObjRefNode(obj, 1), EINDIRECT);
- expr->rtype = TYPE_POINTER(expr->rtype)->target;
- return expr;
-}
-
-ENode *create_objectnode(Object *obj) {
- return checkreference(create_objectnode2(obj));
-}
-
-static ENode *CExpr_ExpandArg(ENode *expr, Type *type) {
- if (ENODE_IS(expr, ETYPCON) && IS_TYPE_FLOAT(type)) {
- expr->rtype = type;
- return expr;
- } else {
- return promote(expr, type);
- }
-}
-
-ENode *CExpr_IsTempConstruction(ENode *expr, Type *type, ENode **resultexpr) {
- ENodeList *args;
- ENode *funccall;
- ENode *funcref;
-
- if (
- !ENODE_IS(expr, EINDIRECT) ||
- expr->rtype != type ||
- !ENODE_IS((funccall = expr->data.monadic), EFUNCCALL) ||
- !(args = funccall->data.funccall.args)
- )
- return NULL;
-
- if (!ENODE_IS((funcref = funccall->data.funccall.funcref), EOBJREF) || !CClass_IsConstructor(funcref->data.objref)) {
- if (expr->data.monadic->data.funccall.functype->functype != type)
- return NULL;
- if (CABI_GetStructResultArgumentIndex(expr->data.monadic->data.funccall.functype) == 1) {
- args = args->next;
- CError_ASSERT(1277, args);
- }
- }
-
- if (resultexpr)
- *resultexpr = args->node;
- return expr->data.monadic;
-}
-
-ENode *CExpr_AdjustFunctionCall(ENode *expr) {
- ENodeList *list;
-
- switch (expr->data.funccall.functype->functype->type) {
- case TYPECLASS:
- CDecl_CompleteType(expr->data.funccall.functype->functype);
- case TYPESTRUCT:
- if (!expr->data.funccall.functype->functype->size)
- CError_Error(CErrorStr136, expr->data.funccall.functype->functype, 0);
- }
-
- if (CMach_GetFunctionResultClass(expr->data.funccall.functype)) {
- list = lalloc(sizeof(ENodeList));
- if (IS_TYPE_CLASS(expr->data.funccall.functype->functype)) {
- CDecl_CompleteType(expr->data.funccall.functype->functype);
- if (CClass_Destructor(TYPE_CLASS(expr->data.funccall.functype->functype)))
- list->node = create_temp_node2(expr->rtype);
- else
- list->node = create_temp_node(expr->rtype);
- } else {
- list->node = create_temp_node(expr->rtype);
- }
- list->next = expr->data.funccall.args;
- expr->data.funccall.args = list;
-
- if (expr->data.funccall.funcref->flags & ENODE_FLAG_10)
- expr = CSOM_EnvCheck(expr, list);
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype);
- return expr;
- }
-
- if (expr->data.funccall.funcref->flags & ENODE_FLAG_10)
- expr = CSOM_EnvCheck(expr, NULL);
- return expr;
-}
-
-ENode *funccallexpr(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, ENode *arg4) {
- ENode *expr;
- TypeFunc *tfunc;
- ENodeList *list;
-
- tfunc = TYPE_FUNC(func->type);
- CError_ASSERT(1411, IS_TYPE_FUNC(tfunc));
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->rtype = tfunc->functype;
- expr->flags = tfunc->qual & ENODE_FLAG_QUALS;
- expr->data.funccall.funcref = create_objectrefnode(func);
- expr->data.funccall.functype = tfunc;
-
- if (arg1) {
- list = lalloc(sizeof(ENodeList));
- expr->data.funccall.args = list;
- list->node = arg1;
- if (arg2) {
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg2;
- if (arg3) {
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg3;
- if (arg4) {
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg4;
- }
- }
- }
- list->next = NULL;
- } else {
- expr->data.funccall.args = NULL;
- }
-
- return CExpr_AdjustFunctionCall(expr);
-}
-
-ENode *CExpr_FuncCallSix(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, ENode *arg4, ENode *arg5, ENode *arg6) {
- ENode *expr;
- TypeFunc *tfunc;
- ENodeList *list;
-
- tfunc = TYPE_FUNC(func->type);
- CError_ASSERT(1460, IS_TYPE_FUNC(tfunc));
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->rtype = tfunc->functype;
- expr->flags = tfunc->qual & ENODE_FLAG_QUALS;
- expr->data.funccall.funcref = create_objectrefnode(func);
- expr->data.funccall.functype = tfunc;
-
- list = lalloc(sizeof(ENodeList));
- expr->data.funccall.args = list;
- list->node = arg1;
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg2;
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg3;
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg4;
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg5;
- if (arg6) {
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = arg6;
- }
- list->next = NULL;
-
- return CExpr_AdjustFunctionCall(expr);
-}
-
-static void CExpr_CalcStdAssign(short checkresult, Match5 *match, Type *t1, UInt32 q1, Type *t2, UInt32 q2, Boolean flag) {
- memclrw(match, sizeof(Match5));
- switch (checkresult) {
- case CheckResult1:
- match->x0++;
- break;
- case CheckResult2:
- match->x2++;
- break;
- case CheckResult3:
- match->x4++;
- match->x6 += assign_value;
- break;
- default:
- CError_FATAL(1504);
- }
-
- if (flag || (IS_TYPE_POINTER_ONLY(t2) && (IS_TYPE_POINTER_ONLY(t1) || IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(t2))) != 0)) {
- if ((q2 & Q_CONST) == (q1 & Q_CONST))
- match->x8++;
- if ((q2 & Q_VOLATILE) == (q1 & Q_VOLATILE))
- match->x8++;
- }
-}
-
-void CExpr_MatchCV(Type *t1, UInt32 q1, Type *t2, UInt32 q2, Match13 *match) {
- Boolean r8;
-
- if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(t2))) {
- t2 = TYPE_POINTER(t2)->target;
- r8 = 1;
- } else {
- r8 = 0;
- }
-
- while (IS_TYPE_POINTER_ONLY(t2) && IS_TYPE_POINTER_ONLY(t1)) {
- if (r8) {
- if ((TYPE_POINTER(t1)->qual & Q_CONST) != (TYPE_POINTER(t2)->qual & Q_CONST))
- match->anotherm5.x8--;
- if ((TYPE_POINTER(t1)->qual & Q_VOLATILE) != (TYPE_POINTER(t2)->qual & Q_VOLATILE))
- match->anotherm5.x8--;
- }
- t2 = TYPE_POINTER(t2)->target;
- t1 = TYPE_POINTER(t1)->target;
- r8 = 1;
- }
-
- if ((q1 & Q_CONST) != (q2 & Q_CONST))
- match->anotherm5.x8--;
- if ((q1 & Q_VOLATILE) != (q2 & Q_VOLATILE))
- match->anotherm5.x8--;
-}
-
-Boolean CExpr_MatchAssign(Type *type, UInt32 qual, ENode *expr, Match13 *match) {
- switch (assign_check(expr, type, qual, 0, 0, 1)) {
- case CheckResult0:
- return 0;
- case CheckResult1:
- match->anotherm5.x0++;
- break;
- case CheckResult2:
- match->anotherm5.x2++;
- break;
- case CheckResult3:
- match->anotherm5.x4++;
- match->anotherm5.x6 += assign_value;
- break;
- case CheckResult4:
- match->xE++;
- match->match5.x0 += user_std_match.x0;
- match->match5.x2 += user_std_match.x2;
- match->match5.x4 += user_std_match.x4;
- match->match5.x6 += user_std_match.x6;
- match->match5.x8 += user_std_match.x8;
- break;
- default:
- CError_FATAL(1585);
- }
-
- if (IS_TYPE_POINTER_ONLY(type))
- CExpr_MatchCV(expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, qual, match);
-
- return 1;
-}
-
-static short CExpr_StdMatchCompare(Match5 *a, Match5 *b, Boolean flag) {
- if (a->x0 > b->x0) return 1;
- if (a->x0 == b->x0) {
- if (a->x2 > b->x2) return 1;
- if (a->x2 == b->x2) {
- if (a->x4 > b->x4) return 1;
- if (a->x4 == b->x4) {
- if (a->x6 > b->x6) return 1;
- if (a->x6 == b->x6) {
- if (!flag)
- return 0;
- if (a->x8 > b->x8) return 1;
- if (a->x8 == b->x8) return 0;
- }
- }
- }
- }
- return -1;
-}
-
-static short CExpr2_MemberPointerConversion(Type *type, ENode *expr, Boolean flag1) {
- ENode *newnode;
- short depth;
-
- newnode = lalloc(sizeof(ENode));
- *newnode = *expr;
- if (!IS_TYPE_MEMBERPOINTER(newnode->rtype)) {
- newnode = CExpr_MemberPointerConversion(newnode, TYPE_MEMBER_POINTER(type), flag1);
- if (iscpp_typeequal(newnode->rtype, type)) {
- if (flag1)
- assign_node = newnode;
- return CheckResult3;
- }
- }
-
- if (IS_TYPE_MEMBERPOINTER(newnode->rtype)) {
- CError_ASSERT(1656, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
- CError_ASSERT(1657, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2));
-
- if (CClass_IsBaseClass(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2), &depth, 0, 0)) {
- assign_value = 1000 - depth;
- if (flag1)
- assign_node = PointerToMemberCast(newnode, TYPE_MEMBER_POINTER(newnode->rtype), TYPE_MEMBER_POINTER(type), 1);
- return CheckResult3;
- }
- }
-
- return CheckResult0;
-}
-
-ENode *CExpr_ClassPointerCast(BClassList *cls, ENode *origexpr, Boolean nullcheckflag) {
- ENode *expr;
- ClassList *base;
- Boolean do_nullcheck;
- TypeClass *tclass;
- SInt32 offset;
- ENode *tmp;
-
- expr = origexpr;
- tclass = TYPE_CLASS(cls->type);
- do_nullcheck = 0;
- CError_ASSERT(1691, cls);
-
- if (!IS_TYPE_POINTER_ONLY(origexpr->rtype)) {
- CError_Error(CErrorStr141);
- return origexpr;
- }
-
- cls = cls->next;
- while (cls) {
- for (base = tclass->bases; base; base = base->next) {
- if (base->base == TYPE_CLASS(cls->type))
- break;
- }
-
- if (!base) {
- CError_Error(CErrorStr221);
- while (cls->next)
- cls = cls->next;
-
- tmp = nullnode();
- tmp->rtype = CDecl_NewPointerType(cls->type);
- return tmp;
- }
-
- if (base->is_virtual) {
- if (!base->base->sominfo) {
- do_nullcheck = 1;
- if ((offset = base->offset) && !canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
- expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(TYPE(base->base)));
- expr = makemonadicnode(expr, EINDIRECT);
- }
- } else {
- if ((offset = base->offset)) {
- do_nullcheck = 1;
- if (!canadd(expr, offset)) {
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- optimizecomm(expr);
- }
- }
- }
-
- switch (expr->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- expr = makemonadicnode(expr, ETYPCON);
- }
-
- expr->rtype = CDecl_NewPointerType(TYPE(base->base));
- tclass = TYPE_CLASS(cls->type);
- cls = cls->next;
- }
-
- if (nullcheckflag && do_nullcheck)
- expr = do_castnullcheck(expr, origexpr);
- return expr;
-}
-
-ENode *CExpr_GetClassAccessNode(BClassList *a, BClassList *b, ENode *expr, Object *obj, AccessType access, Boolean flag) {
- TypeClass *tclass;
- ENode *tmp;
-
- if (!expr) {
- if (!cscope_currentfunc || !cscope_currentclass || !cscope_is_member_func || !(expr = CClass_CreateThisSelfExpr())) {
- CError_Error(CErrorStr221);
- return NULL;
- }
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TYPE(cscope_currentclass);
- }
-
- CError_ASSERT(1786, a);
- CError_ASSERT(1787, IS_TYPE_CLASS(expr->rtype));
-
- tclass = TYPE_CLASS(expr->rtype);
- a = CScope_GetClassAccessPath(a, tclass);
- if (!a || a->type != TYPE(tclass)) {
- CError_Error(CErrorStr221);
- return NULL;
- }
-
- if (flag)
- CClass_CheckPathAccess(a, obj, access);
-
- if (!TYPE_CLASS(a->type)->sominfo) {
- if (b)
- a = CClass_AppendPath(a, b);
-
- if (!ENODE_IS(expr, EINDIRECT))
- expr = CExpr_LValue(expr, 0, 0);
-
- if (ENODE_IS(expr, EINDIRECT)) {
- expr->data.monadic->flags = expr->flags;
- tmp = expr->data.monadic;
- switch (tmp->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- tmp = makemonadicnode(tmp, ETYPCON);
- }
- expr = makemonadicnode(CExpr_ClassPointerCast(a, tmp, 0), EINDIRECT);
- expr->rtype = TYPE(tclass);
- }
- }
-
- return expr;
-}
-
-static short std_assign_check_overload(NameSpaceObjectList *list, TemplArg *templargs, Type *type, Boolean flag1) {
- Object *obj;
- Object *used_obj;
- Boolean found_non_template_func;
- Boolean is_ambig;
- TemplFuncInstance *instance;
- ENode *expr;
- Object *cmp1;
- Object *cmp2;
-
- if (!IS_TYPE_POINTER_ONLY(type) || !IS_TYPE_FUNC(TYPE_POINTER(type)->target))
- return CheckResult0;
-
- used_obj = NULL;
- type = TYPE_POINTER(type)->target;
- found_non_template_func = 0;
- is_ambig = 0;
- for (; list; list = list->next) {
- obj = OBJECT(list->object);
- if (obj->otype != OT_OBJECT)
- continue;
-
- if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) {
- if (!found_non_template_func && CTempl_CanDeduceFunc(obj, TYPE_FUNC(type), templargs)) {
- instance = CTempl_DeduceFunc(obj, TYPE_FUNC(type), templargs, NULL, 0);
- CError_ASSERT(1861, instance);
- if (is_typesame(instance->object->type, type)) {
- if (used_obj && used_obj != instance->object)
- is_ambig = 1;
- else
- used_obj = instance->object;
- }
- }
- } else {
- if (is_typesame(obj->type, type)) {
- if (used_obj && found_non_template_func) {
- cmp1 = obj;
- if (obj->datatype == DALIAS)
- cmp1 = obj->u.alias.object;
- cmp2 = used_obj;
- if (used_obj->datatype == DALIAS)
- cmp2 = used_obj->u.alias.object;
- if (cmp1 != cmp2)
- is_ambig = 1;
- } else {
- is_ambig = 0;
- used_obj = obj;
- }
- found_non_template_func = 1;
- }
- }
- }
-
- if (used_obj) {
- if (flag1) {
- if (is_ambig)
- CError_Error(CErrorStr199);
- expr = CExpr_MakeObjRefNode(used_obj, 1);
- assign_node = expr;
- expr->rtype = CDecl_NewPointerType(used_obj->type);
- expr->flags = obj->qual & ENODE_FLAG_QUALS;
- used_obj->flags |= OBJECT_USED;
- if (used_obj->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- }
- return CheckResult1;
- } else {
- return CheckResult0;
- }
-}
-
-ENode *CExpr_ConvertToBool(ENode *expr, Boolean isExplicit) {
- if (IS_TYPE_MEMBERPOINTER(expr->rtype))
- expr = CExpr_ConvertToCondition(expr);
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEPOINTER:
- if (IS_TYPE_ENUM(expr->rtype))
- expr = forceintegral(expr);
- switch (expr->type) {
- case EINTCONST:
- CInt64_SetLong(&expr->data.intval, !CInt64_IsZero(&expr->data.intval));
- break;
- case EFLOATCONST:
- CInt64_SetLong(&expr->data.intval, !CMach_FloatIsZero(expr->data.floatval));
- expr->type = EINTCONST;
- break;
- default:
- expr = makemonadicnode(expr, ELOGNOT);
- expr->rtype = TYPE(&stbool);
- expr = makemonadicnode(expr, ELOGNOT);
- }
- break;
- default:
- CError_Error(
- isExplicit ? CErrorStr247 : CErrorStr209,
- expr->rtype,
- expr->flags & ENODE_FLAG_QUALS,
- &stbool,
- 0);
- expr = nullnode();
- }
-
- expr->rtype = TYPE(&stbool);
- return expr;
-}
-
-static short std_assign_check(ENode *expr, Type *type, Boolean flag1, Boolean flag2) {
- short result;
-
- if (copts.cplusplus) {
- illegalimplicitconversion = 0;
-
- if ((result = iscpp_typeequal(expr->rtype, type))) {
- assign_node = expr;
- if (result == -1) {
- assign_value = 1;
- return CheckResult3;
- } else {
- return CheckResult1;
- }
- }
-
- if (flag1 && illegalimplicitconversion) {
- CError_Error(CErrorStr209, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0);
- return CheckResult0;
- }
- } else {
- if (is_typeequal(expr->rtype, type)) {
- assign_node = expr;
- return CheckResult1;
- }
- }
-
- if (type == TYPE(&stbool)) {
- switch (expr->rtype->type) {
- case TYPEPOINTER:
- case TYPEMEMBERPOINTER:
- assign_value = 0;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- if (flag1)
- assign_node = CExpr_ConvertToBool(expr, 0);
- return CheckResult3;
- default:
- return CheckResult0;
- }
- }
-
- if (IS_TYPE_ENUM(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) {
- result = CheckResult3;
- if (IS_TYPE_INT(type)) {
- if (TYPE_ENUM(expr->rtype)->enumtype == type) {
- result = CheckResult2;
- } else if (TYPE_INTEGRAL(TYPE_ENUM(expr->rtype)->enumtype)->integral < IT_INT) {
- switch (TYPE_INTEGRAL(type)->integral) {
- case IT_INT:
- if (expr->rtype->size < stsignedint.size || TYPE_ENUM(expr->rtype)->enumtype == TYPE(&stsignedshort))
- result = CheckResult2;
- break;
- case IT_UINT:
- if (expr->rtype->size >= stsignedint.size && TYPE_ENUM(expr->rtype)->enumtype != TYPE(&stsignedshort))
- result = CheckResult2;
- break;
- }
- }
- }
- if (flag1) {
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- assign_node = promote(expr, type);
- }
- return result;
- }
-
- if (IS_TYPE_INT(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) {
- result = CheckResult3;
- if (TYPE_INTEGRAL(expr->rtype)->integral <= IT_INT) {
- if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint)) {
- switch (TYPE_INTEGRAL(type)->integral) {
- case IT_INT:
- if (expr->rtype->size < stsignedint.size || type != TYPE(&stunsignedshort))
- result = CheckResult2;
- break;
- case IT_UINT:
- if (expr->rtype->size == stsignedint.size && type == TYPE(&stunsignedshort))
- result = CheckResult2;
- break;
- }
- }
- }
-
- if (flag1 && type != expr->rtype)
- assign_node = promote(expr, type);
- else
- assign_node = expr;
- return result;
- }
-
- if (IS_TYPE_FLOAT(expr->rtype) && (IS_TYPE_INT(type) || IS_TYPE_FLOAT(type))) {
- if (type == TYPE(&stdouble) && (expr->rtype == TYPE(&stfloat) || expr->rtype == TYPE(&stshortdouble)))
- result = CheckResult2;
- else
- result = CheckResult3;
-
- if (flag1 && (!IS_TYPE_FLOAT(type) || type->size != expr->rtype->size))
- assign_node = promote(expr, type);
- else
- assign_node = expr;
- return result;
- }
-
- if (IS_TYPE_POINTER_ONLY(type)) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval) && (IS_TYPE_INT(expr->rtype) || (!copts.cplusplus && IS_TYPE_ENUM(expr->rtype)))) {
- if (flag1)
- expr->rtype = TYPE(&stunsignedlong);
- assign_node = expr;
- return CheckResult3;
- }
- if (ENODE_IS(expr, EOBJLIST)) {
- return std_assign_check_overload(expr->data.objlist.list, expr->data.objlist.templargs, type, flag1);
- }
- if (IS_TYPE_POINTER_ONLY(expr->rtype)) {
- if (ENODE_IS(expr, EOBJREF) && IS_TYPE_FUNC(expr->data.objref->type) && (TYPE_FUNC(expr->data.objref->type)->flags & FUNC_IS_TEMPL)) {
- NameSpaceObjectList list;
- list.next = NULL;
- list.object = OBJ_BASE(expr->data.objref);
- return std_assign_check_overload(&list, NULL, type, flag1);
- }
- if (copts.objective_c && CObjC_IsCompatibleType(expr->rtype, type)) {
- assign_value = 1;
- return CheckResult3;
- }
- if (IS_TYPE_CLASS(TYPE_POINTER(expr->rtype)->target) && IS_TYPE_CLASS(TYPE_POINTER(type)->target)) {
- short depth;
- Boolean isambig;
- BClassList *path;
- path = CClass_GetBasePath(
- TYPE_CLASS(TYPE_POINTER(expr->rtype)->target),
- TYPE_CLASS(TYPE_POINTER(type)->target),
- &depth, &isambig
- );
- if (path) {
- assign_value = 1000 - depth;
- if (flag1) {
- if (isambig)
- CError_Error(CErrorStr188);
- if (flag2)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
- assign_node = CExpr_ClassPointerCast(path, expr, 1);
- }
- return CheckResult3;
- } else {
- if (flag1) {
- if (isambig)
- CError_Error(CErrorStr188);
- else
- CError_Error(
- CErrorStr244,
- expr->rtype,
- expr->flags & ENODE_FLAG_QUALS,
- type,
- 0);
- }
- return CheckResult0;
- }
- }
- }
- }
-
- if (IS_TYPE_MEMBERPOINTER(type) && !IS_TYPE_CLASS(expr->rtype)) {
- return CExpr2_MemberPointerConversion(type, expr, flag1);
- }
-
- if (IS_TYPE_CLASS(expr->rtype) && IS_TYPE_CLASS(type)) {
- short depth;
- Boolean isambig;
- BClassList *path;
- path = CClass_GetBasePath(
- TYPE_CLASS(expr->rtype),
- TYPE_CLASS(type),
- &depth, &isambig
- );
- if (path) {
- assign_value = 1000 - depth;
- if (flag1) {
- if (isambig)
- CError_Error(CErrorStr188);
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
- assign_node = getnodeaddress(expr, 0);
- assign_node = CExpr_ClassPointerCast(path, assign_node, 0);
- assign_node = makemonadicnode(assign_node, EINDIRECT);
- assign_node->rtype = type;
- }
- return CheckResult3;
- }
- }
-
- if (IS_TYPE_ENUM(type)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- if (!copts.cplusplus) {
- if (flag1) {
- if (copts.pedantic)
- CError_Warning(CErrorStr217, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0);
- assign_node = do_typecast(expr, type, 0);
- assign_node->flags = expr->flags;
- }
- return CheckResult2;
- } else {
- if (flag1)
- CError_Error(CErrorStr217, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, 0);
- }
- }
- }
-
- return CodeGen_AssignCheck(expr, type, flag1, flag2);
-}
-
-static short is_compatible_conversion(Type *a, Type *b) {
- if (IS_TYPE_REFERENCE(a))
- a = TYPE_POINTER(a)->target;
- if (IS_TYPE_REFERENCE(b))
- b = TYPE_POINTER(b)->target;
- return iscpp_typeequal(b, a);
-}
-
-static void CExpr_ConIteratorInit(ConIterator *iter) {
- ClassList *base;
- ConIterator *subiter;
- ConIteratorList *list;
-
- for (base = iter->tclass->bases; base; base = base->next) {
- if (base->base->flags & CLASS_IS_CONVERTIBLE) {
- subiter = galloc(sizeof(ConIterator));
- memclrw(subiter, sizeof(ConIterator));
- subiter->parent = iter;
- subiter->tclass = base->base;
- CExpr_ConIteratorInit(subiter);
-
- list = galloc(sizeof(ConIteratorList));
- memclrw(list, sizeof(ConIteratorList));
- list->iter = subiter;
- list->next = iter->children;
- iter->children = list;
- }
- }
-}
-
-void CExpr_ConversionIteratorInit(ConversionIterator *iter, TypeClass *tclass) {
- memclrw(iter, sizeof(ConversionIterator));
- if (tclass->flags & CLASS_IS_CONVERTIBLE) {
- iter->coniter = &iter->myconiter;
- iter->myconiter.tclass = tclass;
- CExpr_ConIteratorInit(&iter->myconiter);
- CScope_InitObjectIterator(&iter->objiter, tclass->nspace);
- }
-}
-
-static Boolean CExpr_ConversionIteratorIsHidden(ConIterator *iter, TypeFunc *tfunc) {
- CScopeObjectIterator objiter;
- ObjBase *obj;
- TypeFunc *objtfunc;
-
- while (iter) {
- CScope_InitObjectIterator(&objiter, iter->tclass->nspace);
- while (1) {
- if (!(obj = CScope_NextObjectIteratorObject(&objiter)))
- break;
-
- objtfunc = TYPE_FUNC(OBJECT(obj)->type);
- if (
- IS_TYPE_FUNC(objtfunc) &&
- (objtfunc->flags & FUNC_CONVERSION) &&
- is_compatible_conversion(tfunc->functype, objtfunc->functype) &&
- (tfunc->args->qual & Q_CONST) == (objtfunc->args->qual & Q_CONST) &&
- (tfunc->qual & Q_CONST) == (objtfunc->qual & Q_CONST)
- )
- return 1;
- }
- iter = iter->parent;
- }
-
- return 0;
-}
-
-Object *CExpr_ConversionIteratorNext(ConversionIterator *iter) {
- ConIterator *ci;
- Object *obj;
-
- ci = iter->coniter;
- if (!ci)
- return NULL;
-
-restart:
- if ((obj = OBJECT(CScope_NextObjectIteratorObject(&iter->objiter)))) {
- if (
- IS_TYPE_FUNC(obj->type) &&
- (TYPE_FUNC(obj->type)->flags & FUNC_CONVERSION) &&
- !CExpr_ConversionIteratorIsHidden(ci->parent, TYPE_FUNC(obj->type))
- ) {
- return obj;
- }
- goto restart;
- }
-
- do {
- if (ci->children) {
- iter->coniter = ci->children->iter;
- ci->children = ci->children->next;
- ci = iter->coniter;
- CScope_InitObjectIterator(&iter->objiter, ci->tclass->nspace);
- goto restart;
- }
- } while ((ci = ci->parent));
-
- return NULL;
-}
-
-short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2, Boolean flag3) {
- Object *r26;
- ENode *r25;
- Boolean r24;
- Boolean r23;
- Boolean r22;
- Type *r18b;
- short r18;
- TypeFunc *r17;
- Object *r17b;
- NameSpaceObjectList *r16b;
- Object *r16;
- Object *r15;
- ENode *r15b;
- ENode *r14;
- short r14b;
- TypeFunc *r14c;
- ENodeList *r14d;
- TypeMemberFunc *r13;
- ENodeList *r13b;
- short result;
- FuncArg *arg;
- ConversionIterator iter;
- Match5 stdmatch;
- Match5 match_8C;
- Match5 match_98;
- BClassList path;
- UInt16 chk;
- Boolean is_const, is_volatile;
-
- CError_ASSERT(2378, copts.old_argmatch);
-
- memclrw(&stdmatch, sizeof(Match5));
- r24 = 0;
- r22 = 0;
- r23 = 0;
-
- if (!type->size)
- CDecl_CompleteType(type);
- if (!expr->rtype->size)
- CDecl_CompleteType(expr->rtype);
-
- if (IS_TYPE_CLASS(expr->rtype)) {
- r18 = 0;
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype));
- while ((r16 = CExpr_ConversionIteratorNext(&iter))) {
- r17 = TYPE_FUNC(r16->type);
- r14 = CExpr_NewENode(ETEMP);
- r14->rtype = r17->functype;
- if (IS_TYPE_REFERENCE(r14->rtype)) {
- r14->rtype = TYPE_POINTER(r14->rtype)->target;
- if (!CParser_IsConst(r14->rtype, r17->qual)) {
- r14 = makemonadicnode(r14, EINDIRECT);
- r14->data.monadic->rtype = TYPE(&void_ptr);
- r14 = makemonadicnode(r14, EINDIRECT);
- r14->data.monadic->rtype = TYPE(&void_ptr);
- }
- }
- if ((result = std_assign_check(r14, type, 0, flag3))) {
- CExpr_CalcStdAssign(result, &match_98, r17->functype, r17->qual, type, qual, 1);
- CError_ASSERT(2419, r17->args && IS_TYPE_POINTER_ONLY(r17->args->type));
- chk = expr->flags;
- if (!(is_const = (r17->args->qual & Q_CONST)) && (chk & Q_CONST) != 0)
- continue;
- if (!(is_volatile = (r17->args->qual & Q_VOLATILE)) && (chk & Q_VOLATILE) != 0)
- continue;
- //if (((r17->args->qual & Q_CONST) == 0 && (chk & Q_CONST) != 0) || ((r17->args->qual & Q_VOLATILE) == 0 && (chk & Q_VOLATILE) != 0))
- // continue;
-
- r14b = 0;
- if (is_const == (expr->flags & Q_CONST))
- r14b++;
- if (is_volatile == (expr->flags & Q_VOLATILE))
- r14b++;
- switch (CExpr_StdMatchCompare(&match_98, &stdmatch, 1)) {
- case -1:
- continue;
- case 0:
- if (r26 == r16)
- continue;
- if (r14b < r18)
- continue;
- if (r14b != r18)
- break;
- r22 = 1;
- continue;
- }
- r26 = r16;
- stdmatch = match_98;
- r24 = 1;
- r22 = 0;
- r18 = r14b;
- }
- }
- }
-
- if (IS_TYPE_CLASS(type) && (r16b = CClass_Constructor(TYPE_CLASS(type)))) {
- memclrw(&match_8C, sizeof(Match5));
- for (; r16b; r16b = r16b->next) {
- r17b = OBJECT(r16b->object);
- if (r17b->otype != OT_OBJECT)
- continue;
- r14c = TYPE_FUNC(r17b->type);
- if (!IS_TYPE_FUNC(r14c))
- continue;
- if (!flag2 && (r14c->qual & Q_EXPLICIT))
- continue;
- if (!r14c->args)
- continue;
- if (!(arg = r14c->args->next))
- continue;
- if ((TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) && !(arg = arg->next))
- continue;
- if (arg == &elipsis)
- continue;
- if (arg->next && !arg->next->dexpr && arg->next != &elipsis)
- continue;
-
- r18b = arg->type;
- if (IS_TYPE_REFERENCE(r18b)) {
- r18b = TYPE_POINTER(r18b)->target;
- if (!CParser_IsConst(r18b, arg->qual) && !CExpr_IsLValue(expr))
- continue;
- }
-
- if ((result = std_assign_check(expr, r18b, 0, flag3))) {
- CExpr_CalcStdAssign(result, &match_98, r14c->functype, r14c->qual, type, qual, 0);
- switch (CExpr_StdMatchCompare(&match_98, &match_8C, 1)) {
- case -1:
- case 0:
- continue;
- }
- r25 = expr;
- match_8C = match_98;
- r23 = 1;
- r15 = r17b;
- }
- }
-
- if (r23) {
- if (r24) {
- switch (CExpr_StdMatchCompare(&stdmatch, &match_8C, 1)) {
- case -1:
- stdmatch = match_8C;
- r24 = 0;
- break;
- case 0:
- r22 = 1;
- break;
- }
- } else {
- stdmatch = match_8C;
- }
- }
- }
-
- if (r22 && flag1)
- CError_Error(CErrorStr199);
-
- if (r24 || r23) {
- if (flag1) {
- if (r24) {
- r13 = TYPE_METHOD(r26->type);
- CError_ASSERT(2537, r13->flags & FUNC_METHOD);
- r15b = create_objectrefnode(r26);
- r26->flags |= OBJECT_USED;
- r14d = lalloc(sizeof(ENodeList));
- r14d->next = NULL;
- expr = getnodeaddress(expr, 0);
- r14d->node = CExpr_AssignmentPromotion(expr, CDecl_NewPointerType(TYPE(r13->theclass)), expr->flags, 0);
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->rtype = r13->functype;
- expr->flags = r13->qual & ENODE_FLAG_QUALS;
- expr->data.funccall.funcref = r15b;
- expr->data.funccall.args = r14d;
- expr->data.funccall.functype = TYPE_FUNC(r26->type);
- assign_node = checkreference(CExpr_AdjustFunctionCall(expr));
- if (assign_node->rtype != type)
- assign_node = CExpr_AssignmentPromotion(assign_node, type, qual, 1);
- if (!IS_TYPE_REFERENCE(r13->functype))
- temp_reference_init = 1;
- } else {
- r13b = lalloc(sizeof(ENodeList));
- r13b->next = NULL;
- r13b->node = r25;
- if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) {
- r13b->next = lalloc(sizeof(ENodeList));
- r13b->next->node = r25;
- r13b->next->next = NULL;
- r13b->node = intconstnode(TYPE(&stsignedshort), 1);
- }
- path.next = NULL;
- path.type = type;
- assign_node = makemonadicnode(create_temp_node(type), EINDIRECT);
- assign_node->rtype = type;
- assign_node = CExpr_GenericFuncCall(&path, assign_node, 0, r15, NULL, NULL, r13b, 0, 0, 1);
- if (ENODE_IS2(assign_node, EFUNCCALL, EFUNCCALLP)) {
- assign_node->rtype = CDecl_NewPointerType(type);
- assign_node = makemonadicnode(assign_node, EINDIRECT);
- assign_node->rtype = type;
- }
- temp_reference_init = 1;
- }
- }
-
- user_std_match = stdmatch;
- return CheckResult4;
- } else {
- if (flag1)
- CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type, qual);
- return CheckResult0;
- }
-}
-
-ENode *CExpr_ConvertToCondition(ENode *expr) {
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEPOINTER:
- return expr;
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- return expr;
- case TYPEMEMBERPOINTER:
- return memberpointercompare(ENOTEQU, expr, nullnode());
- case TYPECLASS:
- return CExpr_Convert(expr, TYPE(&stbool), 0, 0, 1);
- default:
- CError_Error(CErrorStr376, expr->rtype, expr->flags & ENODE_FLAG_QUALS);
- return nullnode();
- }
-}
-
-ENode *CExpr_ConvertToIntegral(ENode *expr) {
- ConversionIterator iter;
- Type *found;
- Object *obj;
-
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- return integralpromote(expr);
- case TYPECLASS:
- CDecl_CompleteType(expr->rtype);
- found = NULL;
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (IS_TYPE_INT_OR_ENUM(TYPE_FUNC(obj->type)->functype)) {
- if (found) {
- CError_Error(CErrorStr199);
- break;
- }
- found = TYPE_FUNC(obj->type)->functype;
- }
- }
- if (found)
- return integralpromote(CExpr_Convert(expr, found, 0, 0, 1));
- break;
- }
-
- CError_Error(CErrorStr376, expr->rtype, expr->flags & ENODE_FLAG_QUALS);
- return nullnode();
-}
-
-void CExpr_CheckArithmConversion(ENode *expr, Type *type) {
- CInt64 val;
-
- if (expr->rtype == type)
- return;
- if (expr->rtype == TYPE(&stbool))
- return;
-
- if (IS_TYPE_INT(expr->rtype)) {
- if (IS_TYPE_FLOAT(type))
- return;
- CError_ASSERT(2772, IS_TYPE_INT(type));
-
- if (type->size > expr->rtype->size)
- return;
- if (type->size == expr->rtype->size && is_unsigned(type) == is_unsigned(expr->rtype))
- return;
-
- switch (expr->type) {
- case EINTCONST:
- if (!CInt64_IsNegative(&expr->data.intval) || is_unsigned(expr->rtype) || !is_unsigned(type)) {
- val = CExpr_IntConstConvert(type, expr->rtype, expr->data.intval);
- val = CExpr_IntConstConvert(expr->rtype, type, val);
- if (CInt64_Equal(val, expr->data.intval))
- return;
- }
- break;
- case ELOGNOT:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case ELAND:
- case ELOR:
- return;
- }
- } else {
- if (IS_TYPE_FLOAT(type) && type->size >= expr->rtype->size)
- return;
- }
-
- CError_Warning(CErrorStr317, expr->rtype, 0, type, 0);
-}
-
-ENode *get_address_of_temp_copy(ENode *expr, Boolean flag) {
- char buf[64];
- ENode *result;
- Object *obj;
- Type *innertype;
-
- if (flag) {
- if (ENODE_IS2(expr, EINTCONST, EFLOATCONST)) {
- obj = CParser_NewCompilerDefDataObject();
- obj->type = expr->rtype;
- obj->name = CParser_GetUniqueName();
- obj->sclass = TK_STATIC;
- if (ENODE_IS(expr, EINTCONST)) {
- innertype = expr->rtype;
- switch (innertype->type) {
- case TYPEINT:
- break;
- case TYPEENUM:
- innertype = TYPE_ENUM(innertype)->enumtype;
- break;
- case TYPEPOINTER:
- innertype = TYPE(&stunsignedlong);
- break;
- default:
- CError_FATAL(2857);
- }
- CMach_InitIntMem(innertype, expr->data.intval, buf);
- } else {
- CMach_InitFloatMem(expr->rtype, expr->data.floatval, buf);
- }
- CInit_DeclareData(obj, buf, NULL, obj->type->size);
- return create_objectrefnode(obj);
- }
-
- if (cinit_tempnodefunc == NULL)
- result = CExpr_NewETEMPNode(expr->rtype, 1);
- else
- result = cinit_tempnodefunc(expr->rtype, 0);
- result = makemonadicnode(result, EINDIRECT);
- result->rtype = TYPE_POINTER(result->rtype)->target;
- return makecommaexpression(makediadicnode(result, expr, EASS), result->data.monadic);
- } else {
- result = nullnode();
- CInt64_SetLong(&result->data.intval, -1);
- result->rtype = CDecl_NewPointerType(expr->rtype);
- return result;
- }
-}
-
-short assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2, Boolean flag3) {
- Type *type2;
- Boolean r30;
- Boolean r29;
- short result;
-
- assign_value = 1000;
- r30 = 0;
- r29 = 0;
- temp_reference_init = 0;
-
- type2 = type;
- if (IS_TYPE_REFERENCE(type) && !IS_TYPE_FUNC(TYPE_POINTER(type)->target)) {
- type2 = TYPE_POINTER(type)->target;
- r30 = 1;
- }
-
- assign_node = expr;
- if (IS_TYPE_ARRAY(type2)) {
- r29 = 1;
- type2 = CDecl_NewPointerType(TYPE_POINTER(type2)->target);
- }
-
- if (!type2->size) {
- CDecl_CompleteType(type2);
- if (!type2->size && !r30) {
- if (flag1) {
- if (IS_TYPE_CLASS(type2))
- CError_Error(CErrorStr136, type2, 0);
- else
- CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type2, qual);
- }
- return CheckResult0;
- }
- }
-
- if (copts.warn_implicitconv && flag1 && !flag2) {
- if (IS_TYPE_INT_OR_FLOAT(type2) && IS_TYPE_INT_OR_FLOAT(expr->rtype))
- CExpr_CheckArithmConversion(expr, type2);
- }
-
- result = std_assign_check(expr, type2, flag1, flag3);
- if (!result) {
- if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type2)) {
- result = user_assign_check(expr, type2, qual, flag1, flag2, flag3);
- } else if (flag1) {
- CError_Error(CErrorStr244, expr->rtype, expr->flags & ENODE_FLAG_QUALS, type2, qual);
- }
- }
-
- if (r30 && result) {
- if (flag1) {
- if (!ENODE_IS(assign_node, EINDIRECT)) {
- if (!r29) {
- assign_node = CExpr_LValue(assign_node, 0, 0);
- if (!ENODE_IS(assign_node, EINDIRECT)) {
- assign_node = get_address_of_temp_copy(assign_node, 1);
- temp_reference_init = 1;
- } else {
- assign_node = getnodeaddress(assign_node, 0);
- }
- }
- } else {
- if (!CExpr_IsLValue(assign_node))
- temp_reference_init = 1;
- if (!r29)
- assign_node = getnodeaddress(assign_node, 0);
- }
- } else {
- if (!r29 && !CExpr_IsLValue(assign_node) && !CParser_IsConst(TYPE_POINTER(type)->target, qual)) {
- result = CheckResult0;
- }
- }
- }
-
- return result;
-}
-
-Boolean CExpr_MatchCompare(Object *obj, Match13 *a, Match13 *b) {
- Object *tmp;
- ObjectList *list;
-
- switch (CExpr_StdMatchCompare(&b->anotherm5, &a->anotherm5, 0)) {
- case -1:
- return 0;
- case 0:
- if (a->xE > b->xE)
- return 0;
- if (a->xE != b->xE)
- break;
- switch (CExpr_StdMatchCompare(&b->match5, &a->match5, 1)) {
- case -1:
- return 0;
- case 0:
- if (a->anotherm5.x8 > b->anotherm5.x8)
- return 0;
- if (a->anotherm5.x8 == b->anotherm5.x8 && (tmp = a->obj)) {
- if (tmp->datatype == obj->datatype) {
- add_it:
- list = lalloc(sizeof(ObjectList));
- list->next = a->list;
- a->list = list;
- list->object = obj;
- return 0;
- }
- if (obj->datatype == DALIAS)
- return 0;
- if (tmp->datatype != DALIAS)
- goto add_it;
- }
- }
- }
-
- *a = *b;
- a->obj = obj;
- return 1;
-}
-
-static void MatchOverloadFunc(Object *obj, FuncArg *args, ENodeList *argexprs, Match13 *match) {
- Match13 match2;
-
- if (IS_TYPE_FUNC(obj->type) && !(TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) {
- memclrw(&match2, sizeof(Match13));
- while (1) {
- if (!args || args->type == &stvoid) {
- if (!argexprs)
- break;
- return;
- }
-
- if (args == &elipsis)
- break;
- if (args == &oldstyle)
- break;
-
- if (!argexprs) {
- if (args->dexpr)
- break;
- return;
- }
-
- if (!CExpr_MatchAssign(args->type, args->qual, argexprs->node, &match2))
- return;
-
- argexprs = argexprs->next;
- args = args->next;
- }
-
- CExpr_MatchCompare(obj, match, &match2);
- }
-}
-
-Boolean CExpr_GetFuncMatchArgs(Object *obj, ENodeList *argexprs, ENode *expr, FuncMatchArgs *result) {
- ENode *intexpr;
-
- if (!(TYPE_FUNC(obj->type)->flags & FUNC_METHOD)) {
- result->exprs = argexprs;
- result->args = TYPE_FUNC(obj->type)->args;
- return 1;
- }
-
- if (TYPE_METHOD(obj->type)->is_static) {
- result->exprs = argexprs;
- result->args = TYPE_FUNC(obj->type)->args;
- return 1;
- }
-
- if (TYPE_FUNC(obj->type)->flags & FUNC_IS_CTOR) {
- result->exprs = argexprs;
- result->args = TYPE_FUNC(obj->type)->args->next;
- return 1;
- }
-
- if (expr) {
- intexpr = lalloc(sizeof(ENode));
- intexpr->type = EINTCONST;
- intexpr->cost = 0;
- intexpr->flags = expr->flags;
- intexpr->rtype = CDecl_NewPointerType(expr->rtype);
- intexpr->data.intval = cint64_zero;
-
- result->exprs = lalloc(sizeof(ENodeList));
- result->exprs->next = argexprs;
- result->exprs->node = intexpr;
-
- if (obj->datatype == DALIAS) {
- result->args = lalloc(sizeof(FuncArg));
- *result->args = *TYPE_FUNC(obj->type)->args;
- result->args->type = CDecl_NewPointerType(expr->rtype);
- } else {
- result->args = TYPE_FUNC(obj->type)->args;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-static NameSpaceObjectList *CExpr_CopyNameSpaceObjectList(NameSpaceObjectList *list) {
- NameSpaceObjectList *first;
- NameSpaceObjectList *work;
-
- first = work = lalloc(sizeof(NameSpaceObjectList));
- while (1) {
- work->object = list->object;
- list = list->next;
- if (!list) {
- work->next = NULL;
- break;
- } else {
- work->next = lalloc(sizeof(NameSpaceObjectList));
- work = work->next;
- }
- }
- return first;
-}
-
-static void CExpr_MatchArgList(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match, ENode *expr, Boolean flag) {
- NameSpaceObjectList *copied_list;
- NameSpaceObjectList *scan_list;
- Object *obj;
- ENodeList *scan_expr;
- Boolean is_template;
- FuncMatchArgs fma;
-
- if (!copts.old_argmatch) {
- CExpr_FuncArgMatch(CExpr_CopyNameSpaceObjectList(list), templargs, argexprs, match, expr, flag);
- return;
- }
-
- copied_list = CExpr_CopyNameSpaceObjectList(list);
-
- for (scan_expr = argexprs; scan_expr; scan_expr = scan_expr->next)
- CDecl_CompleteType(scan_expr->node->rtype);
-
- scan_list = copied_list;
- is_template = 0;
- for (; scan_list; scan_list = scan_list->next) {
- obj = OBJECT(scan_list->object);
- if (obj->otype != OT_OBJECT)
- continue;
- if (IS_TYPE_FUNC(obj->type) && (!flag || !(obj->qual & Q_EXPLICIT))) {
- if (!(TYPE_FUNC(obj->type)->flags & FUNC_IS_TEMPL)) {
- if (CExpr_GetFuncMatchArgs(obj, argexprs, expr, &fma))
- MatchOverloadFunc(obj, fma.args, fma.exprs, match);
- } else {
- is_template = 1;
- }
- }
- }
-
- if (is_template) {
- if (!match->obj || match->anotherm5.x2 || match->anotherm5.x4 || match->xE)
- CTempl_FuncMatch(copied_list, templargs, argexprs, match, expr);
- }
-}
-
-ENode *CExpr_GetDefaultArgument(ENode *funcexpr, FuncArg *arg) {
- ENode *tmp;
-
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->dexpr)) {
- CError_ASSERT(3264, ENODE_IS(funcexpr, EOBJREF));
- tmp = CTemplTool_DeduceDefaultArg(
- funcexpr->data.objref,
- CInline_CopyExpression(arg->dexpr, CopyMode0)
- );
- return argumentpromotion(tmp, arg->type, arg->qual, 1);
- }
-
- return CInline_CopyExpression(arg->dexpr, CopyMode0);
-}
-
-static ENode *CExpr_GenericCall(ENode *funcexpr, ENodeList *argexprs, TypeFunc *tfunc, FuncArg *args) {
- ENodeList *list;
- ENode *callexpr;
-
- while (args) {
- if (args->dexpr) {
- if (argexprs) {
- list = argexprs;
- while (list->next)
- list = list->next;
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- } else {
- list = argexprs = lalloc(sizeof(ENodeList));
- }
- list->next = NULL;
- list->node = CExpr_GetDefaultArgument(funcexpr, args);
- }
- args = args->next;
- }
-
- callexpr = lalloc(sizeof(ENode));
- callexpr->type = EFUNCCALL;
- callexpr->cost = 4;
- callexpr->rtype = tfunc->functype;
- callexpr->flags = tfunc->qual & ENODE_FLAG_QUALS;
- callexpr->data.funccall.funcref = funcexpr;
- callexpr->data.funccall.funcref->rtype = CDecl_NewPointerType(TYPE(tfunc));
- callexpr->data.funccall.args = argexprs;
- callexpr->data.funccall.functype = tfunc;
- funcexpr->data.objref->flags |= OBJECT_USED;
- return CExpr_AdjustFunctionCall(callexpr);
-}
-
-static Boolean CExpr_IsObjrefPlusX(ENode *expr) {
- Type *type;
-
- if (ENODE_IS(expr, EOBJREF)) {
- type = expr->data.objref->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- return IS_TYPE_CLASS(type);
- }
-
- if (ENODE_IS2(expr, EADD, ESUB)) {
- if (CExpr_IsObjrefPlusX(expr->data.diadic.left))
- return 1;
- if (CExpr_IsObjrefPlusX(expr->data.diadic.right))
- return 1;
- }
-
- return 0;
-}
-
-static Boolean CExpr_IsStaticType(ENode *expr) {
- return ENODE_IS(expr, EINDIRECT) && CExpr_IsObjrefPlusX(expr->data.monadic);
-}
-
-ENode *CExpr_VarArgPromotion(ENode *expr, Boolean flag) {
- if (!copts.old_argmatch)
- expr = pointer_generation(expr);
-
- switch (expr->rtype->type) {
- case TYPEVOID:
- case TYPEFUNC:
- CError_Error(CErrorStr353);
- expr = nullnode();
- break;
- case TYPEINT:
- case TYPEENUM:
- expr = integralpromote(expr);
- break;
- case TYPEFLOAT:
- if (TYPE_INTEGRAL(expr->rtype)->integral < IT_DOUBLE)
- expr = promote(expr, TYPE(&stdouble));
- break;
- case TYPECLASS:
- expr = classargument(expr);
- break;
- }
-
- if (!flag && copts.warn_largeargs) {
- if ((IS_TYPE_INT(expr->rtype) && TYPE_INTEGRAL(expr->rtype)->integral >= IT_LONGLONG) || IS_TYPE_FLOAT(expr->rtype))
- CError_Warning(CErrorStr316);
- }
-
- return expr;
-}
-
-ENode *CExpr_GenericFuncCall(BClassList *path, ENode *funcexpr, Boolean flag1, Object *obj, NameSpaceObjectList *nsol, TemplArg *templargs, ENodeList *nodes, Boolean flag2, Boolean flag3, Boolean flag4) {
- TypeFunc *tfunc;
- AccessType access;
- FuncArg *scan_arg;
- BClassList *buildpath;
- ENode *objexpr;
- ENodeList *scan_expr;
- BClassList *pathcopy;
- Boolean had_alias;
- NameSpaceObjectList my_list;
- Match13 match;
-
- memclrw(&match, sizeof(Match13));
-
- if (!obj || IS_TEMPL_FUNC(obj->type)) {
- if (!funcexpr && cscope_currentfunc && cscope_currentclass && cscope_is_member_func) {
- funcexpr = CClass_CreateThisSelfExpr();
- if (funcexpr) {
- funcexpr = makemonadicnode(funcexpr, EINDIRECT);
- funcexpr->rtype = TYPE(cscope_currentclass);
- }
- }
-
- if (obj) {
- my_list.next = NULL;
- my_list.object = OBJ_BASE(obj);
- nsol = &my_list;
- }
-
- CExpr_MatchArgList(nsol, templargs, nodes, &match, funcexpr, flag2);
- if (!match.obj) {
- CError_ErrorFuncCall(CErrorStr248, nsol, nodes);
- return nullnode();
- }
- if (match.list)
- CError_OverloadedFunctionError(match.obj, match.list);
- obj = match.obj;
- }
-
- objexpr = create_objectrefnode(obj);
- tfunc = TYPE_FUNC(obj->type);
- if (!IS_TYPE_FUNC(tfunc)) {
- CError_Error(CErrorStr161);
- return nullnode();
- }
-
- if (IS_TYPEFUNC_METHOD(tfunc) && !TYPE_METHOD(tfunc)->is_static) {
- had_alias = 0;
- buildpath = NULL;
- access = obj->access;
- while (obj->datatype == DALIAS) {
- buildpath = buildpath ? CClass_AppendPath(buildpath, CClass_GetPathCopy(obj->u.alias.member, 0)) : CClass_GetPathCopy(obj->u.alias.member, 0);
- obj = obj->u.alias.object;
- objexpr = create_objectrefnode(obj);
- had_alias = 1;
- }
- if (flag3)
- CError_Error(CErrorStr188);
-
- if (TYPE_METHOD(tfunc)->theclass->sominfo && (!(obj->qual & Q_INLINE) || (obj->datatype == DVFUNC && !flag1))) {
- pathcopy = CClass_GetPathCopy(path, 0);
- funcexpr = CExpr_GetClassAccessNode(path, buildpath, funcexpr, obj, access, flag4);
- if (!funcexpr)
- return nullnode();
- objexpr = CSOM_MethodAccess(pathcopy, obj, flag1);
- } else {
- if (obj->datatype == DVFUNC) {
- if (flag1 || (!copts.always_vdispatch && !had_alias && funcexpr && CExpr_IsStaticType(funcexpr)))
- objexpr->flags |= ENODE_FLAG_80;
- }
- funcexpr = CExpr_GetClassAccessNode(path, buildpath, funcexpr, obj, access, flag4);
- if (!funcexpr)
- return nullnode();
- }
-
- if (
- (tfunc->flags & FUNC_PURE) &&
- cscope_currentfunc &&
- (TYPE_FUNC(cscope_currentfunc->type)->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) &&
- cscope_currentclass == TYPE_METHOD(tfunc)->theclass &&
- ENODE_IS(funcexpr, EINDIRECT) &&
- ENODE_IS(funcexpr->data.monadic, EINDIRECT) &&
- ENODE_IS(funcexpr->data.monadic->data.monadic, EOBJREF) &&
- funcexpr->data.monadic->data.monadic->data.objref->name == this_name_node &&
- !(objexpr->flags & ENODE_FLAG_80)
- )
- CError_Warning(CErrorStr195);
-
- scan_expr = lalloc(sizeof(ENodeList));
- scan_expr->next = nodes;
- scan_expr->node = funcexpr->data.monadic;
- if (ENODE_IS(scan_expr->node, EOBJREF))
- scan_expr->node->data.objref->flags |= OBJECT_FLAGS_2;
-
- if (((funcexpr->flags & Q_CONST) && !(tfunc->args->qual & Q_CONST)) || ((funcexpr->flags & Q_VOLATILE) && !(tfunc->args->qual & Q_VOLATILE))) {
- if (!(tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)))
- CError_Error(CErrorStr236);
- }
-
- nodes = scan_expr;
- scan_expr = scan_expr->next;
- scan_arg = tfunc->args->next;
- } else {
- if (flag4 && obj->access != ACCESSPROTECTED)
- CClass_CheckObjectAccess(path, obj);
-
- scan_arg = tfunc->args;
- scan_expr = nodes;
- if (tfunc->flags & FUNC_METHOD) {
- CError_ASSERT(3599, TYPE_METHOD(tfunc)->theclass->sominfo == NULL);
- }
- }
-
- while (scan_expr) {
- if (scan_arg && scan_arg != &elipsis && scan_arg != &oldstyle) {
- scan_expr->node = argumentpromotion(scan_expr->node, scan_arg->type, scan_arg->qual, 1);
- scan_arg = scan_arg->next;
- } else {
- if (!scan_arg) {
- my_list.next = NULL;
- my_list.object = OBJ_BASE(obj);
- CError_ErrorFuncCall(CErrorStr248, &my_list, nodes);
- }
- scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, scan_arg == &elipsis);
- }
- scan_expr = scan_expr->next;
- }
-
- if (scan_arg) {
- if (scan_arg != &elipsis && scan_arg != &oldstyle) {
- if (!scan_arg->dexpr) {
- my_list.next = NULL;
- my_list.object = OBJ_BASE(obj);
- CError_ErrorFuncCall(CErrorStr248, &my_list, nodes);
- scan_arg = NULL;
- }
- } else {
- scan_arg = NULL;
- }
- }
-
- return CExpr_GenericCall(objexpr, nodes, tfunc, scan_arg);
-}
-
-ENode *CExpr_GenericPtmfCall(Object *obj, TypeFunc *tfunc, ENodeList *arg_exprs) {
- ENodeList *scan_expr;
- FuncArg *arg;
-
- scan_expr = arg_exprs;
- arg = tfunc->args;
- while (scan_expr) {
- if (!arg) {
- CError_Error(CErrorStr162);
- return nullnode();
- }
-
- if (arg != &elipsis && arg != &oldstyle) {
- scan_expr->node = argumentpromotion(scan_expr->node, arg->type, arg->qual, 1);
- arg = arg->next;
- } else {
- scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, arg == &elipsis);
- }
- scan_expr = scan_expr->next;
- }
-
- if (arg) {
- if (arg != &elipsis && arg != &oldstyle) {
- if (!arg->dexpr) {
- CError_Error(CErrorStr162);
- arg = NULL;
- }
- } else {
- arg = NULL;
- }
- }
-
- return CExpr_GenericCall(create_objectrefnode(obj), arg_exprs, tfunc, arg);
-}
-
-static ENode *CExpr_ConvertEMember(ENode *expr) {
- ENode *result;
-
- if (expr->data.emember->list->next || expr->data.emember->templargs) {
- result = CExpr_NewENode(EOBJLIST);
- result->rtype = OBJECT(expr->data.emember->list->object)->type;
- result->data.objlist.list = expr->data.emember->list;
- result->data.objlist.templargs = expr->data.emember->templargs;
- return result;
- }
-
- if (expr->data.emember->list->object->otype != OT_OBJECT)
- return NULL;
- return CExpr_MakeObjRefNode(OBJECT(expr->data.emember->list->object), 1);
-}
-
-ENode *CExpr_MakeFunctionCall(ENode *funcexpr, ENodeList *arg_exprs) {
- ENode *expr;
- TypeFunc *tfunc;
- BClassList *save_path;
- ENode *save_expr;
- Boolean save_1D;
- Boolean save_isambig;
-
- FuncArg *scan_arg;
- ENodeList *scan_expr;
- Boolean has_varargs;
-
- if (ENODE_IS(funcexpr, EOBJLIST) && funcexpr->data.objlist.name) {
- funcexpr->data.objlist.list = CScope_ArgumentDependentNameLookup(
- funcexpr->data.objlist.list,
- funcexpr->data.objlist.name,
- arg_exprs, 0);
- if (!funcexpr->data.objlist.list) {
- CError_Error(CErrorStr140, CError_GetNameString(NULL, funcexpr->data.objlist.name));
- return nullnode();
- }
-
- if (
- funcexpr->data.objlist.list->object->otype == OT_OBJECT &&
- (TYPE_FUNC(OBJECT(funcexpr->data.objlist.list->object)->type)->flags & FUNC_INTRINSIC) &&
- (expr = CodeGen_HandleIntrinsicCall(OBJECT(funcexpr->data.objlist.list->object), arg_exprs)))
- return expr;
-
- return CExpr_GenericFuncCall(
- NULL, NULL, 0, NULL,
- funcexpr->data.objlist.list,
- funcexpr->data.objlist.templargs,
- arg_exprs, 0, 0, 1);
- }
-
- if (ENODE_IS(funcexpr, EMEMBER)) {
- save_path = funcexpr->data.emember->path;
- save_expr = funcexpr->data.emember->expr;
- save_1D = funcexpr->data.emember->pr_1D;
- save_isambig = funcexpr->data.emember->isambig;
- funcexpr = CExpr_ConvertEMember(funcexpr);
- if (!funcexpr) {
- CError_Error(CErrorStr161);
- return nullnode();
- }
- } else {
- save_path = NULL;
- save_expr = NULL;
- save_1D = 0;
- save_isambig = 0;
- }
-
- if (ENODE_IS(funcexpr, EOBJREF) && IS_TYPE_FUNC(funcexpr->data.objref->type) && (TYPE_FUNC(funcexpr->data.objref->type)->flags & FUNC_INTRINSIC)) {
- if (!(expr = CodeGen_HandleIntrinsicCall(funcexpr->data.objref, arg_exprs))) {
- expr = CExpr_GenericFuncCall(
- save_path, save_expr, save_1D, funcexpr->data.objref,
- NULL, NULL,
- arg_exprs, 0, save_isambig, 1);
- }
- return expr;
- }
-
- if (ENODE_IS(funcexpr, EOBJLIST)) {
- return CExpr_GenericFuncCall(
- save_path, save_expr, save_1D, NULL,
- funcexpr->data.objlist.list, funcexpr->data.objlist.templargs,
- arg_exprs, 0, save_isambig, 1);
- }
-
- if (!IS_TYPE_POINTER_ONLY(funcexpr->rtype) || !IS_TYPE_FUNC((tfunc = TYPE_FUNC(TYPE_POINTER(funcexpr->rtype)->target)))) {
- CError_Error(CErrorStr161);
- return nullnode();
- }
-
- if (ENODE_IS(funcexpr, EOBJREF)) {
- return CExpr_GenericFuncCall(
- save_path, save_expr, save_1D, funcexpr->data.objref,
- NULL, NULL, arg_exprs, 0, save_isambig, 1);
- }
-
- scan_expr = arg_exprs; // r25
- scan_arg = tfunc->args; // r26
- has_varargs = 0;
- while (scan_expr) {
- if (!has_varargs) {
- if (!scan_arg) {
- CError_Error(CErrorStr162);
- return nullnode();
- }
- if (scan_arg == &elipsis || scan_arg == &oldstyle) {
- scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, scan_arg == &elipsis);
- has_varargs = 1;
- } else {
- scan_expr->node = argumentpromotion(scan_expr->node, scan_arg->type, scan_arg->qual, 1);
- scan_arg = scan_arg->next;
- }
- } else {
- scan_expr->node = CExpr_VarArgPromotion(scan_expr->node, 0);
- }
- scan_expr = scan_expr->next;
- }
-
- if (!has_varargs && scan_arg && scan_arg != &elipsis && scan_arg != &oldstyle) {
- do {
- if (!scan_arg->dexpr) {
- CError_Error(CErrorStr162);
- return nullnode();
- }
-
- if (arg_exprs) {
- scan_expr = arg_exprs;
- while (scan_expr->next)
- scan_expr = scan_expr->next;
- scan_expr->next = lalloc(sizeof(ENodeList));
- scan_expr = scan_expr->next;
- } else {
- scan_expr = lalloc(sizeof(ENodeList));
- arg_exprs = scan_expr;
- }
-
- scan_expr->next = NULL;
- scan_expr->node = CExpr_GetDefaultArgument(funcexpr, scan_arg);
- } while ((scan_arg = scan_arg->next) && scan_arg != &elipsis && scan_arg != &oldstyle);
- }
-
- expr = CExpr_NewENode(EFUNCCALL);
- expr->cost = 4;
- expr->rtype = tfunc->functype;
- expr->flags = tfunc->qual & ENODE_FLAG_QUALS;
- expr->data.funccall.funcref = funcexpr;
- expr->data.funccall.args = arg_exprs;
- expr->data.funccall.functype = tfunc;
- return CExpr_AdjustFunctionCall(expr);
-}
-
-static Boolean accept_conversion_type(Type *type, short mode) {
- switch (mode) {
- case 0:
- return IS_TYPE_INT(type);
- case 1:
- return IS_TYPE_INT_OR_FLOAT(type);
- case 2:
- return IS_TYPE_INT_OR_FLOAT(type) || IS_TYPE_POINTER_ONLY(type);
- case 3:
- return IS_TYPE_POINTER_ONLY(type);
- default:
- CError_FATAL(3912);
- return 0;
- }
-}
-
-static ENode *CExpr_OperatorConversion(ENode *expr, Type *type, UInt32 qual) {
- if (IS_TYPE_CLASS(expr->rtype) && type) {
- if (user_assign_check(expr, type, qual, 1, 0, 1))
- return assign_node;
- CError_Error(CErrorStr144);
- }
- return expr;
-}
-
-static Boolean wild_conversion_check(ENode *left, ENode *right, Conversion *conv) {
- ConversionIterator iter;
- Object *obj;
-
- Type *check;
- Type *left_type;
- Type *right_type;
-
- left_type = right_type = NULL;
- if (IS_TYPE_CLASS(left->rtype)) {
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(left->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- check = TYPE_FUNC(obj->type)->functype;
- if (accept_conversion_type(check, 2)) {
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, 2))
- CError_Error(CErrorStr199);
- }
- left_type = check;
- goto found_left;
- }
- }
- return 0;
- }
-found_left:
- if (IS_TYPE_CLASS(right->rtype)) {
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(right->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- check = TYPE_FUNC(obj->type)->functype;
- if (accept_conversion_type(check, 2)) {
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, 2))
- CError_Error(CErrorStr199);
- }
- right_type = check;
- goto found_right;
- }
- }
- return 0;
- }
-found_right:
- conv->x0 = NULL;
- conv->left = CExpr_OperatorConversion(left, left_type, 0);
- conv->right = CExpr_OperatorConversion(right, right_type, 0);
- return 1;
-}
-
-static Boolean monadic_conversion_check(ENode *expr, short which, Conversion *conv) {
- ConversionIterator iter;
- Object *obj;
- Type *check;
-
- if (!IS_TYPE_CLASS(expr->rtype))
- return 0;
-
- if (which == 4)
- which = 2;
- else if (which == 5)
- which = 1;
-
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- check = TYPE_FUNC(obj->type)->functype;
- if (accept_conversion_type(check, which)) {
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (accept_conversion_type(TYPE_FUNC(obj->type)->functype, which))
- CError_Error(CErrorStr199);
- }
-
- conv->x0 = NULL;
- conv->left = CExpr_OperatorConversion(expr, check, 0);
- conv->right = NULL;
- return 1;
- }
- }
-
- return 0;
-}
-
-static Boolean is_legal_type_combination(Type *left, Type *right, short mode) {
- int left_type;
- int right_type;
-
- if (IS_TYPE_ENUM(left))
- left = TYPE_ENUM(left)->enumtype;
- if (IS_TYPE_ENUM(right))
- right = TYPE_ENUM(right)->enumtype;
-
- if (IS_TYPE_REFERENCE(left))
- left = TYPE_POINTER(left)->target;
- if (IS_TYPE_REFERENCE(right))
- right = TYPE_POINTER(right)->target;
-
- left_type = left->type; // r7
- right_type = right->type; // r8
- switch (mode) {
- case 3:
- if (left_type != TYPEPOINTER || right_type != TYPEPOINTER)
- return 0;
- use_cpp_typeequal:
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return iscpp_typeequal(left, right);
- case 7:
- if ((left_type == TYPEPOINTER && right_type == TYPEINT) || (left_type == TYPEINT && right_type == TYPEPOINTER)) {
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return 1;
- }
- return 0;
- case 6:
- if ((left_type == TYPEPOINTER && right_type == TYPEINT) || (left_type == TYPEINT && right_type == TYPEPOINTER)) {
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return 1;
- }
- case 2:
- if (left_type == TYPEPOINTER || right_type == TYPEPOINTER)
- goto use_cpp_typeequal;
- case 1:
- mode1:
- if (left_type == TYPEFLOAT || right_type == TYPEFLOAT) {
- if (left_type == TYPEFLOAT) {
- if (right_type == TYPEFLOAT) {
- if (TYPE_INTEGRAL(right)->integral > TYPE_INTEGRAL(left)->integral)
- left = right;
- diadic_arg2.type = left;
- diadic_arg1.type = left;
- return 1;
- }
- if (right_type != TYPEINT)
- return 0;
- diadic_arg2.type = left;
- diadic_arg1.type = left;
- return 1;
- }
- if (left_type != TYPEINT)
- return 0;
- diadic_arg2.type = right;
- diadic_arg1.type = right;
- return 1;
- }
- case 0:
- if (left_type != TYPEINT || right_type != TYPEINT)
- return 0;
- if (TYPE_INTEGRAL(right)->integral > TYPE_INTEGRAL(left)->integral)
- left = right;
- if (TYPE_INTEGRAL(left)->integral < IT_INT)
- left = TYPE(&stsignedint);
- diadic_arg2.type = left;
- diadic_arg1.type = left;
- return 1;
- case 4:
- if (left_type == TYPEPOINTER) {
- if (right_type != TYPEINT)
- return 0;
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return 1;
- }
- if (right_type == TYPEPOINTER) {
- if (left_type != TYPEINT)
- return 0;
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return 1;
- }
- goto mode1;
- case 5:
- if (left_type != TYPEPOINTER)
- goto mode1;
- if (right_type == TYPEPOINTER)
- goto use_cpp_typeequal;
- if (right_type != TYPEINT)
- return 0;
- diadic_arg1.type = left;
- diadic_arg2.type = right;
- return 1;
- default:
- CError_FATAL(4132);
- return 0;
- }
-}
-
-static void match_class_type_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) {
- ConversionIterator iter;
- Object *obj;
-
- if (which == 6) {
- if (!ENODE_IS(right, EINTCONST) || !CInt64_IsZero(&right->data.intval) || !IS_TYPE_INT(right->rtype))
- which = 2;
- }
-
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(left->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (is_legal_type_combination(TYPE_FUNC(obj->type)->functype, right->rtype, which)) {
- MatchOverloadFunc(obj, &diadic_arg1, list, match);
- if (match->obj == obj) {
- cexpr_left_conversion_type = diadic_arg1.type;
- cexpr_right_conversion_type = diadic_arg2.type;
- }
- }
- }
-}
-
-static void match_type_class_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) {
- ConversionIterator iter;
- Object *obj;
-
- if (which == 6) {
- if (!ENODE_IS(left, EINTCONST) || !CInt64_IsZero(&left->data.intval) || !IS_TYPE_INT(left->rtype))
- which = 2;
- }
-
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(right->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (is_legal_type_combination(left->rtype, TYPE_FUNC(obj->type)->functype, which)) {
- MatchOverloadFunc(obj, &diadic_arg1, list, match);
- if (match->obj == obj) {
- cexpr_left_conversion_type = diadic_arg1.type;
- cexpr_right_conversion_type = diadic_arg2.type;
- }
- }
- }
-}
-
-static void match_class_class_conversion(Match13 *match, ENode *left, ENode *right, ENodeList *list, short which) {
- ConversionIterator iter_left;
- ConversionIterator iter_right;
- Object *obj_left;
- Object *obj_right;
-
- if (which == 6)
- which = 2;
-
- CExpr_ConversionIteratorInit(&iter_left, TYPE_CLASS(left->rtype));
- while ((obj_left = CExpr_ConversionIteratorNext(&iter_left))) {
- CExpr_ConversionIteratorInit(&iter_right, TYPE_CLASS(right->rtype));
- while ((obj_right = CExpr_ConversionIteratorNext(&iter_right))) {
- if (is_legal_type_combination(TYPE_FUNC(obj_left->type)->functype, TYPE_FUNC(obj_right->type)->functype, which)) {
- MatchOverloadFunc(obj_left, &diadic_arg1, list, match);
- if (match->obj == obj_left) {
- cexpr_left_conversion_type = diadic_arg1.type;
- cexpr_right_conversion_type = diadic_arg2.type;
- }
- }
- }
- }
-}
-
-Boolean CExpr_CheckOperatorConversion(short token, ENode *left, ENode *right, ENodeList *list, Conversion *conv) {
- Match13 match;
- short which;
-
- switch (token) {
- case '*':
- if (!right) {
- which = 3;
- break;
- }
- case '/':
- which = 1;
- break;
- case '&':
- if (!right)
- return 0;
- case '%':
- case '^':
- case '|':
- case '~':
- case TK_SHL:
- case TK_SHR:
- which = 0;
- break;
- case '[':
- which = 7;
- break;
- case '+':
- which = 4;
- break;
- case '-':
- which = 5;
- break;
- case '!':
- case ':':
- case '<':
- case '>':
- case TK_LESS_EQUAL:
- case TK_GREATER_EQUAL:
- which = 2;
- break;
- case TK_LOGICAL_EQ:
- case TK_LOGICAL_NE:
- which = 6;
- break;
- case TK_LOGICAL_OR:
- case TK_LOGICAL_AND:
- return wild_conversion_check(left, right, conv);
- default:
- return 0;
- }
-
- if (!right)
- return monadic_conversion_check(left, which, conv);
-
- cexpr_left_conversion_type = cexpr_right_conversion_type = NULL;
- memclrw(&match, sizeof(Match13));
-
- if (IS_TYPE_CLASS(left->rtype)) {
- if (IS_TYPE_CLASS(right->rtype))
- match_class_class_conversion(&match, left, right, list, which);
- else
- match_class_type_conversion(&match, left, right, list, which);
- } else {
- if (IS_TYPE_CLASS(right->rtype))
- match_type_class_conversion(&match, left, right, list, which);
- else
- return 0;
- }
-
- if (!match.obj)
- return 0;
- if (match.list)
- CError_OverloadedFunctionError(match.obj, match.list);
-
- conv->x0 = NULL;
- conv->left = CExpr_OperatorConversion(left, cexpr_left_conversion_type, 0);
- conv->right = CExpr_OperatorConversion(right, cexpr_right_conversion_type, 0);
- return 1;
-}
-
-Boolean CExpr_CheckOperator(short token, ENode *left, ENode *right, Conversion *conv) {
- Match13 match;
- NameResult pr;
- NameResult pr2;
- ENode *expr;
- Object *obj;
- ENodeList *nodes;
- HashNameNode *name;
- BClassList *path;
- EMemberInfo *member;
- Object *prev_obj;
- NameSpaceObjectList mylist_A8;
- NameSpaceObjectList mylist_B0;
-
- if (!copts.old_argmatch) {
- if (token == '(') {
- CDecl_CompleteType(left->rtype);
- if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr,
- CMangler_OperatorName(token))) {
- if (pr.nsol_14 || (pr.obj_10 && pr.obj_10->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(pr.obj_10)->type))) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
- member->path = pr.bcl_18;
- member->expr = left;
- member->pr_1D = pr.x1D;
- if (!pr.nsol_14) {
- member->list = galloc(sizeof(NameSpaceObjectList));
- member->list->next = NULL;
- member->list->object = pr.obj_10;
- } else {
- member->list = pr.nsol_14;
- }
- expr = CExpr_NewENode(EMEMBER);
- expr->rtype = &stvoid;
- expr->data.emember = member;
- tk = lex();
- conv->x0 = checkreference(CExpr_MakeFunctionCall(expr, CExpr_ScanExpressionList(1)));
- conv->left = NULL;
- conv->right = NULL;
- tk = lex();
- return 1;
- } else {
- CError_FATAL(4371);
- }
- }
- return 0;
- } else {
- return CExpr_OperatorMatch(token, left, right, conv);
- }
- }
-
- if (!IS_TYPE_CLASS(left->rtype)) {
- if (!IS_TYPE_ENUM(left->rtype)) {
- if (!right)
- return 0;
- if (!IS_TYPE_CLASS(right->rtype) && !IS_TYPE_ENUM(right->rtype))
- return 0;
- }
- } else {
- CDecl_CompleteType(left->rtype);
- }
-
- memclrw(&match, sizeof(Match13));
- name = CMangler_OperatorName(token);
- if (token == '(') {
- if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr2, name)) {
- if (pr2.nsol_14 || (pr2.obj_10 && pr2.obj_10->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(pr2.obj_10)->type))) {
- member = lalloc(sizeof(EMemberInfo));
- memclrw(member, sizeof(EMemberInfo));
- member->path = pr2.bcl_18;
- member->expr = left;
- member->pr_1D = pr2.x1D;
- if (!pr2.nsol_14) {
- member->list = galloc(sizeof(NameSpaceObjectList));
- member->list->next = NULL;
- member->list->object = pr2.obj_10;
- } else {
- member->list = pr2.nsol_14;
- }
- expr = CExpr_NewENode(EMEMBER);
- expr->rtype = &stvoid;
- expr->data.emember = member;
- tk = lex();
- conv->x0 = checkreference(CExpr_MakeFunctionCall(expr, CExpr_ScanExpressionList(1)));
- conv->left = NULL;
- conv->right = NULL;
- tk = lex();
- return 1;
- } else {
- CError_FATAL(4439);
- }
- }
- return 0;
- }
-
- nodes = lalloc(sizeof(ENodeList));
- nodes->node = left;
- if (right) {
- nodes->next = lalloc(sizeof(ENodeList));
- nodes->next->node = right;
- nodes->next->next = NULL;
- } else {
- nodes->next = NULL;
- }
-
- obj = NULL;
- if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr2, name)) {
- if (pr2.obj_10) {
- mylist_B0.next = NULL;
- mylist_B0.object = pr2.obj_10;
- pr2.nsol_14 = &mylist_B0;
- } else {
- CError_ASSERT(4470, pr2.nsol_14);
- }
-
- if (token != '=' || (pr2.bcl_18->type == left->rtype && pr2.bcl_18->next == NULL)) {
- prev_obj = match.obj;
- CExpr_MatchArgList(pr2.nsol_14, NULL, nodes->next, &match, left, 0);
- if (prev_obj != match.obj) {
- obj = match.obj;
- path = pr2.bcl_18;
- }
- }
- }
-
- if (CScope_FindNonClassObject(cscope_current, &pr2, name)) {
- if (pr2.obj_10) {
- mylist_A8.next = NULL;
- mylist_A8.object = pr2.obj_10;
- pr2.nsol_14 = &mylist_A8;
- }
- } else {
- pr2.nsol_14 = NULL;
- }
-
- if (copts.arg_dep_lookup)
- pr2.nsol_14 = CScope_ArgumentDependentNameLookup(pr2.nsol_14, name, nodes, 1);
- if (pr2.nsol_14)
- CExpr_MatchArgList(pr2.nsol_14, NULL, nodes, &match, NULL, 0);
-
- if (!match.obj) {
- if (!IS_TYPE_CLASS(left->rtype) && (!right || !IS_TYPE_CLASS(right->rtype)))
- return 0;
- return CExpr_CheckOperatorConversion(token, left, right, nodes, conv);
- }
-
- if (!(token == '&' && !right) && (token != ',')) {
- if (!IS_TYPE_CLASS(left->rtype) && (!right || !IS_TYPE_CLASS(right->rtype)) && match.xE)
- return 0;
- if (right && match.xE == 2 && CExpr_CheckOperatorConversion(token, left, right, nodes, conv))
- return 1;
- }
-
- if (match.list)
- CError_OverloadedFunctionError(match.obj, match.list);
-
- if (match.obj == obj) {
- conv->x0 = CExpr_GenericFuncCall(path, nodes->node, 0, match.obj, NULL, NULL, nodes->next, 0, 0, 1);
- } else {
- conv->x0 = CExpr_GenericFuncCall(NULL, NULL, 0, match.obj, NULL, NULL, nodes, 0, 0, 1);
- }
-
- conv->x0 = checkreference(conv->x0);
- conv->left = NULL;
- conv->right = NULL;
- return 1;
-}
-
-ENode *CExpr_ConstructObject(TypeClass *tclass, ENode *addr_expr, ENodeList *args, Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4, Boolean flag5) {
- ENode *expr;
- NameSpaceObjectList *ctorlist;
- BClassList path;
-
- CError_ASSERT(4595, IS_TYPE_POINTER_ONLY(addr_expr->rtype));
-
- addr_expr = makemonadicnode(addr_expr, EINDIRECT);
- addr_expr->rtype = TYPE(tclass);
-
- if (!flag3 && args && !args->next && args->node->rtype == TYPE(tclass) && !CClass_CopyConstructor(tclass)) {
- CError_ASSERT(4605, IS_TYPE_CLASS(addr_expr->rtype));
- expr = makediadicnode(addr_expr, args->node, EASS);
- if (!flag1)
- expr = getnodeaddress(expr, 0);
- return expr;
- }
-
- if ((ctorlist = CClass_Constructor(tclass))) {
- if (tclass->flags & CLASS_HAS_VBASES) {
- ENodeList *list = lalloc(sizeof(ENodeList));
- list->next = args;
- args = list;
- list->node = intconstnode(TYPE(&stsignedshort), flag2 != 0);
- }
- path.next = NULL;
- path.type = TYPE(tclass);
- expr = CExpr_GenericFuncCall(&path, addr_expr, 0, NULL, ctorlist, NULL, args, !flag5, 0, flag4);
- if (ENODE_IS2(expr, EFUNCCALL, EFUNCCALLP))
- expr->rtype = CDecl_NewPointerType(TYPE(tclass));
- if (flag1) {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TYPE(tclass);
- }
- return expr;
- } else {
- if (args) {
- if (!args->next && ENODE_IS(addr_expr, EINDIRECT)) {
- return makediadicnode(
- addr_expr,
- CExpr_AssignmentPromotion(args->node, TYPE(tclass), 0, 1),
- EASS);
- }
- CError_Error(CErrorStr174);
- }
- return addr_expr;
- }
-}
-
-static ENode *CExpr_DeleteFuncCall(Object *obj, ENode *arg, Type *type, Boolean include_size) {
- ENode *expr;
- ENodeList *list;
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->flags = 0;
- expr->rtype = &stvoid;
- expr->data.funccall.funcref = create_objectrefnode(obj);
- expr->data.funccall.functype = TYPE_FUNC(obj->type);
- obj->flags |= OBJECT_USED;
-
- list = lalloc(sizeof(ENodeList));
- list->node = arg;
- expr->data.funccall.args = list;
-
- if (include_size) {
- list->next = lalloc(sizeof(ENodeList));
- list->next->node = nullnode();
- CInt64_SetLong(&list->next->node->data.intval, type->size);
- list->next->node->rtype = CABI_GetSizeTType();
- list->next->next = NULL;
- } else {
- list->next = NULL;
- }
-
- return expr;
-}
-
-static ENode *CExpr_CopyPlacementNewArg(ENodeList *list) {
- switch (list->node->type) {
- case EINDIRECT:
- if (!ENODE_IS(list->node->data.monadic, EOBJREF))
- break;
- if (list->node->data.monadic->data.objref->datatype != DLOCAL && !is_const_object(list->node->data.monadic->data.objref))
- break;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EARGOBJ:
- case ELOCOBJ:
- case EOBJLIST:
- case EVECTOR128CONST:
- return CInline_CopyExpression(list->node, CopyMode0);
- }
-
- switch (list->node->rtype->type) {
- default:
- CError_FATAL(4726);
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- case TYPECLASS:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- case TYPEOBJCID:
- return CExpr_GetETEMPCopy(list->node);
- }
-}
-
-static ENode *CExpr_PlacementDeleteCall(Type *type, ENode *expr, Object *obj, Boolean flag1, Boolean flag2) {
- ENodeList *list;
- Object *funcobj;
- ENode *result;
- ENodeList *inputarg;
- Boolean outflag;
-
- CError_ASSERT(4752, ENODE_IS(expr, EFUNCCALL) && ENODE_IS(expr->data.funccall.funcref, EOBJREF));
-
- funcobj = expr->data.funccall.funcref->data.objref;
- CError_ASSERT(4756, IS_TYPE_FUNC(funcobj->type) && TYPE_FUNC(funcobj->type)->args && TYPE_FUNC(funcobj->type)->args->next);
-
- funcobj = CParser_FindDeallocationObject(type, TYPE_FUNC(funcobj->type)->args->next, flag1, flag2, &outflag);
- if (!funcobj)
- return NULL;
-
- result = CExpr_NewENode(EFUNCCALL);
- result->type = EFUNCCALL;
- result->cost = 4;
- result->rtype = &stvoid;
- result->data.funccall.funcref = create_objectrefnode(funcobj);
- result->data.funccall.functype = TYPE_FUNC(funcobj->type);
- funcobj->flags |= OBJECT_USED;
-
- list = lalloc(sizeof(ENodeList));
- list->node = create_objectnode(obj);
- result->data.funccall.args = list;
-
- CError_ASSERT(4780, (inputarg = expr->data.funccall.args) && (inputarg = inputarg->next));
-
- do {
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = CExpr_CopyPlacementNewArg(inputarg);
- inputarg = inputarg->next;
- } while (inputarg);
- list->next = NULL;
-
- return result;
-}
-
-static Type *scan_type_name(UInt32 *qual) {
- DeclInfo di;
- memclrw(&di, sizeof(DeclInfo));
-
- CParser_GetDeclSpecs(&di, 0);
- di.x46 = 1;
- scandeclarator(&di);
-
- if (di.name)
- CError_Error(CErrorStr146);
-
- firstarrayexpr = di.x24;
- *qual = di.qual;
- return di.thetype;
-}
-
-static UInt32 cv_qualifier_list(void) {
- UInt32 qual;
-
- qual = 0;
- tk = lex();
- while (tk >= TK_CONST && tk <= TK_ASM) {
- switch (tk) {
- case TK_CONST:
- if (qual & Q_CONST)
- CError_Error(CErrorStr121);
- qual |= Q_CONST;
- break;
- case TK_VOLATILE:
- if (qual & Q_VOLATILE)
- CError_Error(CErrorStr121);
- qual |= Q_VOLATILE;
- break;
- default:
- CError_Error(CErrorStr121);
- }
-
- tk = lex();
- }
-
- return qual;
-}
-
-static void scan_new_declarator(DeclInfo *di, Boolean flag) {
- NameResult pr;
- SInt32 size;
- ENode *expr;
-
- switch (tk) {
- case '*':
- makethetypepointer(di, cv_qualifier_list());
- if (tk != '[')
- scan_new_declarator(di, flag);
- break;
- case TK_IDENTIFIER:
- case TK_COLON_COLON:
- if (CScope_ParseQualifiedNameSpace(&pr, 1, 0) && pr.nspace_0 && pr.nspace_0->theclass && tk == '*') {
- makememberpointertype(di, pr.nspace_0->theclass, cv_qualifier_list());
- if (tk != '[')
- scan_new_declarator(di, flag);
- } else {
- CError_Error(CErrorStr121);
- }
- break;
- }
-
- if (tk == '[') {
- tk = lex();
- expr = expression();
-
- if (IS_TYPE_ENUM(expr->rtype))
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- if (!IS_TYPE_INT(expr->rtype))
- CError_Error(CErrorStr146);
-
- if (tk != ']')
- CError_Error(CErrorStr125);
- else
- tk = lex();
-
- if (tk == '[')
- scan_new_declarator(di, 0);
-
- if (CanCreateObject(di->thetype) && IsCompleteType(di->thetype)) {
- di->thetype = CDecl_NewArrayType(di->thetype, 0);
- if (!ENODE_IS(expr, EINTCONST)) {
- size = 1;
- if (!flag)
- CError_Error(CErrorStr124);
- else
- firstarrayexpr = expr;
- } else {
- size = CInt64_GetULong(&expr->data.intval);
- }
- TYPE_POINTER(di->thetype)->size = size * TYPE_POINTER(di->thetype)->target->size;
- } else {
- CError_Error(CErrorStr129);
- }
- }
-}
-
-static Type *scan_new_type_name(UInt32 *qual) {
- DeclInfo di;
- memclrw(&di, sizeof(DeclInfo));
-
- di.x4F = 1;
- CParser_GetDeclSpecs(&di, 0);
- scan_new_declarator(&di, 1);
-
- *qual = di.qual;
- return di.thetype;
-}
-
-static ENode *CExpr_NewAlloc(Type *type, ENodeList *args, Boolean flag1, Boolean flag2) {
- NameSpaceObjectList *list;
- Object *obj;
- Boolean found;
- HashNameNode *name;
- NameResult pr;
-
- found = 0;
- if (!flag1 && IS_TYPE_CLASS(type)) {
- list = NULL;
- obj = NULL;
- name = (flag2 && copts.array_new_delete) ? newa_fobj->name : newp_fobj->name;
- if (CScope_FindClassMemberObject(TYPE_CLASS(type), &pr, name)) {
- list = pr.nsol_14;
- obj = OBJECT(pr.obj_10);
- CError_ASSERT(4935, list || obj);
- found = 1;
- } else if (TYPE_CLASS(type)->flags & CLASS_HANDLEOBJECT) {
- CError_ASSERT(4942, !flag2);
- obj = newh_func;
- found = 1;
- }
- }
-
- if (!found) {
- if (flag2 && copts.array_new_delete)
- list = &newa_fobj->first;
- else
- list = &newp_fobj->first;
- obj = NULL;
- }
-
- return CExpr_GenericFuncCall(NULL, NULL, 0, obj, list, NULL, args, 0, 0, 1);
-}
-
-static ENode *CExpr_NewExceptionSafeAlloc(Type *type, ENode *node, ENodeList *args, Boolean flag1, Boolean flag2, Object **objptr) {
- Object *obj;
- ENode *result;
- ENode *catchexpr;
- Object *deletefunc;
- Boolean include_size;
-
- if (!cscope_currentfunc || !copts.delete_exception || !copts.exceptions)
- return NULL;
-
- obj = create_temp_object(TYPE(&void_ptr));
- *objptr = obj;
- deletefunc = NULL;
- catchexpr = NULL;
- include_size = 0;
- if (args)
- catchexpr = CExpr_PlacementDeleteCall(type, node, obj, flag1, flag2);
- if (!args)
- deletefunc = CParser_FindDeallocationObject(type, NULL, flag1, flag2, &include_size);
-
- if (!deletefunc && !catchexpr)
- return NULL;
-
- result = lalloc(sizeof(ENode));
- *result = *node;
- node = makediadicnode(create_objectnode(obj), node, EASS);
- if (!catchexpr && !include_size) {
- result->type = ENEWEXCEPTION;
- result->data.newexception.initexpr = node;
- result->data.newexception.tryexpr = NULL;
- result->data.newexception.pointertemp = obj;
- result->data.newexception.deletefunc = deletefunc;
- } else {
- if (!catchexpr)
- catchexpr = CExpr_DeleteFuncCall(deletefunc, create_objectnode(obj), type, include_size);
- result->type = EINITTRYCATCH;
- result->data.itc.initexpr = node;
- result->data.itc.tryexpr = NULL;
- result->data.itc.result = create_objectnode(obj);
- result->data.itc.catchexpr = catchexpr;
- }
-
- return result;
-}
-
-static ENode *CExpr_NewExceptionSafeInit(ENode *expr, ENode *tryexpr) {
- switch (expr->type) {
- case ENEWEXCEPTION:
- expr->data.newexception.tryexpr = tryexpr;
- break;
- case EINITTRYCATCH:
- expr->data.itc.tryexpr = tryexpr;
- break;
- default:
- CError_FATAL(5056);
- }
- return expr;
-}
-
-static ENode *CExpr_NewArray(Type *type, UInt32 qual, ENodeList *nodelist, Boolean flag) {
- Type *tptr;
- Type *sizetype;
- Type *innertype;
- ENodeList *newlist;
- ENode *result;
- Object *ctor;
- Object *dtor;
- ENode *ass;
- ENode *etemp;
- ENode *mul;
- SInt32 count;
- ENode *newalloc;
- ENode *newESalloc;
- Object *tempobj;
- ENode *callexpr;
-
- tptr = CDecl_NewPointerType(TYPE_POINTER(type)->target);
- sizetype = CABI_GetSizeTType();
- innertype = TYPE_POINTER(type)->target;
- while (IS_TYPE_ARRAY(innertype))
- innertype = TYPE_POINTER(innertype)->target;
-
- if (!CanAllocObject(innertype) || !IsCompleteType(innertype))
- return nullnode();
-
- newlist = lalloc(sizeof(ENodeList));
- newlist->next = nodelist;
- if (tk == '(') {
- tk = lex();
- if (CExpr_ScanExpressionList(1))
- CError_Error(CErrorStr174);
- if (tk == ')')
- tk = lex();
- else
- CError_Error(CErrorStr115);
- }
-
- if (!IS_TYPE_CLASS(innertype) || CClass_IsPODClass(TYPE_CLASS(innertype))) {
- newlist->node = intconstnode(sizetype, type->size);
- if (firstarrayexpr) {
- newlist->node = makediadicnode(newlist->node, promote(firstarrayexpr, sizetype), EMUL);
- optimizecomm(newlist->node);
- }
- result = CExpr_NewAlloc(innertype, newlist, flag, 1);
- result->rtype = tptr;
- result->flags |= (qual & ENODE_FLAG_QUALS);
- return result;
- }
-
- ctor = NULL;
- if (CClass_Constructor(TYPE_CLASS(innertype))) {
- ctor = CClass_DefaultConstructor(TYPE_CLASS(innertype));
- if (ctor) {
- ctor->flags |= OBJECT_USED;
- } else {
- ctor = CClass_DummyDefaultConstructor(TYPE_CLASS(innertype));
- if (!ctor)
- CError_Error(CErrorStr203);
- }
- }
-
- dtor = CClass_Destructor(TYPE_CLASS(innertype));
- if (dtor)
- dtor = CABI_GetDestructorObject(dtor, CABIDestroy1);
-
- ass = NULL;
- if (firstarrayexpr) {
- etemp = CExpr_NewETEMPNode(sizetype, 1);
- mul = promote(firstarrayexpr, sizetype);
- if (innertype->size)
- count = type->size / innertype->size;
- else
- count = 0;
- if (count > 1) {
- mul = makediadicnode(mul, intconstnode(sizetype, count), EMUL);
- optimizecomm(mul);
- }
- ass = makediadicnode(CExpr_DerefETEMPCopy(etemp), mul, EASS);
- mul = makediadicnode(CExpr_DerefETEMPCopy(etemp), intconstnode(sizetype, innertype->size), EMUL);
- optimizecomm(mul);
- mul = makediadicnode(mul, intconstnode(sizetype, 16), EADD);
- optimizecomm(mul);
- newlist->node = mul;
- etemp = CExpr_DerefETEMPCopy(etemp);
- } else {
- newlist->node = intconstnode(sizetype, type->size + 16);
- if (innertype->size)
- count = type->size / innertype->size;
- else
- count = 0;
- etemp = intconstnode(sizetype, count);
- }
-
- newalloc = CExpr_NewAlloc(innertype, newlist, flag, 1);
- newalloc->rtype = tptr;
- newESalloc = CExpr_NewExceptionSafeAlloc(innertype, newalloc, nodelist, 1, flag, &tempobj);
- if (newESalloc) {
- callexpr = CExpr_FuncCallSix(
- cnar_func,
- create_objectnode(tempobj),
- ctor ? create_objectrefnode(ctor) : nullnode(),
- dtor ? create_objectrefnode(dtor) : nullnode(),
- intconstnode(sizetype, innertype->size),
- etemp,
- NULL
- );
- result = CExpr_NewExceptionSafeInit(newESalloc, makediadicnode(create_objectnode(tempobj), callexpr, EASS));
- } else {
- result = CExpr_FuncCallSix(
- cnar_func,
- newalloc,
- ctor ? create_objectrefnode(ctor) : nullnode(),
- dtor ? create_objectrefnode(dtor) : nullnode(),
- intconstnode(sizetype, innertype->size),
- etemp,
- NULL
- );
- }
-
- if (ass)
- result = makecommaexpression(ass, result);
- result->rtype = tptr;
- result->flags |= (qual & ENODE_FLAG_QUALS);
- return result;
-}
-
-static ENode *CExpr_NewSimpleClass(TypeClass *tclass, ENode *expr, ENodeList *args) {
- ENode *precomp;
- ENode *nullcheck;
-
- precomp = lalloc(sizeof(ENode));
- *precomp = *expr;
- precomp->type = EPRECOMP;
- precomp->data.precompid = CParser_GetUniqueID();
-
- nullcheck = lalloc(sizeof(ENode));
- *nullcheck = *expr;
- nullcheck->type = ENULLCHECK;
- nullcheck->cost = 4;
- nullcheck->data.nullcheck.nullcheckexpr = expr;
- nullcheck->data.nullcheck.condexpr = CExpr_ConstructObject(tclass, precomp, args, 0, 1, 1, 1, 1);
- nullcheck->data.nullcheck.precompid = precomp->data.precompid;
- return nullcheck;
-}
-
-static ENode *CExpr_NewClass(TypeClass *tclass, ENode *expr, ENodeList *args1, ENodeList *args2, Boolean flag) {
- Object *objptr;
- ENode *newESalloc;
-
- if (!args2 && !flag && CABI_ConstructorCallsNew(tclass)) {
- expr = nullnode();
- expr->rtype = CDecl_NewPointerType(TYPE(tclass));
- return CExpr_ConstructObject(tclass, expr, args1, 0, 1, 1, 1, 1);
- } else {
- newESalloc = CExpr_NewExceptionSafeAlloc(TYPE(tclass), expr, args2, 0, flag, &objptr);
- if (newESalloc) {
- return CExpr_NewExceptionSafeInit(
- newESalloc,
- CExpr_ConstructObject(tclass, create_objectnode(objptr), args1, 0, 1, 1, 1, 1));
- } else {
- return CExpr_NewSimpleClass(tclass, expr, args1);
- }
- }
-}
-
-ENode *scannew(Boolean flag) {
- Type *type; // r27
- UInt32 qual;
- ENodeList *args; // r28
- Boolean placement_flag; // r26
- ENodeList *newargs; // r26
- ENode *expr; // r26
- ENodeList *args2; // r29
- Object *tempobj;
- ENode *newESalloc; // r28
- ENode *tempobj_expr; // r25
- ENode *etemp_expr; // r28
- ENode *indirect_expr; // r25
- ENode *ass; // r25
- ENode *cond; // r27
-
- type = NULL;
- args = NULL;
- firstarrayexpr = NULL;
- if ((tk = lex()) == '(') {
- tk = lex();
- placement_flag = isdeclaration(1, 1, 1, ')');
- if (!placement_flag)
- args = CExpr_ScanExpressionList(1);
- if (placement_flag)
- type = scan_type_name(&qual);
- if (tk != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- }
-
- if (!type) {
- if (tk == '(') {
- tk = lex();
- type = scan_type_name(&qual);
- if (tk != ')')
- CError_Error(CErrorStr115);
- else
- tk = lex();
- } else {
- type = scan_new_type_name(&qual);
- }
- }
-
- if (IS_TYPE_ARRAY(type))
- return CExpr_NewArray(type, qual, args, flag);
-
- if (IS_TYPE_CLASS(type)) {
- if (TYPE_CLASS(type)->sominfo)
- return CSOM_New(TYPE_CLASS(type));
- if (TYPE_CLASS(type)->objcinfo)
- return CObjC_New(TYPE_CLASS(type));
- }
-
- if (!IsCompleteType(type) || !CanAllocObject(type))
- return nullnode();
-
- newargs = lalloc(sizeof(ENodeList));
- newargs->next = args;
- newargs->node = intconstnode(CABI_GetSizeTType(), type->size);
-
- expr = CExpr_NewAlloc(type, newargs, flag, 0);
- expr->rtype = CDecl_NewPointerType(type);
- expr->flags |= (qual & ENODE_FLAG_QUALS);
-
- if (tk == '(') {
- tk = lex();
- args2 = CExpr_ScanExpressionList(1);
- if (!args2 && !IS_TYPE_CLASS(type)) {
- args2 = lalloc(sizeof(ENodeList));
- memclrw(args2, sizeof(ENodeList));
- args2->node = do_typecast(nullnode(), type, 0);
- }
- if (tk == ')')
- tk = lex();
- else
- CError_Error(CErrorStr115);
- } else {
- args2 = NULL;
- }
-
- if (ENODE_IS(expr, EINTCONST))
- return expr;
-
- if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type)))
- return CExpr_NewClass(TYPE_CLASS(type), expr, args2, args, flag);
-
- if (args2) {
- if (args2->next) {
- CError_Error(CErrorStr174);
- return nullnode();
- }
-
- newESalloc = CExpr_NewExceptionSafeAlloc(type, expr, args, 0, flag, &tempobj);
- if (newESalloc) {
- tempobj_expr = makemonadicnode(create_objectnode(tempobj), EINDIRECT);
- tempobj_expr->rtype = type;
- tempobj_expr->flags = args2->node->flags & ENODE_FLAG_QUALS;
- return CExpr_NewExceptionSafeInit(
- newESalloc,
- makediadicnode(tempobj_expr, CExpr_AssignmentPromotion(args2->node, type, newESalloc->flags, 1), EASS)
- );
- } else {
- etemp_expr = CExpr_GetETEMPCopy(expr);
- indirect_expr = makemonadicnode(etemp_expr, EINDIRECT);
- indirect_expr->rtype = type;
- indirect_expr->flags = args2->node->flags & ENODE_FLAG_QUALS;
- ass = makediadicnode(indirect_expr, CExpr_AssignmentPromotion(args2->node, type, indirect_expr->flags, 1), EASS);
- cond = CExpr_NewENode(ECOND);
- cond->cost = 4;
- cond->rtype = &stvoid;
- cond->data.cond.cond = expr;
- cond->data.cond.expr1 = ass;
- cond->data.cond.expr2 = nullnode();
- cond = makecommaexpression(cond, etemp_expr);
- cond->rtype = etemp_expr->rtype;
- cond->flags = etemp_expr->flags;
- return cond;
- }
- } else {
- return expr;
- }
-}
-
-static ENode *CExpr_DeleteArray(ENode *expr, Type *type, Boolean flag) {
- Object *obj;
- Object *dtor;
- Boolean outflag;
- ENode *precomp;
- SInt32 precompid;
- ENode *tmp;
- ENode *result;
-
- obj = CParser_FindDeallocationObject(type, NULL, 1, flag, &outflag);
-
- if (!IS_TYPE_CLASS(type) || CClass_IsPODClass(TYPE_CLASS(type)))
- return CExpr_DeleteFuncCall(obj, expr, type, outflag);
-
- dtor = CClass_Destructor(TYPE_CLASS(type));
- if (dtor || outflag) {
- if (obj->nspace == cscope_root && !outflag) {
- return funccallexpr(dnar_func, expr, dtor ? create_objectrefnode(dtor) : nullnode(), NULL, NULL);
- }
- return funccallexpr(
- dnar3_func,
- expr,
- dtor ? create_objectrefnode(dtor) : nullnode(),
- create_objectrefnode(obj),
- intconstnode(TYPE(&stsignedshort), outflag));
- }
-
- precomp = lalloc(sizeof(ENode));
- *precomp = *expr;
- precomp->type = EPRECOMP;
- precomp->data.precompid = precompid = CParser_GetUniqueID();
- tmp = CExpr_DeleteFuncCall(obj, makediadicnode(precomp, intconstnode(CABI_GetSizeTType(), 16), ESUB), type, 0);
-
- result = CExpr_NewENode(ENULLCHECK);
- result->rtype = &stvoid;
- result->cost = 4;
- result->data.nullcheck.nullcheckexpr = expr;
- result->data.nullcheck.condexpr = tmp;
- result->data.nullcheck.precompid = precompid;
-
- return result;
-}
-
-ENode *scandelete(Boolean flag) {
- Boolean is_array; // r24
- ENode *expr; // r25
- Type *conv_type; // r22
- UInt32 conv_qual; // r23
- Type *innertype; // r23
- Type *t;
- Object *obj;
- Object *dtor; // r24
- ENode *result_expr; // r24???
- ENode *precomp_orig; // r31
- SInt32 precompid; // r30
- Boolean is_virtual; // r23
- ENode *nc;
- ConversionIterator iter;
- Boolean outflag;
- BClassList path;
-
- if ((tk = lex()) == '[') {
- if ((tk = lex()) != ']')
- CError_Error(CErrorStr125);
- else
- tk = lex();
- is_array = 1;
- } else {
- is_array = 0;
- }
-
- expr = cast_expression();
- if (!IS_TYPE_POINTER_ONLY(expr->rtype)) {
- if (IS_TYPE_CLASS(expr->rtype)) {
- conv_type = NULL;
- CExpr_ConversionIteratorInit(&iter, TYPE_CLASS(expr->rtype));
- while ((obj = CExpr_ConversionIteratorNext(&iter))) {
- if (IS_TYPE_POINTER_ONLY(TYPE_FUNC(obj->type)->functype)) {
- if (conv_type) {
- CError_Error(CErrorStr199);
- break;
- }
- conv_type = TYPE_FUNC(obj->type)->functype;
- conv_qual = TYPE_FUNC(obj->type)->qual;
- }
- }
- if (conv_type) {
- if (!copts.old_argmatch) {
- expr = CExpr_Convert(expr, conv_type, conv_qual, 1, 1);
- } else {
- if (user_assign_check(expr, conv_type, conv_qual, 1, 0, 1))
- expr = assign_node;
- }
- }
- }
- if (!IS_TYPE_POINTER_ONLY(expr->rtype)) {
- CError_Error(CErrorStr146);
- return nullnode();
- }
- }
-
- innertype = TYPE_POINTER(expr->rtype)->target;
- if (innertype->size == 0)
- CDecl_CompleteType(innertype);
-
- if (IS_TYPE_ARRAY(innertype) && !is_array)
- CError_Error(CErrorStr146);
-
- if (is_array) {
- t = innertype;
- while (IS_TYPE_ARRAY(t))
- t = TYPE_POINTER(t)->target;
- return CExpr_DeleteArray(expr, t, flag);
- }
-
- if (copts.objective_c && CObjC_IsType_id(expr->rtype))
- return CObjC_Delete(NULL, expr);
-
- if (!IS_TYPE_CLASS(innertype)) {
- obj = CParser_FindDeallocationObject(innertype, NULL, 0, flag, &outflag);
- CClass_CheckObjectAccess(NULL, obj);
- return CExpr_DeleteFuncCall(obj, expr, innertype, outflag);
- }
-
- if (TYPE_CLASS(innertype)->sominfo)
- return CSOM_Delete(TYPE_CLASS(innertype), expr);
-
- if (TYPE_CLASS(innertype)->objcinfo)
- return CObjC_Delete(TYPE_CLASS(innertype), expr);
-
- if (!(TYPE_CLASS(innertype)->flags & CLASS_COMPLETED) && copts.pedantic)
- CError_Warning(CErrorStr136, innertype, 0);
-
- obj = CParser_FindDeallocationObject(innertype, NULL, 0, flag, &outflag);
- CClass_CheckObjectAccess(NULL, obj);
- dtor = CClass_Destructor(TYPE_CLASS(innertype));
- if (!dtor)
- return CExpr_DeleteFuncCall(obj, expr, innertype, outflag);
-
- path.next = NULL;
- path.type = innertype;
- CClass_CheckObjectAccess(&path, dtor);
-
- result_expr = lalloc(sizeof(ENode));
- result_expr->type = EFUNCCALL;
- result_expr->cost = 4;
- result_expr->flags = 0;
- result_expr->rtype = &stvoid;
- if (dtor->datatype == DVFUNC) {
- precomp_orig = expr;
- expr = lalloc(sizeof(ENode));
- *expr = *precomp_orig;
- expr->type = EPRECOMP;
- expr->data.precompid = precompid = CParser_GetUniqueID();
- is_virtual = 1;
- } else {
- is_virtual = 0;
- }
-
- if (!flag) {
- result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 1);
- } else {
- CError_ASSERT(5650, !outflag);
- result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 0);
- result_expr->rtype = TYPE(&void_ptr);
- result_expr = funccallexpr(obj, result_expr, NULL, NULL, NULL);
- obj->flags |= OBJECT_USED;
- }
-
- if (is_virtual) {
- nc = lalloc(sizeof(ENode));
- nc->type = ENULLCHECK;
- nc->rtype = &stvoid;
- nc->cost = 4;
- nc->flags = 0;
- nc->data.nullcheck.nullcheckexpr = precomp_orig;
- nc->data.nullcheck.condexpr = result_expr;
- nc->data.nullcheck.precompid = precompid;
- return nc;
- } else {
- return result_expr;
- }
-}
diff --git a/compiler_and_linker/unsorted/CExprConvMatch.c b/compiler_and_linker/unsorted/CExprConvMatch.c
deleted file mode 100644
index 5cc145f..0000000
--- a/compiler_and_linker/unsorted/CExprConvMatch.c
+++ /dev/null
@@ -1,2518 +0,0 @@
-#include "compiler/CExpr.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CInt64.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CTemplateFunc.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct StandardConv {
- Type *type1;
- Type *type2;
- UInt32 qual1;
- UInt32 qual2;
- Boolean x10; // unknown
- Boolean x11;
- Boolean x12;
- Boolean x13;
- Boolean x14;
- Boolean x15;
-} StandardConv;
-
-typedef enum EImplicitConvType {
- ICT_0,
- ICT_1,
- ICT_2,
- ICT_3
-} EImplicitConvType;
-
-typedef struct ImplicitConv {
- EImplicitConvType type;
- union {
- struct {
- Object *x2;
- StandardConv standardConv;
- } ic2;
- struct {
- StandardConv standardConv;
- } ic3;
- } u;
-} ImplicitConv;
-
-typedef struct ConversionTypeList {
- struct ConversionTypeList *next;
- Object *func;
- Type *type;
- UInt32 qual;
-} ConversionTypeList;
-
-typedef struct Match {
- struct Match *next;
- Object *object;
- Object *specialfunc;
- Type *type;
- UInt32 qual;
- Type *type2;
- UInt32 qual2;
- ImplicitConv conv[3];
-} Match;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// forward decls
-static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean flag2, Boolean flag3);
-
-static Type *CExpr_GetImplictObjectParamType(Object *object, UInt32 *qual) {
- Type *type;
-
- CError_ASSERT(98, IS_TYPE_FUNC(object->type));
- CError_ASSERT(99, TYPE_FUNC(object->type)->flags & FUNC_METHOD);
- CError_ASSERT(100, !TYPE_METHOD(object->type)->is_static);
- CError_ASSERT(101, TYPE_METHOD(object->type)->args);
-
- type = CDecl_NewRefPointerType(TYPE(TYPE_METHOD(object->type)->theclass));
- *qual = TYPE_METHOD(object->type)->args->qual & Q_CV;
- return type;
-}
-
-static Type *CExpr_GetParamType(Object *object, int index, UInt32 *qual) {
- FuncArg *arg;
-
- CError_ASSERT(120, IS_TYPE_FUNC(object->type));
- CError_ASSERT(121, arg = TYPE_FUNC(object->type)->args);
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type)))
- CError_ASSERT(125, arg = arg->next);
-
- while (index > 0) {
- CError_ASSERT(129, arg = arg->next);
- index--;
- }
-
- *qual = arg->qual & Q_CV;
- return arg->type;
-}
-
-static Boolean CExpr_HasNParams(Object *object, int count) {
- FuncArg *arg;
- int i;
-
- CError_ASSERT(146, IS_TYPE_FUNC(object->type));
- CError_ASSERT(147, arg = TYPE_FUNC(object->type)->args);
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type)))
- arg = arg->next;
-
- i = 0;
- while (arg) {
- arg = arg->next;
- i++;
- }
-
- return i == count;
-}
-
-typedef enum TypeCompareMode {
- TCM_0,
- TCM_1,
- TCM_2
-} TypeCompareMode;
-
-static Boolean CExpr_TypeCompare(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB, TypeCompareMode mode) {
- if (typeA->type != typeB->type)
- return 0;
-
- switch (mode) {
- case TCM_0:
- while (1) {
- switch (typeA->type) {
- case TYPEPOINTER:
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- if (typeA->type != typeB->type)
- return 0;
- continue;
-
- case TYPEMEMBERPOINTER:
- if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2))
- return 0;
- typeA = TYPE_MEMBER_POINTER(typeA)->ty1;
- typeB = TYPE_MEMBER_POINTER(typeB)->ty1;
- if (typeA->type != typeB->type)
- return 0;
- continue;
- }
- break;
- }
- break;
-
- case TCM_1:
- switch (typeA->type) {
- case TYPEPOINTER:
- if ((qualA & Q_CV) != (qualB & Q_CV))
- return 0;
-
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- break;
-
- case TYPEMEMBERPOINTER:
- if ((qualA & Q_CV) != (qualB & Q_CV))
- return 0;
-
- if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2))
- return 0;
- typeA = TYPE_MEMBER_POINTER(typeA)->ty1;
- typeB = TYPE_MEMBER_POINTER(typeB)->ty1;
- break;
- }
- break;
-
- case TCM_2:
- if ((qualA & Q_CV) != (qualB & Q_CV))
- return 0;
- break;
- }
-
- return is_typesame(typeA, typeB);
-}
-
-static int CExpr_IsReferenceCompatible(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB) {
- if (CParser_IsSameOrMoreCVQualified(CParser_GetCVTypeQualifiers(typeA, qualA), CParser_GetCVTypeQualifiers(typeB, qualB))) {
- if (CExpr_TypeCompare(typeA, qualA, typeB, qualB, TCM_1))
- return 1;
-
- if (IS_TYPE_CLASS(typeB) && IS_TYPE_CLASS(typeA)) {
- short depth;
- Boolean isambigbase;
- if (CClass_GetBasePath(TYPE_CLASS(typeB), TYPE_CLASS(typeA), &depth, &isambigbase))
- return 2;
- }
- }
-
- return 0;
-}
-
-static Boolean CExpr_IsBaseOf(TypeClass *baseclass, TypeClass *superclass) {
- ClassList *base;
-
- for (base = superclass->bases; base; base = base->next) {
- if (base->base == baseclass || CExpr_IsBaseOf(baseclass, base->base))
- return 1;
- }
-
- return 0;
-}
-
-static Boolean CExpr_IsBetterClassConversion(TypeClass *a, TypeClass *b, TypeClass *c, TypeClass *d) {
- if (a == c)
- return CExpr_IsBaseOf(d, b);
- if (b == d)
- return CExpr_IsBaseOf(a, c);
- return 0;
-}
-
-CW_INLINE Boolean Inline_501D40(Type *a, Type *b) {
- return (a == TYPE(&stbool)) && (IS_TYPE_POINTER_ONLY(b) || IS_TYPE_MEMBERPOINTER(b));
-}
-
-static Boolean CExpr_IsBetterStandardConv(StandardConv *a, StandardConv *b) {
- Boolean flag10;
- Boolean flag3;
-
- flag10 = 1;
- flag3 = 0;
-
- if (b->x11) {
- if (!a->x11)
- flag3 = 1;
- } else {
- if (a->x11)
- flag10 = 0;
- }
-
- if (b->x12) {
- if (!a->x12)
- flag3 = 1;
- } else {
- if (a->x12)
- flag10 = 0;
- }
-
- if (b->x13) {
- if (a->x13) {
- if (Inline_501D40(b->type2, b->type1)) {
- if (!Inline_501D40(a->type2, a->type1))
- return 1;
- } else {
- if (Inline_501D40(a->type2, a->type1))
- return 0;
- }
- } else {
- flag3 = 1;
- }
- } else {
- if (a->x13)
- flag10 = 0;
- }
-
- if (flag10 && flag3)
- return 1;
-
- if (!a->x13) {
- if (b->x13)
- return 1;
-
- if (a->x12) {
- if (!b->x12)
- return 0;
- } else {
- if (b->x12)
- return 1;
- }
- } else {
- if (!b->x13)
- return 0;
- }
-
- if (
- IS_TYPE_POINTER_ONLY(a->type1) &&
- IS_TYPE_CLASS(TPTR_TARGET(a->type1)) &&
- IS_TYPE_POINTER_ONLY(a->type2) &&
- IS_TYPE_POINTER_ONLY(b->type1) &&
- IS_TYPE_CLASS(TPTR_TARGET(b->type1)) &&
- IS_TYPE_POINTER_ONLY(b->type2)
- )
- {
- if (TPTR_TARGET(b->type2) == &stvoid) {
- if (TPTR_TARGET(a->type2) == &stvoid) {
- if (CExpr_IsBaseOf(TYPE_CLASS(TPTR_TARGET(a->type1)), TYPE_CLASS(TPTR_TARGET(b->type1))))
- return 1;
- } else {
- if (TPTR_TARGET(a->type1) == TPTR_TARGET(b->type1) && IS_TYPE_CLASS(TPTR_TARGET(a->type2)))
- return 1;
- }
- } else if (IS_TYPE_CLASS(TPTR_TARGET(a->type2)) && IS_TYPE_CLASS(TPTR_TARGET(b->type2))) {
- if (CExpr_IsBetterClassConversion(
- TYPE_CLASS(TPTR_TARGET(a->type1)),
- TYPE_CLASS(TPTR_TARGET(a->type2)),
- TYPE_CLASS(TPTR_TARGET(b->type1)),
- TYPE_CLASS(TPTR_TARGET(b->type2))
- ))
- return 1;
- }
- }
-
- if (
- IS_TYPE_CLASS(a->type1) &&
- IS_TYPE_CLASS(a->type2) &&
- IS_TYPE_CLASS(b->type1) &&
- IS_TYPE_CLASS(b->type2) &&
- CExpr_IsBetterClassConversion(
- TYPE_CLASS(a->type1),
- TYPE_CLASS(a->type2),
- TYPE_CLASS(b->type1),
- TYPE_CLASS(b->type2)
- )
- )
- return 1;
-
- if (
- IS_TYPE_MEMBERPOINTER(a->type1) &&
- IS_TYPE_MEMBERPOINTER(a->type2) &&
- IS_TYPE_MEMBERPOINTER(b->type1) &&
- IS_TYPE_MEMBERPOINTER(b->type2) &&
- IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2) &&
- IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2) &&
- IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2) &&
- IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2) &&
- CExpr_IsBetterClassConversion(
- TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2),
- TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2),
- TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2),
- TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2)
- )
- )
- return 1;
-
- if (
- a->x14 &&
- b->x14 &&
- CExpr_TypeCompare(a->type2, a->qual2, b->type2, b->qual2, TCM_1) &&
- CParser_IsMoreCVQualified(
- CParser_GetTypeQualifiers(b->type2, b->qual2),
- CParser_GetTypeQualifiers(a->type2, a->qual2)
- )
- )
- return 1;
-
- return 0;
-}
-
-static Boolean CExpr_IsBetterImplicitConv(ImplicitConv *a, ImplicitConv *b) {
- if (a->type > b->type)
- return 1;
- if (a->type != b->type)
- return 0;
-
- if (a->type == ICT_3)
- return CExpr_IsBetterStandardConv(&a->u.ic3.standardConv, &b->u.ic3.standardConv);
-
- if (a->type == ICT_2 && a->u.ic2.x2 == b->u.ic2.x2 && CExpr_IsBetterStandardConv(&a->u.ic2.standardConv, &b->u.ic2.standardConv))
- return 1;
-
- return 0;
-}
-
-typedef enum SSCRMode {
- SSCR_0,
- SSCR_1,
- SSCR_2
-} SSCRMode;
-
-static Boolean CExpr_SetupStandardConversionResult(ENode *expr, Type *type2, UInt32 qual2, SSCRMode mode, Boolean x14, Boolean refFlag, StandardConv *result) {
- UInt32 cv1;
- UInt32 cv2;
-
- if (x14) {
- if (!CParser_IsConst(type2, qual2)) {
- if (!refFlag && !CExpr_IsLValue(expr))
- return 0;
- if (mode != SSCR_0 && !IS_TYPE_CLASS(type2))
- return 0;
- }
-
- cv2 = CParser_GetTypeQualifiers(type2, qual2) & Q_CV;
- cv1 = CParser_GetTypeQualifiers(expr->rtype, ENODE_QUALS(expr)) & Q_CV;
- if (cv2 != cv1 && !CParser_IsMoreCVQualified(cv2, cv1))
- return 0;
- }
-
- memclrw(result, sizeof(StandardConv));
- result->type2 = type2;
- result->qual2 = qual2;
- result->type1 = expr->rtype;
- result->qual1 = ENODE_QUALS(expr);
- result->x14 = x14;
-
- switch (mode) {
- case SSCR_0:
- break;
- case SSCR_1:
- result->x12 = 1;
- break;
- case SSCR_2:
- result->x13 = 1;
- break;
- default:
- CError_FATAL(581);
- }
-
- return 1;
-}
-
-typedef enum MysteryEnum {
- ME_0,
- ME_1,
- ME_255 = 255
-} MysteryEnum;
-
-CW_INLINE MysteryEnum Inline_501FF0(UInt32 qual1, UInt32 qual2) {
- if ((qual1 & Q_CV) == (qual2 & Q_CV))
- return ME_0;
-
- if (((qual2 & Q_CONST) && !(qual1 & Q_CONST)) || ((qual2 & Q_VOLATILE) && !(qual1 & Q_VOLATILE)))
- return ME_255;
-
- return ME_1;
-}
-
-static Boolean CExpr_SetQualConversionResult(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, StandardConv *result) {
- Boolean flag = 1;
- UInt32 cv1;
- UInt32 cv2;
-
- while (1) {
- cv1 = CParser_GetCVTypeQualifiers(type1, qual1);
- cv2 = CParser_GetCVTypeQualifiers(type2, qual2);
-
- switch (Inline_501FF0(cv1, cv2)) {
- case ME_0:
- break;
-
- case ME_1:
- result->x11 = 1;
- if (!flag)
- return 0;
- break;
-
- default:
- return 0;
- }
-
- if (!(cv1 & Q_CONST))
- flag = 0;
-
- if (IS_TYPE_POINTER_ONLY(type1)) {
- CError_ASSERT(635, IS_TYPE_POINTER_ONLY(type2));
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- } else {
- if (!IS_TYPE_MEMBERPOINTER(type1))
- return 1;
-
- CError_ASSERT(642, IS_TYPE_MEMBERPOINTER(type2));
- type1 = TYPE_MEMBER_POINTER(type1)->ty1;
- type2 = TYPE_MEMBER_POINTER(type2)->ty1;
- }
- }
-}
-
-static Boolean CExpr_OverloadFuncMatch(NameSpaceObjectList *list, TemplArg *templargs, Type *type, ENode **outExpr) {
- Object *object;
- TemplFuncInstance *inst;
- ENode *expr;
- FuncArg *arg;
- int i;
- ObjectList *objlist;
- Object *object26;
- ObjectList *objlist25;
- ObjectList *objlist24;
- Boolean flag23;
-
- if (!IS_TYPE_POINTER_ONLY(type) || !IS_TYPE_FUNC(type = TPTR_TARGET(type)))
- return 0;
-
- object26 = NULL;
- objlist25 = NULL;
- objlist24 = NULL;
- flag23 = 0;
-
- while (list) {
- object = OBJECT(list->object);
- if (object->otype == OT_OBJECT) {
- if (IS_TEMPL_FUNC(object->type)) {
- if (!flag23 && CTempl_CanDeduceFunc(object, TYPE_FUNC(type), templargs)) {
- CError_ASSERT(685, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0));
- if (is_typesame(inst->object->type, type)) {
- objlist = lalloc(sizeof(ObjectList));
- objlist->next = objlist24;
- objlist->object = object;
- objlist24 = objlist;
-
- if (object26 && object26 != inst->object) {
- objlist = lalloc(sizeof(ObjectList));
- objlist->next = objlist25;
- objlist->object = inst->object;
- objlist25 = objlist;
- } else {
- object26 = inst->object;
- }
- }
- }
- } else if (is_typesame(object->type, type)) {
- if (object26 && flag23) {
- Object *checkA, *checkB;
- checkA = object;
- if (checkA->datatype == DALIAS)
- checkA = checkA->u.alias.object;
- checkB = object26;
- if (checkB->datatype == DALIAS)
- checkB = checkB->u.alias.object;
- if (checkA != checkB) {
- objlist = lalloc(sizeof(ObjectList));
- objlist->next = objlist25;
- objlist->object = object;
- objlist25 = objlist;
- }
- } else {
- objlist25 = NULL;
- object26 = object;
- }
- flag23 = 1;
- }
- }
- list = list->next;
- }
-
- if (object26) {
- if (outExpr) {
- if (objlist25) {
- i = 0;
- for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next)
- i++;
-
- if (!flag23 && (object = CTempl_PartialOrdering(objlist24->object, objlist24->next, i))) {
- CError_ASSERT(741, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0));
- object26 = inst->object;
- } else {
- CError_OverloadedFunctionError(object26, objlist25);
- }
- }
-
- expr = CExpr_MakeObjRefNode(object26, 1);
- *outExpr = expr;
- expr->rtype = CDecl_NewPointerType(object26->type);
- expr->flags = object->qual & ENODE_FLAG_QUALS;
- object26->flags |= OBJECT_USED;
- if (object26->datatype == DINLINEFUNC)
- CError_Error(CErrorStr175);
- }
-
- return 1;
- }
-
- return 0;
-}
-
-static Boolean CExpr_StandardConversionMatch(ENode *expr, Type *type2, UInt32 qual2, Boolean x14, StandardConv *result) {
- Type *type1;
- UInt32 qual1;
- Boolean refFlag;
- Type *inner2;
- Type *inner1;
- SSCRMode mode;
- NameSpaceObjectList list;
-
- if (IS_TYPE_REFERENCE(type2)) {
- type2 = TPTR_TARGET(type2);
- if (IS_TYPE_POINTER_ONLY(type2))
- expr = pointer_generation(expr);
- refFlag = 1;
- } else {
- if (
- (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type2)) ||
- (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type2))
- )
- expr = pointer_generation(expr);
- refFlag = 0;
- }
-
- type1 = expr->rtype;
- qual1 = ENODE_QUALS(expr);
-
- if (IS_TYPE_POINTER_ONLY(type2)) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
- if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1)))
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result);
- }
-
- if (
- IS_TYPE_INT(expr->rtype) &&
- ENODE_IS_INDIRECT_TO(expr, EOBJREF) &&
- (expr->data.monadic->data.objref->qual & Q_INLINE_DATA) &&
- CInt64_IsZero(&expr->data.monadic->data.objref->u.data.u.intconst)
- )
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result);
-
- if (ENODE_IS(expr, EOBJLIST))
- return CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type2, NULL) &&
- CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result);
-
- if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) {
- list.next = NULL;
- list.object = OBJ_BASE(expr->data.objref);
- return CExpr_OverloadFuncMatch(&list, NULL, type2, NULL) &&
- CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result);
- }
-
- if (IS_TYPE_POINTER_ONLY(type1)) {
- if (
- ENODE_IS(expr, ESTRINGCONST) &&
- TPTR_TARGET(type2) == TPTR_TARGET(type1) &&
- !(qual2 & Q_CONST) &&
- (
- TPTR_TARGET(type2) == TYPE(&stchar) ||
- TPTR_TARGET(type2) == TYPE(&stunsignedchar) ||
- TPTR_TARGET(type2) == CParser_GetWCharType()
- )
- )
- {
- if (
- CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result) &&
- CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1 & ~Q_CONST, result)
- )
- {
- result->x11 = 1;
- return 1;
- } else {
- return 0;
- }
- }
-
- if (copts.objective_c && CObjC_IsCompatibleType(expr->rtype, type2))
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result);
-
- if (IS_TYPE_VOID(TPTR_TARGET(type2)) || (!copts.cplusplus && IS_TYPE_VOID(TPTR_TARGET(type1)))) {
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, IS_TYPE_VOID(TPTR_TARGET(type1)) ? SSCR_0 : SSCR_2, refFlag, x14, result)) {
- switch (Inline_501FF0(qual2, CParser_GetCVTypeQualifiers(TPTR_TARGET(type1), qual1))) {
- case ME_1:
- result->x11 = 1;
- case ME_0:
- return 1;
- default:
- return 0;
- }
- } else {
- return 0;
- }
- }
-
- inner2 = TPTR_TARGET(type2);
- inner1 = TPTR_TARGET(type1);
- while (1) {
- if (inner2->type != inner1->type)
- break;
-
- switch (inner2->type) {
- case TYPEPOINTER:
- inner2 = TPTR_TARGET(inner2);
- inner1 = TPTR_TARGET(inner1);
- continue;
- case TYPEMEMBERPOINTER:
- if (!is_typesame(TYPE_MEMBER_POINTER(inner2)->ty2, TYPE_MEMBER_POINTER(inner1)->ty2))
- break;
-
- inner2 = TYPE_MEMBER_POINTER(inner2)->ty1;
- inner1 = TYPE_MEMBER_POINTER(inner1)->ty1;
- if (!IS_TYPE_POINTER_ONLY(inner2) && !IS_TYPE_MEMBERPOINTER(inner2)) {
- if (!is_memberpointerequal(inner2, inner1))
- break;
-
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result))
- return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result);
- else
- return 0;
- }
- continue;
- default:
- if (!is_typesame(inner2, inner1))
- break;
-
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result))
- return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result);
- else
- return 0;
- }
-
- break;
- }
-
- if (IS_TYPE_CLASS(TPTR_TARGET(type2)) && IS_TYPE_CLASS(TPTR_TARGET(type1))) {
- short depth;
- Boolean isambigbase;
- if (CClass_GetBasePath(TYPE_CLASS(TPTR_TARGET(type1)), TYPE_CLASS(TPTR_TARGET(type2)), &depth, &isambigbase)) {
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result))
- return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result);
- else
- return 0;
- }
- }
- }
-
- if (copts.mpwc_relax && !copts.cplusplus && IS_TYPE_POINTER_ONLY(type1)) {
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result))
- return 1;
- }
-
- return 0;
- }
-
- if (is_typesame(type2, type1))
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result);
-
- if (type2 == TYPE(&stbool)) {
- switch (type1->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result);
- default:
- return 0;
- }
- }
-
- if (IS_TYPE_MEMBERPOINTER(type2)) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
- if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1)))
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result);
- }
-
- if (ENODE_IS(expr, EMEMBER)) {
- expr = getpointertomemberfunc(expr, type2, 0);
- type1 = expr->rtype;
- }
-
- if (IS_TYPE_MEMBERPOINTER(type1)) {
- short depth;
- Boolean isambigbase;
-
- CError_ASSERT(996, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2) && IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2));
- if (!is_memberpointerequal(TYPE_MEMBER_POINTER(type2)->ty1, TYPE_MEMBER_POINTER(type1)->ty1))
- return 0;
-
- if (
- TYPE_MEMBER_POINTER(type2)->ty2 == TYPE_MEMBER_POINTER(type1)->ty2 ||
- CClass_GetBasePath(TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2), &depth, &isambigbase)
- )
- {
- if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result))
- return CExpr_SetQualConversionResult(TYPE_MEMBER_POINTER(type2)->ty1, qual2, TYPE_MEMBER_POINTER(type1)->ty1, qual1, result);
- else
- return 0;
- }
- }
-
- return 0;
- }
-
- mode = SSCR_2;
- switch (type1->type) {
- case TYPEINT:
- switch (type2->type) {
- case TYPEINT:
- if (TYPE_INTEGRAL(type1)->integral < IT_INT) {
- if (type2 == TYPE(&stsignedint)) {
- if (type1->size < type2->size || !is_unsigned(type1))
- mode = SSCR_1;
- } else if (type2 == TYPE(&stunsignedint)) {
- if (type2->size == type1->size && is_unsigned(type1))
- mode = SSCR_1;
- }
- }
- break;
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- if (copts.cplusplus)
- return 0;
- break;
- default:
- return 0;
- }
- break;
-
- case TYPEFLOAT:
- switch (type2->type) {
- case TYPEINT:
- break;
- case TYPEFLOAT:
- if (type2 == TYPE(&stdouble)) {
- if (type1 == TYPE(&stfloat) || type1 == TYPE(&stshortdouble))
- mode = SSCR_1;
- }
- break;
- case TYPEENUM:
- if (copts.cplusplus)
- return 0;
- break;
- default:
- return 0;
- }
- break;
-
- case TYPEENUM:
- switch (type2->type) {
- case TYPEINT:
- if (TYPE_INTEGRAL(TYPE_ENUM(expr->rtype)->enumtype)->integral < IT_INT) {
- if (type1->size == type2->size && is_unsigned(TYPE_ENUM(type1)->enumtype)) {
- if (type2 == TYPE(&stunsignedint))
- mode = SSCR_1;
- } else {
- if (type2 == TYPE(&stsignedint))
- mode = SSCR_1;
- }
- } else {
- if (TYPE_ENUM(type1)->enumtype == type2)
- mode = SSCR_1;
- }
- break;
- case TYPEFLOAT:
- break;
- case TYPEENUM:
- if (copts.cplusplus)
- return 0;
- break;
- default:
- return 0;
- }
- break;
-
- case TYPECLASS: {
- short depth;
- Boolean isambigbase;
-
- if (!IS_TYPE_CLASS(type1) || !CClass_GetBasePath(TYPE_CLASS(type1), TYPE_CLASS(type2), &depth, &isambigbase))
- return 0;
- break;
- }
-
- default:
- return 0;
- }
-
- return CExpr_SetupStandardConversionResult(expr, type2, qual2, mode, refFlag, x14, result);
-}
-
-static ENode *CExpr_UserConversion(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result, Boolean flag1, Boolean isExplicit, Boolean flag3) {
- Object *object28;
- Object *object27;
- Object *object26;
- ObjectList *objlist25;
- ObjectList *objlist24;
- ObjectList *objlist;
- TypeFunc *tfunc23;
- Type *tmptype23;
- NameSpaceObjectList *list22;
- Boolean flag22;
- Boolean flag21;
- FuncArg *arg21;
- Boolean flag20;
- ENode *newExpr;
- ENode *funcref;
- ENode *tmpExpr;
- ENodeList *arglist;
- UInt32 q1;
- UInt32 q2;
- StandardConv sc3;
- StandardConv sc2;
- StandardConv sc1;
- ConversionIterator convIter;
- ENodeList myarglist;
- ObjectList myobjlist;
- BClassList path;
-
- object28 = NULL;
- object27 = NULL;
- objlist25 = NULL;
- objlist24 = NULL;
-
- if (type2->size == 0)
- CDecl_CompleteType(type2);
- if (expr->rtype->size == 0)
- CDecl_CompleteType(expr->rtype);
-
- if (IS_TYPE_CLASS(expr->rtype)) {
- CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype));
- flag22 = 1;
- while ((object26 = CExpr_ConversionIteratorNext(&convIter))) {
- tfunc23 = TYPE_FUNC(object26->type);
- if (tfunc23->flags & FUNC_IS_TEMPL) {
- object26 = CTempl_DeduceFromConversion(object26, type2, qual2);
- if (!object26)
- continue;
- tfunc23 = TYPE_FUNC(object26->type);
- }
-
- if (flag3) {
- if (
- !IS_TYPE_REFERENCE(tfunc23->functype) ||
- !CExpr_IsReferenceCompatible(type2, qual2, TPTR_TARGET(tfunc23->functype), tfunc23->qual)
- )
- continue;
- }
-
- CError_ASSERT(1230, tfunc23->args && IS_TYPE_POINTER_ONLY(tfunc23->args->type));
-
- q1 = ENODE_QUALS(expr);
- q2 = tfunc23->args->qual;
- if ((q1 & Q_CV) != (q2 & Q_CV)) {
- if (!flag22)
- continue;
- if ((q1 & Q_CONST) && !(q2 & Q_CONST))
- continue;
- if ((q1 & Q_VOLATILE) && !(q2 & Q_VOLATILE))
- continue;
- flag21 = 1;
- } else {
- flag21 = 0;
- }
-
- newExpr = CExpr_NewENode(ETEMP);
- newExpr->rtype = tfunc23->functype;
- newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS;
- flag20 = 0;
-
- if (IS_TYPE_REFERENCE(newExpr->rtype)) {
- newExpr->rtype = TPTR_TARGET(newExpr->rtype);
- if (!CParser_IsConst(newExpr->rtype, tfunc23->qual)) {
- newExpr = makemonadicnode(newExpr, EINDIRECT);
- newExpr->data.monadic->rtype = TYPE(&void_ptr);
- newExpr = makemonadicnode(newExpr, EINDIRECT);
- newExpr->data.monadic->rtype = TYPE(&void_ptr);
- flag20 = 1;
- }
- }
-
- if (CExpr_StandardConversionMatch(newExpr, type2, qual2, 0, &sc1)) {
- if (flag22 && !flag21) {
- object28 = NULL;
- objlist25 = NULL;
- flag22 = 0;
- }
-
- if (object28 && object28 != object26) {
- if (CExpr_IsBetterStandardConv(&sc3, &sc1))
- continue;
-
- if (!CExpr_IsBetterStandardConv(&sc1, &sc3)) {
- objlist = lalloc(sizeof(ObjectList));
- objlist->next = objlist25;
- objlist->object = object28;
- objlist25 = objlist;
- } else {
- objlist25 = NULL;
- }
- }
-
- object28 = object26;
- sc3 = sc1;
- sc3.x15 = flag20;
- }
- }
- }
-
- if (!flag3 && IS_TYPE_CLASS(type2) && (list22 = CClass_Constructor(TYPE_CLASS(type2)))) {
- for (; list22; list22 = list22->next) {
- object26 = OBJECT(list22->object);
- if (
- object26->otype == OT_OBJECT &&
- IS_TYPE_FUNC(tfunc23 = TYPE_FUNC(object26->type)) &&
- (isExplicit || !(object26->qual & Q_EXPLICIT))
- )
- {
- if (tfunc23->flags & FUNC_IS_TEMPL) {
- myarglist.next = NULL;
- myarglist.node = expr;
- object26 = CTempl_DeduceFromFunctionCall(object26, NULL, &myarglist);
- if (!object26)
- continue;
- tfunc23 = TYPE_FUNC(object26->type);
- }
-
- if (!(arg21 = tfunc23->args))
- continue;
- if (!(arg21 = arg21->next))
- continue;
- if ((TYPE_CLASS(type2)->flags & CLASS_HAS_VBASES) && !(arg21 = arg21->next))
- continue;
- if (arg21 == &elipsis)
- continue;
- if (arg21->next && !arg21->next->dexpr && arg21->next != &elipsis)
- continue;
-
- tmptype23 = arg21->type;
- if (IS_TYPE_REFERENCE(tmptype23)) {
- tmptype23 = TPTR_TARGET(tmptype23);
- if (!CParser_IsConst(tmptype23, arg21->qual) && !CExpr_IsLValue(expr))
- continue;
- }
-
- if (CExpr_StandardConversionMatch(expr, tmptype23, arg21->qual, 0, &sc1)) {
- if (object27) {
- if (object26->u.func.inst && !object27->u.func.inst)
- continue;
- if (CExpr_IsBetterStandardConv(&sc2, &sc1))
- continue;
-
- if (!CExpr_IsBetterStandardConv(&sc1, &sc2)) {
- if (!object26->u.func.inst && object27->u.func.inst) {
- objlist24 = NULL;
- } else {
- objlist = lalloc(sizeof(ObjectList));
- objlist->next = objlist25;
- objlist->object = object28;
- objlist25 = objlist;
- }
- } else {
- objlist25 = NULL;
- }
- }
-
- object27 = object26;
- sc2 = sc1;
- }
- }
- }
- }
-
- if (object28 && object27) {
- if (!CExpr_IsBetterStandardConv(&sc2, &sc3)) {
- if (!CExpr_IsBetterStandardConv(&sc3, &sc2)) {
- if (result) {
- result->type = ICT_2;
- result->u.ic2.x2 = object28;
- result->u.ic2.standardConv = sc3;
- }
- if (flag1) {
- myobjlist.next = NULL;
- myobjlist.object = object27;
- CError_OverloadedFunctionError(object28, &myobjlist);
- }
- } else {
- object27 = NULL;
- }
- } else {
- object28 = NULL;
- }
- }
-
- if (object28) {
- if (result) {
- result->type = ICT_2;
- result->u.ic2.x2 = object28;
- result->u.ic2.standardConv = sc3;
- }
- if (!flag1)
- return expr;
- if (objlist25)
- CError_OverloadedFunctionError(object28, objlist25);
- tfunc23 = TYPE_FUNC(object28->type);
- CError_ASSERT(1416, IS_TYPEFUNC_METHOD(tfunc23));
-
- funcref = create_objectrefnode(object28);
- object28->flags |= OBJECT_USED;
-
- arglist = lalloc(sizeof(ENodeList));
- arglist->next = NULL;
-
- expr = getnodeaddress(expr, 0);
- arglist->node = CExpr_AssignmentPromotion(
- expr,
- CDecl_NewPointerType(TYPE(TYPE_METHOD(tfunc23)->theclass)),
- expr->flags,
- 0);
-
- newExpr = lalloc(sizeof(ENode));
- newExpr->type = EFUNCCALL;
- newExpr->cost = 4;
- newExpr->rtype = tfunc23->functype;
- newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS;
- newExpr->data.funccall.funcref = funcref;
- newExpr->data.funccall.args = arglist;
- newExpr->data.funccall.functype = TYPE_FUNC(object28->type);
- newExpr = CExpr_AdjustFunctionCall(newExpr);
- newExpr = checkreference(newExpr);
-
- if (newExpr->rtype != type2) {
- if (flag3) {
- tmpExpr = CExpr_DerivedToBase(newExpr, type2, qual2, 1, 0, 1);
- if (tmpExpr)
- return tmpExpr;
- }
- newExpr = CExpr_Convert(newExpr, type2, qual2, 0, 1);
- }
- return newExpr;
- }
-
- if (object27) {
- if (result) {
- result->type = ICT_2;
- result->u.ic2.x2 = object27;
- result->u.ic2.standardConv = sc2;
- }
- if (!flag1)
- return expr;
- if (objlist24)
- CError_OverloadedFunctionError(object27, objlist24);
-
- arglist = lalloc(sizeof(ENodeList));
- arglist->next = NULL;
- arglist->node = expr;
-
- if (TYPE_CLASS(type2)->flags & CLASS_HAS_VBASES) {
- arglist->next = lalloc(sizeof(ENodeList));
- arglist->next->node = expr;
- arglist->next->next = NULL;
- arglist->node = intconstnode(TYPE(&stsignedshort), 1);
- }
-
- path.next = NULL;
- path.type = type2;
-
- tmpExpr = makemonadicnode(create_temp_node(type2), EINDIRECT);
- tmpExpr->rtype = type2;
-
- newExpr = CExpr_GenericFuncCall(
- &path, tmpExpr, 0, object27, NULL, NULL, arglist, 0, 0, 1
- );
-
- if (ENODE_IS2(newExpr, EFUNCCALL, EFUNCCALLP)) {
- newExpr->rtype = CDecl_NewPointerType(type2);
- newExpr = makemonadicnode(newExpr, EINDIRECT);
- newExpr->rtype = type2;
- }
-
- return newExpr;
- }
-
- return NULL;
-}
-
-static Boolean CExpr_UserConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) {
- Boolean flag;
-
- if (IS_TYPE_REFERENCE(type2)) {
- type2 = TPTR_TARGET(type2);
- flag = !CParser_IsConst(type2, qual2);
- } else {
- expr = pointer_generation(expr);
- flag = 0;
- }
-
- if (CExpr_UserConversion(expr, type2, qual2, result, 0, 0, flag))
- return 1;
-
- return 0;
-}
-
-static Boolean CExpr_ImplicitConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) {
- if (CExpr_StandardConversionMatch(expr, type2, qual2, 0, &result->u.ic3.standardConv)) {
- result->type = ICT_3;
- return 1;
- }
-
- if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type2) || (IS_TYPE_REFERENCE(type2) && IS_TYPE_CLASS(TPTR_TARGET(type2)))) {
- if (CExpr_UserConversionMatch(expr, type2, qual2, result)) {
- result->type = ICT_2;
- return 1;
- }
- }
-
- return 0;
-}
-
-Boolean CExpr_CanImplicitlyConvert(ENode *expr, Type *type2, UInt32 qual2) {
- ImplicitConv result;
- return CExpr_ImplicitConversionMatch(expr, type2, qual2, &result);
-}
-
-static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean nullcheckflag, Boolean pathcheckflag) {
- BClassList *path;
- short depth;
- Boolean isambigbase;
-
- if (
- IS_TYPE_CLASS(type2) &&
- IS_TYPE_CLASS(expr->rtype) &&
- (path = CClass_GetBasePath(TYPE_CLASS(expr->rtype), TYPE_CLASS(type2), &depth, &isambigbase))
- )
- {
- if (isambigbase)
- CError_Error(CErrorStr188);
- if (flag1)
- CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC);
-
- if (pathcheckflag) {
- expr = getnodeaddress(expr, 0);
- expr = makemonadicnode(CExpr_ClassPointerCast(path, expr, nullcheckflag), EINDIRECT);
- expr->rtype = type2;
- expr->flags = qual2 & ENODE_FLAG_QUALS;
- }
-
- return expr;
- }
- else {
- return NULL;
- }
-}
-
-static ENode *CExpr_ClassReferenceConversion(ENode *expr, Type *type2, UInt32 qual2, Boolean pathcheckflag) {
- int refcompat;
-
- if (CExpr_IsLValue(expr) && IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) {
- refcompat = CExpr_IsReferenceCompatible(type2, 0, expr->rtype, 0);
- if (refcompat > 0) {
- if (refcompat == 2) {
- CError_ASSERT(1668, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype));
- expr = CExpr_DerivedToBase(expr, type2, qual2, pathcheckflag, 0, 1);
- }
- expr->flags = qual2 & ENODE_FLAG_QUALS;
- return expr;
- }
-
- refcompat = CExpr_IsReferenceCompatible(expr->rtype, 0, type2, 0);
- if (refcompat > 0) {
- expr = CClass_ClassPointerCast(
- getnodeaddress(expr, 0),
- TYPE_CLASS(expr->rtype), TYPE_CLASS(type2),
- 1, 1, pathcheckflag
- );
- CError_ASSERT(1680, IS_TYPE_POINTER_ONLY(expr->rtype));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = type2;
- expr->flags = qual2 & ENODE_FLAG_QUALS;
- return expr;
- }
- }
-
- if (IS_TYPE_CLASS(expr->rtype)) {
- if ((expr = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1)))
- return expr;
- }
-
- return NULL;
-}
-
-static ENode *CExpr_BindToReference(ENode *expr, Type *type2, UInt32 qual2) {
- UInt32 cv;
- int refcompat;
- ENode *tmp;
-
- cv = CParser_GetCVTypeQualifiers(type2, qual2);
-
- if (CExpr_IsLValue(expr)) {
- refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr));
- if (refcompat > 0) {
- if (refcompat == 2) {
- CError_ASSERT(1718, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype));
- expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1);
- }
- return getnodeaddress(expr, 0);
- }
- } else if (IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) {
- refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr));
- if (refcompat > 0) {
- if (refcompat == 2)
- expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1);
- return getnodeaddress(expr, 0);
- }
- }
-
- if (IS_TYPE_CLASS(expr->rtype)) {
- if ((tmp = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1)))
- return getnodeaddress(tmp, 0);
- }
-
- if (!(cv & Q_CONST))
- CError_Error(CErrorStr228);
- if (cv & Q_VOLATILE)
- CError_Error(CErrorStr259);
-
- if (expr->rtype != type2)
- expr = CExpr_Convert(expr, type2, qual2, 0, 1);
-
- if (!CExpr_IsLValue(expr)) {
- expr = CExpr_LValue(expr, 0, 0);
- if (!ENODE_IS(expr, EINDIRECT))
- expr = get_address_of_temp_copy(expr, 1);
- else
- expr = getnodeaddress(expr, 0);
- } else {
- expr = getnodeaddress(expr, 0);
- }
-
- return expr;
-}
-
-ENode *CExpr_Convert(ENode *expr, Type *type, UInt32 qual, Boolean isExplicit, Boolean flag2) {
- UInt32 cv;
- ENode *refExpr;
- ENode *newExpr;
- Type *typeCopy;
- NameSpaceObjectList myList;
-
- cv = qual & Q_CV;
-
- if (copts.cpp_extensions && is_typesame(expr->rtype, type) && !ENODE_IS(expr, EOBJLIST)) {
- expr = CExpr_RewriteConst(expr);
- expr->rtype = type;
- expr->flags &= ~ENODE_FLAG_QUALS;
- expr->flags |= cv;
- return expr;
- }
-
- if (type == TYPE(&stvoid)) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
- }
-
- if (IS_TYPE_REFERENCE(type)) {
- if (isExplicit) {
- refExpr = CExpr_ClassReferenceConversion(expr, TPTR_TARGET(type), qual, flag2);
- if (refExpr)
- return refExpr;
-
- expr = getnodeaddress(expr, 0);
- typeCopy = galloc(sizeof(TypePointer));
- *TYPE_POINTER(typeCopy) = *TYPE_POINTER(type);
- TPTR_QUAL(typeCopy) &= ~Q_REFERENCE;
- expr = CExpr_Convert(expr, typeCopy, qual, 0, flag2);
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(type);
- expr->flags = cv;
- return expr;
- } else {
- return CExpr_BindToReference(expr, TPTR_TARGET(type), qual);
- }
- }
-
- if (
- (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type)) ||
- (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type))
- )
- {
- expr = pointer_generation(expr);
- } else {
- expr = CExpr_RewriteConst(expr);
- }
-
- if (ENODE_IS(expr, EOBJLIST)) {
- if (CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type, &refExpr))
- return refExpr;
- } else if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) {
- myList.next = NULL;
- myList.object = OBJ_BASE(expr->data.objref);
- if (CExpr_OverloadFuncMatch(&myList, NULL, type, &refExpr))
- return refExpr;
- } else if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type)) {
- if (expr->rtype->size == 0)
- CDecl_CompleteType(expr->rtype);
-
- if (IS_TYPE_CLASS(type)) {
- CanAllocObject(type);
- if (!CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_IsTrivialCopyClass(TYPE_CLASS(type))) {
- if (expr->rtype == type)
- return expr;
-
- refExpr = CExpr_DerivedToBase(expr, type, qual, flag2, 0, 1);
- if (refExpr)
- return refExpr;
- }
- }
-
- refExpr = CExpr_UserConversion(expr, type, qual, NULL, 1, isExplicit, 0);
- if (refExpr) {
- refExpr->flags = cv;
- return refExpr;
- }
- } else if (!isExplicit && is_typesame(expr->rtype, type)) {
- if (ENODE_IS(expr, EINDIRECT) && ENODE_QUALS(expr) != cv)
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
- } else {
- if (
- copts.warn_implicitconv &&
- !isExplicit &&
- IS_TYPE_INT_OR_FLOAT(type) &&
- IS_TYPE_INT_OR_FLOAT(expr->rtype)
- )
- CExpr_CheckArithmConversion(expr, type);
-
- switch (type->type) {
- case TYPEINT:
- if (type == TYPE(&stbool)) {
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- return CExpr_ConvertToBool(expr, isExplicit);
- }
- } else {
- switch (expr->rtype->type) {
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- case TYPEINT:
- case TYPEFLOAT:
- do_int_float_conversion:
- if (
- ENODE_IS(expr, ETYPCON) &&
- expr->rtype->type == type->type &&
- expr->rtype->size == type->size &&
- is_unsigned(expr->rtype) == is_unsigned(type) &&
- ENODE_QUALS(expr) == qual
- )
- {
- expr->rtype = type;
- expr->flags |= ENODE_FLAG_80;
- return expr;
- } else {
- refExpr = promote(expr, type);
- refExpr->flags = cv;
- return refExpr;
- }
- break;
- case TYPEPOINTER:
- if (expr->rtype->size > type->size && copts.warn_ptr_int_conv)
- CError_Warning(CErrorStr382);
- if (ENODE_IS(expr, ETYPCON)) {
- ENode *inner = expr->data.monadic;
- if (ENODE_IS(inner, EINTCONST)) {
- inner->rtype = type;
- inner->flags = cv;
- inner->data.intval = CExpr_IntConstConvert(type, TYPE(&stunsignedlong), inner->data.intval);
- return inner;
- }
- }
- if (type->size != 4) {
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
- }
- }
- break;
-
- case TYPEFLOAT:
- switch (expr->rtype->type) {
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- case TYPEINT:
- case TYPEFLOAT:
- goto do_int_float_conversion;
- }
- break;
-
- case TYPEENUM:
- expr = CExpr_Convert(expr, TYPE_ENUM(type)->enumtype, qual, isExplicit, flag2);
- if (!ENODE_IS(expr, EINTCONST))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
-
- case TYPEPOINTER:
- switch (expr->rtype->type) {
- case TYPEENUM:
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
- case TYPEINT:
- if (expr->rtype->size != 4) {
- if (!ENODE_IS(expr, EINTCONST))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = TYPE(&stunsignedlong);
- }
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
-
- case TYPEPOINTER:
- if (IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(type)))
- expr = CExpr_SafeClassPointerCast(expr, TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), 1, flag2);
- if (!ENODE_IS(expr, ETYPCON))
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = cv;
- return expr;
- }
- break;
-
- case TYPEMEMBERPOINTER:
- if (!IS_TYPE_MEMBERPOINTER(expr->rtype))
- expr = CExpr_MemberPointerConversion(expr, TYPE_MEMBER_POINTER(type), 1);
-
- if (IS_TYPE_MEMBERPOINTER(expr->rtype)) {
- expr = PointerToMemberCast(expr, TYPE_MEMBER_POINTER(expr->rtype), TYPE_MEMBER_POINTER(type), flag2);
- expr->flags = cv;
- return expr;
- }
- break;
- }
- }
-
- if (isExplicit) {
- if ((newExpr = CodeGen_HandleTypeCast(expr, type, qual)))
- return newExpr;
- }
-
- CError_Error(
- isExplicit ? CErrorStr247 : CErrorStr209,
- expr->rtype, ENODE_QUALS(expr),
- type, qual);
- return nullnode();
-}
-
-ENode *CExpr_AssignmentPromotion(ENode *expr, Type *type2, UInt32 qual2, Boolean flag) {
- ImplicitConv result;
-
- if (copts.old_argmatch)
- return oldassignmentpromotion(expr, type2, qual2, flag);
-
- if (ENODE_IS(expr, EMEMBER))
- expr = getpointertomemberfunc(expr, type2, 1);
-
- if (!CExpr_ImplicitConversionMatch(expr, type2, qual2, &result)) {
- CError_Error(CErrorStr209, expr->rtype, ENODE_QUALS(expr), type2, qual2);
- return nullnode();
- }
-
- return CExpr_Convert(expr, type2, qual2, 0, flag);
-}
-
-static Boolean CExpr_IsBetterMatch(Match *a, Match *b, int count) {
- ImplicitConv *convA;
- ImplicitConv *convB;
- int i;
- Boolean flag;
-
- convA = a->conv;
- convB = b->conv;
- flag = 0;
-
- if (convA->type != ICT_0 && convB->type != ICT_0) {
- if (CExpr_IsBetterImplicitConv(convB, convA))
- return 0;
- if (CExpr_IsBetterImplicitConv(convA, convB))
- flag = 1;
- }
-
- for (i = 0; i < count; i++) {
- if (CExpr_IsBetterImplicitConv(++convB, ++convA))
- return 0;
- if (CExpr_IsBetterImplicitConv(convA, convB))
- flag = 1;
- }
-
- if (flag)
- return 1;
-
- if (b->object) {
- CError_ASSERT(2165, IS_TYPE_FUNC(b->object->type));
- if (b->object->u.func.inst) {
- if (!a->object)
- return 1;
-
- CError_ASSERT(2169, IS_TYPE_FUNC(a->object->type));
- if (!a->object->u.func.inst)
- return 1;
-
- CError_ASSERT(2174, a->specialfunc && b->specialfunc);
- if (CTempl_FuncIsMoreSpecialized(a->specialfunc, b->specialfunc))
- return 1;
- }
- }
-
- return 0;
-}
-
-static Boolean CExpr_MatchArgs(Object *func, ENodeList *argexprs, ENode *expr, ImplicitConv *convs) {
- FuncArg *args;
- ENode *newExpr;
- Type *type;
-
- args = TYPE_FUNC(func->type)->args;
-
- if (!(TYPE_FUNC(func->type)->flags & FUNC_METHOD)) {
- convs->type = ICT_0;
- } else if (TYPE_METHOD(func->type)->is_static) {
- convs->type = ICT_0;
- } else if (TYPE_FUNC(func->type)->flags & FUNC_IS_CTOR) {
- convs->type = ICT_0;
- args = args->next;
- } else {
- if (!expr)
- return 0;
-
- newExpr = lalloc(sizeof(ENode));
- newExpr->type = EINTCONST;
- newExpr->cost = 0;
- newExpr->flags = expr->flags;
- newExpr->rtype = CDecl_NewPointerType(expr->rtype);
- newExpr->data.intval = cint64_zero;
-
- if (func->datatype == DALIAS) {
- CError_ASSERT(2231, func->u.alias.member);
- type = CDecl_NewPointerType(func->u.alias.member->type);
- } else {
- type = args->type;
- }
-
- if (!CExpr_ImplicitConversionMatch(newExpr, type, args->qual, convs))
- return 0;
- args = args->next;
- }
-
- convs++;
- while (1) {
- if (!args || args->type == &stvoid) {
- if (argexprs)
- return 0;
- else
- return 1;
- }
-
- if (args == &elipsis || args == &oldstyle) {
- while (argexprs) {
- convs->type = ICT_1;
- argexprs = argexprs->next;
- convs++;
- }
- return 1;
- }
-
- if (!argexprs)
- return args->dexpr != NULL;
-
- if (!CExpr_ImplicitConversionMatch(argexprs->node, args->type, args->qual, convs))
- return 0;
-
- argexprs = argexprs->next;
- args = args->next;
- convs++;
- }
-}
-
-static Object *CExpr_GetMatchObject(Match *match, HashNameNode *name) {
- Object *object;
- FuncArg *arg;
- TypeFunc *tfunc;
-
- if (match->object)
- return match->object;
-
- tfunc = lalloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = &stvoid;
-
- arg = lalloc(sizeof(FuncArg));
- memclrw(arg, sizeof(FuncArg));
- arg->type = match->type;
- arg->qual = match->qual;
- tfunc->args = arg;
-
- if (match->type2) {
- arg = lalloc(sizeof(FuncArg));
- memclrw(arg, sizeof(FuncArg));
- arg->type = match->type2;
- arg->qual = match->qual2;
- tfunc->args->next = arg;
- }
-
- object = lalloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->name = name;
- object->datatype = DFUNC;
- object->nspace = cscope_root;
- object->type = TYPE(tfunc);
- return object;
-}
-
-static Match *CExpr_FindBestMatch(Match *matches, int count, HashNameNode *name, ObjectList **outList, ENodeList *argExprs) {
- Match *scan;
- Match *best;
- ObjectList *listHead;
- ObjectList *list;
-
- best = matches;
- for (scan = matches->next; scan; scan = scan->next) {
- if (CExpr_IsBetterMatch(scan, best, count))
- best = scan;
- }
-
- for (scan = matches, listHead = NULL; scan; scan = scan->next) {
- if (scan != best && !CExpr_IsBetterMatch(best, scan, count)) {
- list = lalloc(sizeof(ObjectList));
- list->next = listHead;
- list->object = CExpr_GetMatchObject(scan, name);
- listHead = list;
- }
- }
-
- if (!outList) {
- if (listHead)
- CError_OverloadedFunctionError(CExpr_GetMatchObject(best, name), listHead);
- } else {
- *outList = listHead;
- }
-
- return best;
-}
-
-void CExpr_FuncArgMatch(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match13, ENode *expr, Boolean flag) {
- NameSpaceObjectList *i;
- NameSpaceObjectList *j;
- Match *match;
- Match *matches;
- Object *object;
- Object *object2;
- Object *specialfunc;
- ENodeList *argscan;
- int argcount;
-
- for (argscan = argexprs, argcount = 0; argscan; argscan = argscan->next) {
- CDecl_CompleteType(argscan->node->rtype);
- argcount++;
- }
-
- matches = NULL;
- match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv)));
-
- for (i = list; i; i = i->next) {
- object = OBJECT(i->object);
- if (
- object->otype == OT_OBJECT &&
- IS_TYPE_FUNC(object->type) &&
- (!flag || !(object->qual & Q_EXPLICIT))
- )
- {
- if (object->datatype == DALIAS && (TYPE_FUNC(object->type)->flags & FUNC_METHOD)) {
- for (j = list; j; j = j->next) {
- if (j == i)
- continue;
-
- object2 = OBJECT(j->object);
- if (
- object2->otype == OT_OBJECT &&
- IS_TYPE_METHOD(object2->type) &&
- (TYPE_FUNC(object2->type)->flags & FUNC_FLAGS_CV) == (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_CV)
- )
- {
- FuncArg *argsA;
- FuncArg *argsB;
- argsA = TYPE_FUNC(object->type)->args;
- if (argsA && !TYPE_METHOD(object->type)->is_static)
- argsA = argsA->next;
- argsB = TYPE_FUNC(object2->type)->args;
- if (argsB && !TYPE_METHOD(object2->type)->is_static)
- argsB = argsB->next;
- if (is_arglistsame(argsA, argsB))
- break;
- }
- }
-
- if (j)
- continue;
- }
-
- if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) {
- specialfunc = object;
- object = CTempl_DeduceFromFunctionCall(object, templargs, argexprs);
- if (!object)
- continue;
- } else {
- if (templargs)
- continue;
- specialfunc = NULL;
- }
-
- if (CExpr_MatchArgs(object, argexprs, expr, match->conv)) {
- match->object = object;
- match->specialfunc = specialfunc;
- match->next = matches;
- matches = match;
- match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv)));
- }
- }
- }
-
- if (matches) {
- matches = CExpr_FindBestMatch(matches, argcount, NULL, &match13->list, argexprs);
- match13->obj = matches->object;
- }
-}
-
-static ConversionTypeList *CExpr_BuildConversionTypeList(ENode *expr) {
- ConversionTypeList *first;
- ConversionTypeList *list;
- Object *object;
- Type *type;
- ConversionIterator convIter;
-
- if (!IS_TYPE_CLASS(expr->rtype)) {
- first = lalloc(sizeof(ConversionTypeList));
- first->next = NULL;
- first->func = NULL;
- first->type = expr->rtype;
- first->qual = ENODE_QUALS(expr);
- if (IS_TYPE_ENUM(first->type))
- first->qual = 0;
- } else {
- first = NULL;
- CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype));
- while ((object = CExpr_ConversionIteratorNext(&convIter))) {
- type = TYPE_FUNC(object->type)->functype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
-
- if (!IS_TYPE_CLASS(type)) {
- list = lalloc(sizeof(ConversionTypeList));
- list->next = first;
- list->func = object;
- list->type = type;
- list->qual = TYPE_FUNC(object->type)->qual & Q_CV;
- first = list;
- }
- }
- }
-
- return first;
-}
-
-static Type *CExpr_NextPromotedIntegralType(int *p) {
- switch (++(*p)) {
- case 1: return TYPE(&stsignedint);
- case 2: return TYPE(&stunsignedint);
- case 3: return TYPE(&stsignedlong);
- case 4: return TYPE(&stunsignedlong);
- case 5:
- if (copts.longlong)
- return TYPE(&stsignedlonglong);
- else
- return NULL;
- case 6:
- if (copts.longlong)
- return TYPE(&stunsignedlonglong);
- else
- return NULL;
- }
-
- return NULL;
-}
-
-static Type *CExpr_NextArithmeticType(int *p) {
- switch (++(*p)) {
- case 1: return TYPE(&stbool);
- case 2: return TYPE(&stchar);
- case 3: return TYPE(&stsignedchar);
- case 4: return TYPE(&stunsignedchar);
- case 5: return TYPE(&stwchar);
- case 6: return TYPE(&stsignedshort);
- case 7: return TYPE(&stunsignedshort);
- case 8: return TYPE(&stsignedint);
- case 9: return TYPE(&stunsignedint);
- case 10: return TYPE(&stsignedlong);
- case 11: return TYPE(&stunsignedlong);
- case 12: return TYPE(&stfloat);
- case 13: return TYPE(&stdouble);
- case 14: return TYPE(&stlongdouble);
- case 15:
- if (copts.longlong)
- return TYPE(&stsignedlonglong);
- else
- return NULL;
- case 16:
- if (copts.longlong)
- return TYPE(&stunsignedlonglong);
- else
- return NULL;
- }
-
- return NULL;
-}
-
-static Type *CExpr_NextPromotedArithmeticType(int *p) {
- switch (++(*p)) {
- case 1: return TYPE(&stsignedint);
- case 2: return TYPE(&stunsignedint);
- case 3: return TYPE(&stsignedlong);
- case 4: return TYPE(&stunsignedlong);
- case 5: return TYPE(&stdouble);
- case 6: return TYPE(&stlongdouble);
- case 7:
- if (copts.longlong)
- return TYPE(&stsignedlonglong);
- else
- return NULL;
- case 8:
- if (copts.longlong)
- return TYPE(&stunsignedlonglong);
- else
- return NULL;
- }
-
- return NULL;
-}
-
-static Match *CExpr_MatchBuiltin(Match *matches, ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual) {
- Match *scan;
- Match mymatch;
-
- if (CExpr_ImplicitConversionMatch(left, leftType, leftQual, &mymatch.conv[0])) {
- if (!right || CExpr_ImplicitConversionMatch(right, rightType, rightQual, &mymatch.conv[1])) {
- if (right) {
- for (scan = matches; scan; scan = scan->next) {
- if (
- !scan->object &&
- is_typesame(scan->type, leftType) &&
- scan->qual == leftQual &&
- is_typesame(scan->type2, rightType) &&
- scan->qual2 == rightQual
- )
- return matches;
- }
- }
-
- mymatch.next = matches;
- mymatch.object = NULL;
- mymatch.specialfunc = NULL;
- mymatch.type = leftType;
- mymatch.qual = leftQual;
- mymatch.type2 = rightType;
- mymatch.qual2 = rightQual;
-
- matches = lalloc(sizeof(Match));
- *matches = mymatch;
- }
- }
-
- return matches;
-}
-
-static Match *CExpr_CheckIncDecBuiltin(Match *matches, short token, ENode *expr1, ENode *expr2) {
- Object *object;
- Type *type;
- TypeFunc *tfunc;
- ConversionIterator convIter;
-
- if (IS_TYPE_CLASS(expr1->rtype)) {
- CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr1->rtype));
- while ((object = CExpr_ConversionIteratorNext(&convIter))) {
- tfunc = TYPE_FUNC(object->type);
- if (IS_TYPE_REFERENCE(tfunc->functype)) {
- type = TPTR_TARGET(tfunc->functype);
- switch (type->type) {
- case TYPEINT:
- if (type == TYPE(&stbool) && token == TK_DECREMENT)
- break;
- case TYPEFLOAT:
- case TYPEPOINTER:
- if (!CParser_IsConst(type, tfunc->qual)) {
- matches = CExpr_MatchBuiltin(
- matches,
- expr1, type, tfunc->qual,
- expr2, expr2 ? TYPE(&stsignedint) : NULL, 0
- );
- }
- break;
- }
- }
- }
- }
-
- return matches;
-}
-
-static Match *CExpr_CheckUnaryBuiltin(Match *matches, short token, ENode *expr) {
- ConversionTypeList *typelist;
- Type *type;
- int typenum;
-
- switch (token) {
- case TK_INCREMENT:
- case TK_DECREMENT:
- return CExpr_CheckIncDecBuiltin(matches, token, expr, NULL);
-
- case '!':
- matches = CExpr_MatchBuiltin(matches, expr, TYPE(&stbool), 0, NULL, NULL, 0);
- break;
-
- case '~':
- typenum = 0;
- while ((type = CExpr_NextPromotedIntegralType(&typenum))) {
- matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0);
- }
- break;
-
- case '*':
- case '+':
- for (typelist = CExpr_BuildConversionTypeList(expr); typelist; typelist = typelist->next) {
- if (IS_TYPE_POINTER_ONLY(typelist->type))
- matches = CExpr_MatchBuiltin(matches, expr, typelist->type, typelist->qual, NULL, NULL, 0);
- }
- if (token != '+')
- break;
-
- case '-':
- typenum = 0;
- while ((type = CExpr_NextPromotedArithmeticType(&typenum))) {
- matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0);
- }
- break;
- }
-
- return matches;
-}
-
-static Match *CExpr_CheckBinaryBuiltin(Match *matches, ENode *left, short token, ENode *right) {
- int typenum1;
- int typenum2;
- Type *type1;
- Type *type2;
- Type *ptrdiff;
- Boolean allowPtrDiffOnRight;
- Boolean allowPtrCV;
- Boolean allowPtrDiffOnLeft;
- Boolean allowMemberPtrs;
- Boolean allowEnum;
- ConversionTypeList *leftList;
- ConversionTypeList *rightList;
- ConversionTypeList *scan;
-
- switch (token) {
- case TK_INCREMENT:
- case TK_DECREMENT:
- return CExpr_CheckIncDecBuiltin(matches, token, left, right);
-
- case '*':
- case '+':
- case '-':
- case '/':
- case ':':
- case '<':
- case '>':
- case TK_LOGICAL_EQ:
- case TK_LOGICAL_NE:
- case TK_LESS_EQUAL:
- case TK_GREATER_EQUAL:
- typenum1 = 0;
- while ((type1 = CExpr_NextPromotedArithmeticType(&typenum1))) {
- typenum2 = 0;
- while ((type2 = CExpr_NextPromotedArithmeticType(&typenum2))) {
- matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0);
- }
- }
- break;
-
- case '%':
- case '&':
- case '^':
- case '|':
- case TK_SHL:
- case TK_SHR:
- typenum1 = 0;
- while ((type1 = CExpr_NextPromotedIntegralType(&typenum1))) {
- typenum2 = 0;
- while ((type2 = CExpr_NextPromotedIntegralType(&typenum2))) {
- matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0);
- }
- }
- return matches;
-
- case TK_LOGICAL_OR:
- case TK_LOGICAL_AND:
- return CExpr_MatchBuiltin(matches, left, TYPE(&stbool), 0, right, TYPE(&stbool), 0);
- }
-
- allowEnum = 0;
- allowMemberPtrs = 0;
- allowPtrCV = 0;
- allowPtrDiffOnLeft = 0;
- allowPtrDiffOnRight = 0;
-
- switch (token) {
- case '+':
- case '[':
- allowPtrDiffOnLeft = 1;
- allowPtrDiffOnRight = 1;
- break;
- case '-':
- allowPtrCV = 1;
- allowPtrDiffOnRight = 1;
- break;
- case ':':
- case TK_LOGICAL_EQ:
- case TK_LOGICAL_NE:
- allowMemberPtrs = 1;
- case '<':
- case '>':
- case TK_LESS_EQUAL:
- case TK_GREATER_EQUAL:
- allowPtrCV = 1;
- allowEnum = 1;
- break;
- default:
- return matches;
- }
-
- leftList = CExpr_BuildConversionTypeList(left);
- rightList = CExpr_BuildConversionTypeList(right);
- ptrdiff = CABI_GetPtrDiffTType();
-
- for (scan = leftList; ; scan = scan->next) {
- if (!scan) {
- scan = rightList;
- if (!rightList)
- break;
- rightList = NULL;
- }
-
- type1 = scan->type;
- if (IS_TYPE_REFERENCE(type1))
- type1 = TPTR_TARGET(type1);
-
- switch (type1->type) {
- case TYPEENUM:
- if (allowEnum)
- matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual);
- break;
-
- case TYPEPOINTER:
- if (allowPtrDiffOnRight)
- matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, ptrdiff, 0);
- if (allowPtrDiffOnLeft)
- matches = CExpr_MatchBuiltin(matches, left, ptrdiff, 0, right, type1, scan->qual);
- if (allowPtrCV) {
- if (IS_TYPE_POINTER_ONLY(TPTR_TARGET(type1))) {
- type2 = galloc(sizeof(TypePointer));
- *TYPE_POINTER(type2) = *TYPE_POINTER(type1);
- TPTR_QUAL(type2) |= Q_CONST | Q_VOLATILE;
- matches = CExpr_MatchBuiltin(matches, left, type2, scan->qual, right, type2, scan->qual);
- } else {
- matches = CExpr_MatchBuiltin(matches, left, type1, Q_CONST | Q_VOLATILE, right, type1, Q_CONST | Q_VOLATILE);
- }
- }
- break;
-
- case TYPEMEMBERPOINTER:
- if (allowMemberPtrs)
- matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual);
- break;
- }
- }
-
- return matches;
-}
-
-static Boolean CExpr_MatchOperands(ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual, ImplicitConv *twoResults, Boolean flag) {
- if (flag) {
- if (!CExpr_StandardConversionMatch(left, leftType, leftQual, 1, &twoResults[0].u.ic3.standardConv))
- return 0;
- twoResults[0].type = ICT_3;
- } else {
- if (!CExpr_ImplicitConversionMatch(left, leftType, leftQual, &twoResults[0]))
- return 0;
- }
-
- if (right) {
- if (!CExpr_ImplicitConversionMatch(right, rightType, rightQual, &twoResults[1]))
- return 0;
- }
-
- return 1;
-}
-
-Boolean CExpr_CondOperatorMatch(ENode *left, ENode *right, Conversion *conv) {
- Match *match;
-
- if ((match = CExpr_CheckBinaryBuiltin(NULL, left, ':', right))) {
- match = CExpr_FindBestMatch(match, 1, GetHashNameNode("operator?:"), NULL, NULL);
- CError_ASSERT(2931, !match->object);
-
- conv->x0 = NULL;
- conv->left = CExpr_Convert(left, match->type, match->qual, 0, 1);
- conv->right = CExpr_Convert(right, match->type2, match->qual2, 0, 1);
- return 1;
- }
-
- return 0;
-}
-
-Boolean CExpr_OperatorMatch(short token, ENode *left, ENode *right, Conversion *conv) {
- HashNameNode *name;
- ENodeList *argExprs;
- BClassList *path;
- int hasArg;
- Match *matches;
- Object *object;
- Object *specialfunc;
- NameSpaceObjectList *list;
- Type *leftType;
- UInt32 leftQual;
- Type *rightType;
- UInt32 rightQual;
- NameResult pr;
- NameSpaceObjectList myList;
- Match myMatch;
-
- if (!IS_TYPE_CLASS(left->rtype)) {
- if (!IS_TYPE_ENUM(left->rtype)) {
- if (!right || !(IS_TYPE_CLASS(right->rtype) || IS_TYPE_ENUM(right->rtype)))
- return 0;
- }
- } else {
- CDecl_CompleteType(left->rtype);
- }
-
- name = CMangler_OperatorName(token);
- path = NULL;
-
- argExprs = lalloc(sizeof(ENodeList));
- argExprs->node = left;
- if (right) {
- argExprs->next = lalloc(sizeof(ENodeList));
- argExprs->next->node = right;
- argExprs->next->next = NULL;
- hasArg = 1;
- } else {
- argExprs->next = NULL;
- hasArg = 0;
- }
-
- matches = NULL;
-
- if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr, name)) {
- if (token != '=' || (pr.bcl_18->type == left->rtype && !pr.bcl_18->next)) {
- if (pr.obj_10) {
- myList.next = NULL;
- myList.object = pr.obj_10;
- pr.nsol_14 = &myList;
- } else {
- CError_ASSERT(3009, pr.nsol_14);
- }
-
- for (list = pr.nsol_14; list; list = list->next) {
- object = OBJECT(list->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) {
- if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) {
- specialfunc = object;
- object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs->next);
- if (!object)
- continue;
- } else {
- specialfunc = NULL;
- }
-
- leftType = CExpr_GetImplictObjectParamType(object, &leftQual);
- if (right) {
- if (!CExpr_HasNParams(object, 1))
- continue;
- rightType = CExpr_GetParamType(object, 0, &rightQual);
- } else {
- if (!CExpr_HasNParams(object, 0))
- continue;
- }
-
- if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 1)) {
- myMatch.object = object;
- myMatch.specialfunc = specialfunc;
- myMatch.next = matches;
- matches = lalloc(sizeof(Match));
- *matches = myMatch;
- path = pr.bcl_18;
- }
- }
- }
- }
- }
-
- if (CScope_FindNonClassObject(cscope_current, &pr, name)) {
- if (pr.obj_10) {
- myList.next = NULL;
- myList.object = pr.obj_10;
- pr.nsol_14 = &myList;
- }
- } else {
- pr.nsol_14 = NULL;
- }
-
- if (copts.arg_dep_lookup)
- pr.nsol_14 = CScope_ArgumentDependentNameLookup(pr.nsol_14, name, argExprs, 1);
-
- for (list = pr.nsol_14; list; list = list->next) {
- object = OBJECT(list->object);
- if (object->otype == OT_OBJECT && IS_TYPE_NONMETHOD(object->type)) {
- if (TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) {
- specialfunc = object;
- object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs);
- if (!object)
- continue;
- } else {
- specialfunc = NULL;
- }
-
- leftType = CExpr_GetParamType(object, 0, &leftQual);
- if (right) {
- if (!CExpr_HasNParams(object, 2))
- continue;
- rightType = CExpr_GetParamType(object, 1, &rightQual);
- } else {
- if (!CExpr_HasNParams(object, 1))
- continue;
- }
-
- if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 0)) {
- myMatch.object = object;
- myMatch.specialfunc = specialfunc;
- myMatch.next = matches;
- matches = lalloc(sizeof(Match));
- *matches = myMatch;
- }
- }
- }
-
- if (right)
- matches = CExpr_CheckBinaryBuiltin(matches, left, token, right);
- else
- matches = CExpr_CheckUnaryBuiltin(matches, token, left);
-
- if (matches) {
- conv->x0 = NULL;
- conv->left = NULL;
- conv->right = NULL;
-
- matches = CExpr_FindBestMatch(matches, hasArg, name, NULL, argExprs);
- object = matches->object;
- if (!object) {
- if (IS_TYPE_CLASS(left->rtype))
- conv->left = CExpr_Convert(left, matches->type, matches->qual, 0, 1);
- else
- conv->left = left;
-
- if (right) {
- if (IS_TYPE_CLASS(right->rtype))
- conv->right = CExpr_Convert(right, matches->type2, matches->qual2, 0, 1);
- else
- conv->right = right;
- }
-
- return 1;
- }
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) {
- CError_ASSERT(3125, path);
- left = CExpr_GenericFuncCall(path, argExprs->node, 0, object, NULL, NULL, argExprs->next, 0, 0, 1);
- } else {
- left = CExpr_GenericFuncCall(NULL, NULL, 0, object, NULL, NULL, argExprs, 0, 0, 1);
- }
-
- conv->x0 = checkreference(left);
- return 1;
- }
-
- return 0;
-}
-
-static ENode *CExpr_ClassCopyInit(TypeClass *tclass, ENode *expr1, ENode *expr2) {
- Object *best;
- NameSpaceObjectList *list;
- ObjectList *objlist;
- ObjectList *objlistEntry;
- ENodeList *argExprs;
- FuncArg *arg;
- Type *type;
- Object *object;
- ImplicitConv bestConv;
- ImplicitConv conv;
- BClassList path;
- ConversionIterator convIter;
-
- best = NULL;
- objlist = NULL;
-
- for (list = CClass_Constructor(tclass); list; list = list->next) {
- object = OBJECT(list->object);
- if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type) && !(object->qual & Q_EXPLICIT)) {
- arg = TYPE_FUNC(object->type)->args;
-
- CError_ASSERT(3199, arg);
- arg = arg->next;
-
- if (tclass->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(3203, arg);
- arg = arg->next;
- }
-
- if (
- arg &&
- arg != &elipsis &&
- (!arg->next || arg->next->dexpr) &&
- CExpr_ImplicitConversionMatch(expr2, arg->type, arg->qual, &conv)
- )
- {
- if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) {
- best = object;
- bestConv = conv;
- objlist = NULL;
- } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) {
- objlistEntry = lalloc(sizeof(ObjectList));
- objlistEntry->next = objlist;
- objlistEntry->object = object;
- objlist = objlistEntry;
- }
- }
- }
- }
-
- if (IS_TYPE_CLASS(expr2->rtype)) {
- CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr2->rtype));
- while ((object = CExpr_ConversionIteratorNext(&convIter))) {
- type = TYPE_FUNC(object->type)->functype;
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
-
- if (
- IS_TYPE_CLASS(type) &&
- (tclass == TYPE_CLASS(type) || CClass_IsBaseClass(tclass, TYPE_CLASS(type), NULL, 0, 0))
- )
- {
- CError_ASSERT(3248, TYPE_FUNC(object->type)->args &&
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->args->type));
-
- type = galloc(sizeof(TypePointer));
- *TYPE_POINTER(type) = *TYPE_POINTER(TYPE_FUNC(object->type)->args->type);
- TPTR_QUAL(type) = Q_REFERENCE;
- if (CExpr_ImplicitConversionMatch(expr2, type, TYPE_FUNC(object->type)->args->qual, &conv)) {
- if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) {
- best = object;
- bestConv = conv;
- objlist = NULL;
- } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) {
- objlistEntry = lalloc(sizeof(ObjectList));
- objlistEntry->next = objlist;
- objlistEntry->object = object;
- objlist = objlistEntry;
- }
- }
- }
- }
- }
-
- if (objlist)
- CError_OverloadedFunctionError(best, objlist);
-
- if (!best) {
- CError_Error(CErrorStr209, expr2->rtype, ENODE_QUALS(expr2), tclass, 0);
- return expr1;
- }
-
- CError_ASSERT(3284, IS_TYPE_POINTER_ONLY(expr1->rtype));
-
- expr1 = makemonadicnode(expr1, EINDIRECT);
- expr1->rtype = TYPE(tclass);
-
- argExprs = lalloc(sizeof(ENodeList));
- argExprs->node = expr2;
- if (tclass->flags & CLASS_HAS_VBASES) {
- argExprs->next = lalloc(sizeof(ENodeList));
- argExprs->next->next = NULL;
- argExprs->next->node = intconstnode(TYPE(&stsignedshort), 1);
- } else {
- argExprs->next = NULL;
- }
-
- path.next = NULL;
- path.type = TYPE(tclass);
- expr1 = CExpr_GenericFuncCall(&path, expr1, 0, best, NULL, NULL, argExprs, 0, 0, 1);
-
- if (ENODE_IS2(expr1, EFUNCCALL, EFUNCCALLP))
- expr1->rtype = CDecl_NewPointerType(TYPE(tclass));
-
- expr1 = makemonadicnode(expr1, EINDIRECT);
- expr1->rtype = TYPE(tclass);
- return expr1;
-}
diff --git a/compiler_and_linker/unsorted/CFunc.c b/compiler_and_linker/unsorted/CFunc.c
deleted file mode 100644
index 38cfab3..0000000
--- a/compiler_and_linker/unsorted/CFunc.c
+++ /dev/null
@@ -1,3224 +0,0 @@
-#include "compiler/CFunc.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/FuncLevelAsmPPC.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/Switch.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-struct CFuncSave {
- CScopeSave scope;
- ObjectList *arguments;
- ObjectList *locals;
- CLabel *labels;
- Statement *curstmt;
- DeclBlock *firstblock;
- DeclBlock *currentblock;
- ExceptionAction *cexcept_dobjstack;
- CLabel *sinit_label;
- ENode *ainit_expr;
- CtorChain *ctor_chain;
- ParserTryBlock *trychain;
- TempNodeCB cinit_tempnodefunc;
- HashNameNode *tkidentifier;
- Object *sinit_first_object;
- FileOffsetInfo cparser_fileoffset;
- TStreamElement symdecltoken;
- SInt32 functionbodyoffset;
- HashNameNode *functionbodypath;
- SInt32 symdecloffset;
- SInt32 symdeclend;
- SInt32 sourceoffset;
- HashNameNode *sourcefilepath;
- SInt32 curstmtvalue;
- NameObjCheckCB name_obj_check;
- FuncArg *check_arglist;
- short blockcount;
- short localcount;
- short tk;
- AccessType global_access;
- Boolean cexcept_hasdobjects;
- Boolean ainit_only_one;
- Boolean cfunc_is_extern_c;
- Boolean temp_reference_init;
-};
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-FuncArg elipsis;
-FuncArg oldstyle;
-ObjectList *arguments;
-ObjectList *locals;
-short localcount;
-SInt32 curstmtvalue;
-SInt32 sourceoffset;
-HashNameNode *sourcefilepath;
-SInt32 functionbodyoffset;
-HashNameNode *functionbodypath;
-InitExpr *init_expressions;
-CLabel *Labels;
-CtorChain *ctor_chain;
-Statement *curstmt;
-static short temp_destructor_object_regmem;
-static short temp_destructor_objects;
-static short temp_expression_has_conditionals;
-static DeclBlock *firstblock;
-static DeclBlock *currentblock;
-static short blockcount;
-static Object *sinit_first_object;
-static CLabel *sinit_label;
-static Boolean ainit_only_one;
-static ENode *ainit_expr;
-static FuncArg *check_arglist;
-static Boolean cfunc_is_extern_c;
-static short cfunc_staticvarcount;
-static void *destroyobjects;
-static Boolean cfunc_hasdtortemp;
-
-// forward decls
-static void statement(DeclThing *thing);
-
-static void CFunc_LoopIncrement(void) {
- if (curstmtvalue >= 0x1000) {
- if (curstmtvalue >= 0xF000)
- curstmtvalue++;
- else
- curstmtvalue += 0x1000;
- } else {
- curstmtvalue <<= 3;
- }
-}
-
-static void CFunc_LoopDecrement(void) {
- if (curstmtvalue > 0x1000) {
- if (curstmtvalue > 0xF000)
- curstmtvalue--;
- else
- curstmtvalue -= 0x1000;
- } else {
- curstmtvalue >>= 3;
- }
-
- if (curstmtvalue < 1)
- curstmtvalue = 1;
-}
-
-DeclBlock *CFunc_NewDeclBlock(void) {
- DeclBlock *block;
- NameSpace *nspace;
-
- block = lalloc(sizeof(DeclBlock));
- if (firstblock) {
- currentblock->next = block;
- currentblock = block;
- } else {
- firstblock = block;
- currentblock = block;
- }
-
- block->index = blockcount++;
- block->parent_nspace = cscope_current;
- block->dobjstack = cexcept_dobjstack;
-
- nspace = CScope_NewListNameSpace(NULL, 0);
- nspace->parent = cscope_current;
- cscope_current = nspace;
-
- return block;
-}
-
-void CFunc_RestoreBlock(DeclBlock *block) {
- if (curstmt && curstmt->dobjstack != cexcept_dobjstack) {
- Statement *stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = nullnode();
- }
-
- cscope_current = block->parent_nspace;
- cexcept_dobjstack = block->dobjstack;
-}
-
-void CFunc_SetupLocalVarInfo(Object *obj) {
- obj->u.var.info = CodeGen_GetNewVarInfo();
- obj->u.var.info->func = cscope_currentfunc;
-
- if (obj->sclass == TK_REGISTER) {
- if (!copts.optimizesize)
- obj->u.var.info->usage = 100;
- else
- obj->u.var.info->usage = 5;
- }
-
- if (obj->type && is_volatile_object(obj))
- obj->u.var.info->noregister = 1;
-}
-
-static void adjustargumenttype(DeclInfo *declinfo) {
- switch (declinfo->thetype->type) {
- case TYPECLASS:
- if (TYPE_CLASS(declinfo->thetype)->sominfo) {
- CError_Error(CErrorStr284);
- declinfo->thetype = TYPE(&stsignedint);
- }
- break;
- case TYPEFUNC:
- makethetypepointer(declinfo, 0);
- return;
- case TYPEARRAY:
- declinfo->thetype = CDecl_NewPointerType(TPTR_TARGET(declinfo->thetype));
- return;
- case TYPETEMPLATE:
- if (TYPE_TEMPLATE(declinfo->thetype)->dtype == TEMPLDEP_ARRAY)
- declinfo->thetype = CDecl_NewPointerType(TYPE_TEMPLATE(declinfo->thetype)->u.array.type);
- return;
- }
-
- if (!CanCreateObject(declinfo->thetype))
- declinfo->thetype = TYPE(&stsignedint);
-}
-
-static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) {
- while (list) {
- if (name == list->name)
- return list;
- list = list->next;
- }
-
- return NULL;
-}
-
-static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) {
- while (list) {
- if (name == list->object->name)
- return list->object;
- list = list->next;
- }
-
- return NULL;
-}
-
-static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) {
- FuncArg *tail;
-
- if ((tail = *list)) {
- while (tail->next)
- tail = tail->next;
- tail->next = arg;
- } else {
- *list = arg;
- }
-}
-
-static void identifier_list(DeclInfo *declinfo) {
- FuncArg *arg;
-
- declinfo->x45 = 1;
-
- while (1) {
- if (tk != TK_IDENTIFIER) {
- CError_Error(CErrorStr121);
- } else {
- if (CFunc_IsInArgList(declinfo->x18, tkidentifier))
- CError_Error(CErrorStr122, tkidentifier->name);
-
- arg = CParser_NewFuncArg();
- arg->name = tkidentifier;
- CFunc_AppendArg(&declinfo->x18, arg);
- declinfo->x44 = 1;
- }
-
- if ((tk = lex()) != ',')
- break;
- tk = lex();
- }
-}
-
-static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) {
- FuncArg *arg;
-
- if (name) {
- for (arg = check_arglist; arg; arg = arg->next) {
- if (arg->name == name) {
- CError_Error(CErrorStr205);
- return 0;
- }
- }
- }
-
- if (obj && obj->datatype == DLOCAL) {
- CError_Error(CErrorStr205);
- return 0;
- }
-
- return 1;
-}
-
-ENode *CFunc_DefaultArg(Type *type, UInt32 qual, FuncArg *args) {
- TStreamElement *element;
- ENode *expr;
- ENode *templdepexpr;
-
- name_obj_check = defarg_name_obj_check;
- check_arglist = args;
- expr = conv_assignment_expression();
- name_obj_check = NULL;
-
- if (
- !CTemplTool_IsTemplateArgumentDependentExpression(expr) &&
- !CTemplTool_IsTemplateArgumentDependentType(type)
- )
- {
- expr = argumentpromotion(expr, type, qual, 1);
- } else {
- element = CPrep_CurStreamElement();
- if (element && element->tokenfile) {
- templdepexpr = CExpr_NewTemplDepENode(TDE_SOURCEREF);
- templdepexpr->data.templdep.u.sourceref.expr = expr;
- templdepexpr->data.templdep.u.sourceref.token = galloc(sizeof(TStreamElement));
- *templdepexpr->data.templdep.u.sourceref.token = *element;
- expr = templdepexpr;
- }
- }
-
- return CInline_CopyExpression(expr, CopyMode1);
-}
-
-static FuncArg *parameter_list(DeclInfo *declinfo) {
- Boolean flag26;
- FuncArg *args;
- FuncArg *arg;
- DeclInfo my_di;
- Boolean isArray;
-
- args = NULL;
- flag26 = 1;
-
- while (1) {
- if (tk == TK_ELLIPSIS) {
- if (flag26) {
- if (!copts.cplusplus && copts.ANSIstrict)
- CError_Warning(CErrorStr127);
- args = &elipsis;
- } else {
- CFunc_AppendArg(&args, &elipsis);
- }
-
- tk = lex();
- return args;
- }
-
- memclrw(&my_di, sizeof(my_di));
- CParser_GetDeclSpecs(&my_di, 0);
- if (my_di.x48)
- CError_Error(CErrorStr127);
-
- if (
- my_di.storageclass &&
- my_di.storageclass != TK_REGISTER &&
- (!copts.cplusplus || my_di.storageclass != TK_AUTO)
- )
- {
- CError_Error(CErrorStr127);
- my_di.storageclass = 0;
- }
-
- my_di.name = NULL;
-
- scandeclarator(&my_di);
-
- if (flag26) {
- flag26 = 0;
- if (my_di.thetype == &stvoid) {
- if (my_di.storageclass || my_di.qual || my_di.name)
- CError_Error(CErrorStr127);
- return NULL;
- }
- }
-
- isArray = IS_TYPE_ARRAY(my_di.thetype);
- adjustargumenttype(&my_di);
-
- if (my_di.name) {
- if (args && CFunc_IsInArgList(args, my_di.name))
- CError_Error(CErrorStr122, my_di.name->name);
- } else {
- my_di.name = no_name_node;
- }
-
- if (my_di.thetype == &stvoid)
- CError_Error(CErrorStr126);
-
- arg = CParser_NewFuncArg();
- arg->name = my_di.name;
- arg->type = my_di.thetype;
- arg->qual = my_di.qual;
- arg->sclass = my_di.storageclass;
- arg->is_array = isArray;
- CFunc_AppendArg(&args, arg);
-
- if (copts.cplusplus && tk == '=') {
- tk = lex();
- arg->dexpr = CFunc_DefaultArg(arg->type, arg->qual, args);
- }
-
- if (tk != ',') {
- if (tk != TK_ELLIPSIS || !copts.cplusplus)
- return args;
- } else {
- tk = lex();
- }
- }
-}
-
-Boolean CFunc_ParseFakeArgList(Boolean flag) {
- DeclInfo di;
-
- if (tk == TK_ELLIPSIS)
- return 1;
-
- do {
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (di.x48)
- return 0;
-
- scandeclarator(&di);
-
- if (tk == '=') {
- tk = lex();
- assignment_expression();
- }
-
- switch (tk) {
- case TK_ELLIPSIS:
- return 1;
- case ',':
- if (!flag)
- tk = lex();
- else
- return 1;
- break;
- default:
- return 0;
- }
- } while (tk != TK_ELLIPSIS);
-
- return 1;
-}
-
-FuncArg *parameter_type_list(DeclInfo *declinfo) {
- FuncArg *args;
- NameSpace *nspace;
- Boolean save_in_func_arglist;
-
- declinfo->x44 = 0;
- declinfo->x45 = 0;
- declinfo->x1C = NULL;
-
- if (tk == TK_ELLIPSIS || isdeclaration(0, 0, 0, 0)) {
- if (!copts.cplusplus) {
- nspace = CScope_NewListNameSpace(NULL, 0);
- nspace->parent = cscope_current;
- cscope_current = nspace;
-
- save_in_func_arglist = in_func_arglist;
- in_func_arglist = 1;
- args = parameter_list(declinfo);
- in_func_arglist = save_in_func_arglist;
-
- cscope_current = nspace->parent;
-
- if (!CScope_IsEmptyNameSpace(nspace))
- declinfo->x1C = nspace;
- } else {
- args = parameter_list(declinfo);
- }
- } else if (copts.cplusplus) {
- args = NULL;
- if (tk != ')')
- CError_Error(CErrorStr127);
- } else {
- identifier_list(declinfo);
- args = &oldstyle;
- }
-
- return args;
-}
-
-CLabel *findlabel(void) {
- CLabel *scan;
-
- for (scan = Labels; scan; scan = scan->next) {
- if (tkidentifier == scan->name)
- return scan;
- }
-
- return NULL;
-}
-
-CLabel *newlabel(void) {
- CLabel *label = lalloc(sizeof(CLabel));
- memclrw(label, sizeof(CLabel));
-
- label->name = label->uniquename = CParser_GetUniqueName();
- return label;
-}
-
-Statement *CFunc_AppendStatement(StatementType sttype) {
- Statement *stmt = lalloc(sizeof(Statement));
-
- stmt->next = NULL;
- stmt->type = sttype;
- stmt->value = curstmtvalue;
- stmt->flags = 0;
- stmt->sourceoffset = sourceoffset;
- stmt->sourcefilepath = sourcefilepath;
- stmt->dobjstack = cexcept_dobjstack;
-
- curstmt->next = stmt;
- curstmt = stmt;
- return stmt;
-}
-
-Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) {
- Statement *stmt = lalloc(sizeof(Statement));
-
- stmt->next = after->next;
- after->next = stmt;
- stmt->type = sttype;
- stmt->value = after->value;
- stmt->flags = 0;
- stmt->sourceoffset = after->sourceoffset;
- stmt->sourcefilepath = after->sourcefilepath;
- stmt->dobjstack = after->dobjstack;
-
- return stmt;
-}
-
-Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) {
- Statement *stmt = lalloc(sizeof(Statement));
-
- *stmt = *before;
- before->next = stmt;
- before->type = sttype;
- before->flags = 0;
-
- return before;
-}
-
-void CheckCLabels(void) {
- CLabel *scan;
-
- for (scan = Labels; scan; scan = scan->next) {
- if (!scan->stmt)
- CError_Error(CErrorStr159, scan->name->name);
- }
-}
-
-Object *create_temp_object(Type *type) {
- Object *object = CParser_NewLocalDataObject(NULL, 1);
- object->name = CParser_GetUniqueName();
- object->type = type;
- CFunc_SetupLocalVarInfo(object);
- return object;
-}
-
-ENode *create_temp_node(Type *type) {
- ENode *node;
-
- if (cinit_tempnodefunc)
- return cinit_tempnodefunc(type, 0);
-
- node = CExpr_NewETEMPNode(type, 0);
- if (IS_TYPE_CLASS(type) && CClass_Destructor(TYPE_CLASS(type)))
- node->data.temp.needs_dtor = 1;
- return node;
-}
-
-ENode *create_temp_node2(Type *type) {
- ENode *node;
-
- if (cinit_tempnodefunc)
- return cinit_tempnodefunc(type, 1);
-
- node = CExpr_NewETEMPNode(type, 0);
- node->data.temp.needs_dtor = 1;
- return node;
-}
-
-static ENode *CFunc_DestroyReverse(ENode *expr, DtorTemp *list) {
- expr = makediadicnode(expr, CABI_DestroyObject(list->dtor, create_objectrefnode(list->object), CABIDestroy1, 1, 0), ECOMMA);
- expr->rtype = &stvoid;
- if (list->next)
- expr = CFunc_DestroyReverse(expr, list->next);
- return expr;
-}
-
-static ENode *CFunc_TempTransDestroy(ENode *expr, DtorTemp *list, Boolean flag) {
- Object *tempobj;
-
- if (flag) {
- CError_ASSERT(738, !(IS_TYPE_CLASS(expr->rtype) && CClass_Destructor(TYPE_CLASS(expr->rtype))));
- tempobj = create_temp_object(expr->rtype);
- expr = makediadicnode(create_objectnode(tempobj), expr, EASS);
- }
-
- expr = CFunc_DestroyReverse(expr, list);
-
- if (flag) {
- expr = makediadicnode(expr, create_objectnode(tempobj), ECOMMA);
- expr->rtype = tempobj->type;
- }
-
- return expr;
-}
-
-void CFunc_WarnUnused(void) {
- if (copts.warn_unusedvar) {
- ObjectList *list;
- for (list = locals; list; list = list->next) {
- if (
- !(list->object->flags & OBJECT_USED) &&
- !IsTempName(list->object->name) &&
- !(list->object->qual & Q_INLINE_DATA)
- )
- {
- CError_SetErrorToken(&list->object->u.var.info->deftoken);
- CError_Warning(CErrorStr182, &list->object->name->name);
- }
- }
- }
-
- if (copts.warn_unusedarg) {
- ObjectList *list;
- for (list = arguments; list; list = list->next) {
- if (
- !(list->object->flags & OBJECT_USED) &&
- !IsTempName(list->object->name) &&
- list->object->name != this_name_node &&
- list->object->name != self_name_node
- )
- {
- CError_SetErrorToken(&symdecltoken);
- CError_Warning(CErrorStr182, &list->object->name->name);
- }
- }
- }
-}
-
-void CFunc_CodeCleanup(Statement *stmt) {
- if (cscope_currentclass && cscope_currentclass->sominfo)
- CSOM_InitSOMSelf(cscope_currentclass, stmt);
-
- CFunc_WarnUnused();
- CExcept_ExceptionTansform(stmt);
-}
-
-static Boolean DestructorNeeded(ExceptionAction *ea, ExceptionAction *end) {
- while (ea) {
- if (CExcept_ActionNeedsDestruction(ea))
- return 1;
- if (ea == end)
- break;
- ea = ea->prev;
- }
-
- return 0;
-}
-
-static Statement *DestructLocals(Statement *stmt, ExceptionAction *ea, ExceptionAction *end) {
- while (ea) {
- stmt = CExcept_ActionCleanup(ea, stmt);
- if (ea == end)
- break;
- ea = ea->prev;
- }
-
- return stmt;
-}
-
-static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) {
- ExceptionAction *ea2;
- ExceptionAction *ea1;
- ExceptionAction *scan;
-
- ea1 = stmt1->dobjstack;
- ea2 = stmt2->dobjstack;
-
- for (scan = ea2; scan; scan = scan->prev) {
- if (scan == ea1)
- return 0;
- }
-
- while (ea1 && ea1 != ea2) {
- if (CExcept_ActionNeedsDestruction(ea1))
- return 1;
- ea1 = ea1->prev;
- }
-
- return 0;
-}
-
-static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) {
- ExceptionAction *ea1;
- ExceptionAction *ea2;
-
- for (ea2 = stmt2->dobjstack; ea2; ea2 = ea2->prev) {
- for (ea1 = stmt1->dobjstack; ea1; ea1 = ea1->prev) {
- if (ea1->prev == ea2)
- return ea1;
- }
- }
-
- return NULL;
-}
-
-static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) {
- Statement *stmt;
- Object *tempobj;
-
- if (stmt1->dobjstack != stmt2->dobjstack && NeedsDestruction(stmt1, stmt2))
- stmt1 = DestructLocals(stmt1, stmt1->dobjstack, FindLastNonCommonStackObj(stmt1, stmt2));
-
- if (DestructorNeeded(stmt2->dobjstack, NULL)) {
- if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) != 1) {
- tempobj = create_temp_object(stmt2->expr->rtype);
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1);
- stmt->expr = makediadicnode(create_objectnode(tempobj), stmt2->expr, EASS);
- stmt->sourceoffset = stmt2->sourceoffset;
- stmt->sourcefilepath = stmt2->sourcefilepath;
- DestructLocals(stmt, stmt2->dobjstack, NULL);
- stmt2->expr = create_objectnode(tempobj);
- } else {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1);
- stmt->expr = stmt2->expr;
- stmt->sourceoffset = stmt2->sourceoffset;
- stmt->sourcefilepath = stmt2->sourcefilepath;
- DestructLocals(stmt, stmt2->dobjstack, NULL);
- stmt2->expr = nullnode();
- }
- }
-}
-
-static Statement *DestructorIfTransform(Statement *stmt) {
- CLabel *label;
- Statement *newStmt;
-
- if (stmt->type == ST_IFGOTO)
- stmt->type = ST_IFNGOTO;
- else
- stmt->type = ST_IFGOTO;
-
- label = newlabel();
- newStmt = DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, stmt->label->stmt));
- newStmt = CFunc_InsertStatement(ST_GOTO, newStmt);
- newStmt->label = stmt->label;
- newStmt = CFunc_InsertStatement(ST_LABEL, newStmt);
- newStmt->label = label;
- label->stmt = newStmt;
- stmt->label = label;
- newStmt->dobjstack = stmt->dobjstack;
- return newStmt;
-}
-
-static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) {
- if (!exc1)
- return 1;
-
- while (exc2) {
- if (exc2 == exc1)
- return 1;
- exc2 = exc2->prev;
- }
-
- return 0;
-}
-
-static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) {
- if (stmt->dobjstack != exc && !IsSubStack(exc, stmt->dobjstack)) {
- while (exc) {
- if (CExcept_ActionNeedsDestruction(exc) && exc->type != EAT_ACTIVECATCHBLOCK) {
- CError_Warning(CErrorStr211);
- break;
- }
- exc = exc->prev;
- }
- }
-}
-
-void CFunc_DestructorCleanup(Statement *stmt) {
- Statement *scan;
- Statement *next;
- SwitchCase *swcase;
-
- if (copts.cplusplus) {
- for (scan = stmt; scan; scan = scan->next) {
- switch (scan->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_EXPRESSION:
- case ST_RETURN:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- case ST_ASM:
- break;
- case ST_SWITCH:
- CFunc_CheckInitSkip(scan, ((SwitchInfo *) scan->label)->defaultlabel->stmt->dobjstack);
- for (swcase = ((SwitchInfo *) scan->label)->cases; swcase; swcase = swcase->next) {
- CFunc_CheckInitSkip(scan, swcase->label->stmt->dobjstack);
- }
- break;
- case ST_GOTO:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CFunc_CheckInitSkip(scan, scan->label->stmt->dobjstack);
- break;
- default:
- CError_FATAL(1045);
- }
- }
-
- if (cexcept_hasdobjects) {
- while (1) {
- next = stmt->next;
- if (!next) {
- if (stmt->type != ST_RETURN && stmt->dobjstack)
- DestructLocals(stmt, stmt->dobjstack, NULL);
- return;
- }
-
- switch (next->type) {
- case ST_GOTO:
- if (
- stmt->dobjstack != next->label->stmt->dobjstack &&
- NeedsDestruction(stmt, next->label->stmt)
- )
- {
- DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next->label->stmt));
- }
- stmt = next;
- continue;
-
- case ST_RETURN:
- if (next->expr && DestructorNeeded(stmt->dobjstack, NULL)) {
- DestructorReturnTransform(stmt, next);
- } else if (stmt->dobjstack) {
- DestructLocals(stmt, stmt->dobjstack, NULL);
- }
- stmt = next;
- continue;
- }
-
- switch (stmt->type) {
- case ST_GOTO:
- case ST_SWITCH:
- case ST_RETURN:
- case ST_GOTOEXPR:
- break;
- case ST_NOP:
- case ST_LABEL:
- case ST_EXPRESSION:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_ASM:
- if (
- stmt->dobjstack != next->dobjstack &&
- NeedsDestruction(stmt, next)
- )
- {
- DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next));
- }
- break;
- default:
- CError_FATAL(1109);
- }
-
- switch (next->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_ASM:
- stmt = next;
- continue;
-
- case ST_IFGOTO:
- case ST_IFNGOTO:
- if (
- next->dobjstack != next->label->stmt->dobjstack &&
- NeedsDestruction(next, next->label->stmt)
- )
- {
- stmt = DestructorIfTransform(next);
- } else {
- stmt = next;
- }
- break;
-
- default:
- CError_FATAL(1138);
- }
- }
- }
- }
-}
-
-static void scancase(DeclThing *thing) {
- SwitchCase *swcase;
- Statement *stmt;
- CInt64 min;
- CInt64 max;
-
- if (!thing->switchinfo) {
- CError_Error(CErrorStr169);
- return;
- }
-
- tk = lex();
- min = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr());
- if (!copts.ANSIstrict && tk == TK_ELLIPSIS) {
- tk = lex();
- max = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr());
- if (CInt64_Greater(min, max))
- CError_Error(CErrorStr366);
- if (thing->switchinfo->x8->size == stsignedlonglong.size)
- CError_Error(CErrorStr368);
- } else {
- max = min;
- }
-
- for (swcase = thing->switchinfo->cases; swcase; swcase = swcase->next) {
- if (CInt64_GreaterEqual(swcase->min, min) && CInt64_LessEqual(swcase->min, max))
- CError_Error(CErrorStr172);
- if (CInt64_GreaterEqual(swcase->max, min) && CInt64_LessEqual(swcase->max, max))
- CError_Error(CErrorStr172);
- if (CInt64_Less(swcase->min, min) && CInt64_Greater(swcase->max, max))
- CError_Error(CErrorStr172);
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
-
- swcase = lalloc(sizeof(SwitchCase));
- swcase->min = min;
- swcase->label = stmt->label;
- swcase->next = thing->switchinfo->cases;
- thing->switchinfo->cases = swcase;
- swcase->max = max;
-
- if (tk != ':')
- CError_ErrorSkip(CErrorStr170);
- else
- tk = lex();
-
- statement(thing);
-}
-
-static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) {
- char buf[64];
- HashNameNode *name;
-
- if (!(cscope_currentfunc && (cscope_currentfunc->qual & Q_INLINE)) || CParser_HasInternalLinkage(cscope_currentfunc)) {
- obj->name = CParser_AppendUniqueName(str);
- } else {
- sprintf(buf, "$localstatic%" PRId32 "$", cfunc_staticvarcount++);
- name = CMangler_GetLinkName(cscope_currentfunc);
- name = CParser_NameConcat(buf, name->name);
- name = CParser_NameConcat(str, name->name);
- obj->name = name;
- obj->qual |= Q_20000;
- obj->sclass = 0;
- }
-}
-
-static void sinit_insert_expr(ENode *expr) {
- Statement *stmt;
-
- if (!sinit_first_object) {
- sinit_first_object = CParser_NewCompilerDefDataObject();
- sinit_first_object->type = TYPE(&stsignedchar);
- sinit_first_object->sclass = TK_STATIC;
- CFunc_NameLocalStaticDataObject(sinit_first_object, "init");
- CInit_DeclareData(sinit_first_object, NULL, NULL, sinit_first_object->type->size);
-
- sinit_label = newlabel();
- stmt = CFunc_AppendStatement(ST_IFGOTO);
- stmt->expr = create_objectnode(sinit_first_object);
- stmt->label = sinit_label;
- }
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
-}
-
-static void ainit_insert_expr(ENode *expr) {
- Statement *stmt;
-
- if (ainit_only_one) {
- if (ainit_expr) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = ainit_expr;
- }
- ainit_expr = expr;
- } else {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
- }
-}
-
-static ENode *ainit_register_object(Type *type, Object *local, SInt32 offset, Boolean flag) {
- return CExcept_RegisterDestructorObject(local, offset, CClass_Destructor(TYPE_CLASS(type)), flag);
-}
-
-static void CFunc_LocalDataDeclarator(DeclInfo *di, TStreamElement *deftoken, Boolean flag1, Boolean flag2) {
- Object *object;
- Object *aliasObject;
- NameSpace *globalNS;
- NameSpaceObjectList *nsol;
- NameSpaceName *nsname;
- Statement *stmt;
-
- if (di->nspace)
- CError_Error(CErrorStr121);
-
- CDecl_CompleteType(di->thetype);
-
- object = NULL;
-
- if ((nsol = CScope_FindName(cscope_current, di->name))) {
- switch (nsol->object->otype) {
- case OT_OBJECT:
- object = OBJECT(nsol->object);
- break;
- case OT_NAMESPACE:
- CError_Error(CErrorStr321);
- return;
- case OT_ENUMCONST:
- case OT_TYPE:
- CError_Error(CErrorStr322);
- break;
- case OT_TYPETAG:
- break;
- default:
- CError_FATAL(1344);
- }
- }
-
- if (object)
- CError_Error(CErrorStr333, object);
-
- if (di->storageclass == TK_EXTERN) {
- object = NULL;
- globalNS = CScope_FindGlobalNS(cscope_current);
- if ((nsol = CScope_FindName(globalNS, di->name))) {
- switch (nsol->object->otype) {
- case OT_OBJECT:
- object = OBJECT(nsol->object);
- break;
- case OT_NAMESPACE:
- CError_Error(CErrorStr321);
- return;
- case OT_ENUMCONST:
- case OT_TYPE:
- CError_Error(CErrorStr322);
- break;
- case OT_TYPETAG:
- break;
- default:
- CError_FATAL(1381);
- }
- }
-
- if (object) {
- if (
- !is_typesame(di->thetype, object->type) ||
- (di->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK)) != (object->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK))
- )
- {
- CError_Error(CErrorStr249, di->name->name, object->type, object->qual, di->thetype, di->qual);
- }
- } else {
- object = CParser_NewGlobalDataObject(di);
- object->nspace = globalNS;
- }
-
- CParser_NewAliasObject(object, 0);
- return;
- }
-
- if (di->storageclass != TK_STATIC)
- object = CParser_NewObject(di);
- else
- object = CParser_NewGlobalDataObject(di);
-
- object->name = di->name;
- object->type = di->thetype;
- object->qual = di->qual;
- object->sclass = di->storageclass;
-
- switch (di->storageclass) {
- case TK_STATIC:
- if (flag1) {
- CError_Error(CErrorStr177);
- return;
- }
- if (flag2)
- CError_Error(CErrorStr174);
-
- if (CanCreateObject(di->thetype)) {
- CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_WEAK | Q_ALIGNED_MASK));
- CParser_NewAliasObject(object, 0);
- object->nspace = cscope_root;
- object->datatype = DDATA;
- CFunc_NameLocalStaticDataObject(object, object->name->name);
-
- if (copts.cplusplus) {
- sinit_first_object = NULL;
- CInit_InitializeStaticData(object, sinit_insert_expr);
- if (sinit_first_object) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(
- create_objectnode(sinit_first_object),
- intconstnode(TYPE(&stsignedchar), 1),
- EASS);
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = sinit_label;
- sinit_label->stmt = stmt;
- }
- } else {
- CInit_InitializeData(object);
- }
- }
- break;
-
- case 0:
- case TK_AUTO:
- case TK_REGISTER:
- if (CanCreateObject(di->thetype)) {
- CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK));
- object->datatype = DLOCAL;
- CFunc_SetupLocalVarInfo(object);
-
- object->u.var.info->deftoken = *deftoken;
- if (object->sclass == TK_REGISTER && flag1)
- object->u.var.info->usage = 100;
-
- CScope_AddObject(cscope_current, object->name, OBJ_BASE(object));
-
- if (!flag1) {
- if (IS_TYPE_SOM_CLASS(di->thetype)) {
- CSOM_InitAutoClass(object);
- } else {
- CInit_InitializeAutoData(object, ainit_insert_expr, ainit_register_object);
- if (object->type != di->thetype && (IS_TYPE_STRUCT(object->type) || IS_TYPE_CLASS(object->type))) {
- CError_ASSERT(1478, !cscope_current->is_hash);
- CError_ASSERT(1479, nsname = CScope_FindNameSpaceName(cscope_current, object->name));
- CError_ASSERT(1480, nsname->first.object == OBJ_BASE(object));
- CError_ASSERT(1481, !nsname->first.next);
- nsname->name = CParser_AppendUniqueName(object->name->name);
-
- aliasObject = CParser_NewAliasObject(object, 0);
- aliasObject->type = di->thetype;
- }
- }
- }
-
- if (object->datatype == DLOCAL) {
- ObjectList *list = lalloc(sizeof(ObjectList));
- list->object = object;
- list->next = locals;
- locals = list;
- }
-
- IsCompleteType(di->thetype);
- }
- break;
-
- default:
- CError_FATAL(1504);
- }
-}
-
-static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) {
- Type *type;
- UInt32 qual;
- DeclInfo di;
- TStreamElement deftoken;
-
- ainit_expr = NULL;
- ainit_only_one = flag2;
-
- while (flag2 || isdeclaration(copts.cplusplus, 0, 0, 0)) {
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
-
- memclrw(&di, sizeof(di));
- di.is_extern_c = cfunc_is_extern_c;
- CParser_GetDeclSpecs(&di, 0);
-
- if (IS_TYPE_TEMPLATE(di.thetype)) {
- CError_Error(CErrorStr146);
- di.thetype = TYPE(&stsignedint);
- }
-
- type = di.thetype;
- qual = di.qual;
-
- if (tk != ';') {
- while (1) {
- deftoken = *CPrep_CurStreamElement();
- di.name = NULL;
- scandeclarator(&di);
-
- if (di.name) {
- if (di.storageclass != TK_TYPEDEF) {
- if (IS_TYPE_FUNC(di.thetype)) {
- if (!CDecl_FunctionDeclarator(&di, CScope_FindGlobalNS(cscope_current), 0, 0))
- break;
- } else {
- CFunc_LocalDataDeclarator(&di, &deftoken, flag1, flag2);
- }
- } else {
- CDecl_TypedefDeclarator(&di);
- }
- } else {
- CError_Error(CErrorStr134);
- }
-
- if (tk == ';')
- break;
-
- if (tk != ',') {
- if (!flag2)
- CError_Error(CErrorStr123);
- break;
- }
-
- di.nspace = NULL;
- di.thetype = type;
- di.qual = qual;
- tk = lex();
- }
- } else {
- CParser_CheckAnonymousUnion(&di, 1);
- }
-
- if (flag2)
- break;
- if (flag4)
- break;
- tk = lex();
- }
-
- if (flag2) {
- if (!ainit_expr) {
- if (!flag3) {
- CError_Error(CErrorStr141);
- ainit_expr = nullnode();
- }
- } else {
- ainit_expr = checkreference(ainit_expr);
- }
- }
-
- return ainit_expr;
-}
-
-static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) {
- Statement *stmt;
- CLabel *tmplabel;
-
- if (!expr) {
- if (flag1) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- stmt->label = label1;
- return;
- }
- return;
- }
-
- if (
- ENODE_IS(expr, ETYPCON) &&
- IS_TYPE_INT(expr->rtype) &&
- IS_TYPE_INT(expr->data.monadic->rtype) &&
- expr->rtype->size >= expr->data.monadic->rtype->size
- )
- expr = expr->data.monadic;
-
- if (isnotzero(expr)) {
- if (flag1) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- stmt->label = label1;
- return;
- }
- return;
- }
-
- if (iszero(expr)) {
- if (!flag1) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- stmt->label = label1;
- return;
- }
- return;
- }
-
- if (ENODE_IS(expr, ELOGNOT)) {
- makeifstatement(expr->data.monadic, label1, label2, !flag1, flag2);
- return;
- }
-
- if (ENODE_IS(expr, ELOR)) {
- tmplabel = newlabel();
- if (flag1) {
- makeifstatement(expr->data.diadic.left, label1, tmplabel, 1, flag2);
- tmplabel->stmt = CFunc_AppendStatement(ST_LABEL);
- tmplabel->stmt->label = tmplabel;
- makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2);
- return;
- } else {
- makeifstatement(expr->data.diadic.left, label2, tmplabel, 1, flag2);
- tmplabel->stmt = CFunc_AppendStatement(ST_LABEL);
- tmplabel->stmt->label = tmplabel;
- makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2);
- return;
- }
- }
-
- if (ENODE_IS(expr, ELAND)) {
- tmplabel = newlabel();
- if (flag1) {
- makeifstatement(expr->data.diadic.left, label2, tmplabel, 0, flag2);
- tmplabel->stmt = CFunc_AppendStatement(ST_LABEL);
- tmplabel->stmt->label = tmplabel;
- makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2);
- return;
- } else {
- makeifstatement(expr->data.diadic.left, label1, tmplabel, 0, flag2);
- tmplabel->stmt = CFunc_AppendStatement(ST_LABEL);
- tmplabel->stmt->label = tmplabel;
- makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2);
- return;
- }
- }
-
- stmt = CFunc_AppendStatement(ST_IFGOTO);
- stmt->label = label1;
- stmt->expr = expr;
- if (!flag1)
- stmt->type = ST_IFNGOTO;
- if (flag2)
- stmt->flags = stmt->flags | StmtFlag_4;
-}
-
-static void CFunc_HasDtorTempCallBack(ENode *expr) {
- if (expr->data.temp.needs_dtor || expr->data.temp.uniqueid)
- cfunc_hasdtortemp = 1;
-}
-
-static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) {
- Statement *stmt;
- CLabel *tmplabel;
-
- if (expr && copts.cplusplus && copts.exceptions) {
- cfunc_hasdtortemp = 0;
- CExpr_SearchExprTree(expr, CFunc_HasDtorTempCallBack, 1, ETEMP);
- if (cfunc_hasdtortemp) {
- stmt = CFunc_AppendStatement(flag1 ? ST_IFGOTO : ST_IFNGOTO);
- stmt->label = label;
- stmt->expr = expr;
- if (flag2)
- stmt->flags = stmt->flags | StmtFlag_4;
- return;
- }
- }
-
- tmplabel = newlabel();
- makeifstatement(expr, label, tmplabel, flag1, flag2);
- tmplabel->stmt = CFunc_AppendStatement(ST_LABEL);
- tmplabel->stmt->label = tmplabel;
-}
-
-Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *lowerBound, ENode *upperBound, ENode *increment1, ENode *increment2, ENode *(*callback)(ENode *, ENode *)) {
- ENode *var1;
- ENode *var2;
- CLabel *label;
- ENode *ind;
- ENode *ind2;
- Statement *s;
-
- var1 = CExpr_NewETEMPNode(type, 1);
- ind = lalloc(sizeof(ENode));
- *ind = *var1;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- // initialise var1 to lowerBound
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_EXPRESSION);
- }
- s->expr = makediadicnode(ind, lowerBound, EASS);
-
- if (increment2) {
- var2 = CExpr_NewETEMPNode(type, 1);
- ind = lalloc(sizeof(ENode));
- *ind = *var2;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- // initialise var2 to upperBound
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_EXPRESSION);
- }
- s->expr = makediadicnode(ind, upperBound, EASS);
- }
-
- // label for loop body
- label = newlabel();
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_LABEL, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_LABEL);
- }
- s->label = label;
- label->stmt = s;
-
- if (callback) {
- ind = lalloc(sizeof(ENode));
- *ind = *var1;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- if (increment2) {
- ind2 = lalloc(sizeof(ENode));
- *ind2 = *var2;
- ind2 = makemonadicnode(ind2, EINDIRECT);
- ind2->rtype = type;
- } else {
- ind2 = NULL;
- }
-
- // generate a loop body
- if ((ind = callback(ind, ind2))) {
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_EXPRESSION);
- }
- s->expr = ind;
- }
- }
-
- if (increment1) {
- ind = lalloc(sizeof(ENode));
- *ind = *var1;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- // add increment1 to var1
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_EXPRESSION);
- }
- s->expr = makediadicnode(ind, increment1, EADDASS);
-
- if (increment2) {
- ind = lalloc(sizeof(ENode));
- *ind = *var2;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- // add increment2 to var2
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_EXPRESSION);
- }
- s->expr = makediadicnode(ind, increment2, EADDASS);
- }
- }
-
- ind = lalloc(sizeof(ENode));
- *ind = *var1;
- ind = makemonadicnode(ind, EINDIRECT);
- ind->rtype = type;
-
- // loop if var1 < upperBound
- if (stmt) {
- stmt = CFunc_InsertStatement(ST_IFGOTO, stmt);
- s = stmt;
- } else {
- s = CFunc_AppendStatement(ST_IFGOTO);
- }
- s->expr = makediadicnode(ind, upperBound, ELESS);
- s->expr->rtype = TYPE(&stbool);
- s->label = label;
- s->flags = StmtFlag_4;
-
- return stmt;
-}
-
-static Boolean checklabel(void) {
- HashNameNode *savename;
- short savesize;
- short token;
-
- savename = tkidentifier;
- savesize = tksize;
- token = lookahead();
- tkidentifier = savename;
- tksize = savesize;
-
- return token == ':';
-}
-
-static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) {
- Object *object;
- ENode *expr2;
- ENode *objexpr;
- ObjectList *list;
- ENodeList *exprlist;
-
- for (list = arguments; list; list = list->next) {
- if (list->object->name == temp_argument_name)
- break;
- }
-
- CError_ASSERT(1907, list);
-
- object = list->object;
- if ((expr2 = CExpr_IsTempConstruction(expr, type, &objexpr)) && ENODE_IS(objexpr, ETEMP)) {
- *objexpr = *create_objectnode(object);
- return expr2;
- }
-
- if (IS_TYPE_CLASS(type)) {
- expr2 = create_objectnode(object);
- exprlist = lalloc(sizeof(ENodeList));
- exprlist->next = NULL;
- exprlist->node = expr;
- return CExpr_ConstructObject(TYPE_CLASS(type), expr2, exprlist, 1, 1, 0, 1, 0);
- }
-
- expr2 = create_objectnode(object);
- expr2 = makemonadicnode(expr2, EINDIRECT);
- expr2->rtype = type;
-
- return makediadicnode(expr2, CExpr_AssignmentPromotion(expr, type, qual, 1), EASS);
-}
-
-static void CFunc_AutoResultCheck(ENode *expr) {
- while (1) {
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.right;
-
- switch (expr->type) {
- case EOBJREF:
- if (expr->data.objref->datatype != DLOCAL)
- break;
- case ETEMP:
- CError_Warning(CErrorStr326);
- break;
- case EADD:
- case ESUB:
- CFunc_AutoResultCheck(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- continue;
- default:
- break;
- }
- break;
- }
-}
-
-static void statement(DeclThing *thing) {
- Statement *stmt;
- Statement *stmt2;
- CLabel *label;
- DeclBlock *block;
- ENode *expr;
- HashNameNode *name;
- DeclThing subthing;
-
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
-
- switch (tk) {
- case TK_RETURN:
- tk = lex();
- if (
- (thing->thetype == &stvoid && !copts.cplusplus) ||
- CClass_IsConstructor(cscope_currentfunc) ||
- CClass_IsDestructor(cscope_currentfunc)
- )
- {
- if (tk != ';') {
- CError_Error(CErrorStr315);
- expression();
- }
-
- stmt = CFunc_AppendStatement(ST_RETURN);
- stmt->expr = NULL;
- CError_ResetErrorSkip();
- tk = lex();
- return;
- }
-
- if (tk == ';') {
- if (thing->thetype != &stvoid && (copts.pedantic || copts.cplusplus))
- CError_Warning(CErrorStr184);
-
- stmt = CFunc_AppendStatement(ST_RETURN);
- stmt->expr = NULL;
- CError_ResetErrorSkip();
- tk = lex();
- return;
- }
-
- if (copts.old_argmatch)
- expr = expression();
- else
- expr = s_expression();
-
- if (thing->thetype == &stvoid) {
- if (expr->rtype != &stvoid)
- CError_Error(CErrorStr315);
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
-
- stmt = CFunc_AppendStatement(ST_RETURN);
- stmt->expr = NULL;
- } else {
- if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) == 1)
- expr = returnstatementadjust(expr, thing->thetype, thing->qual);
- else
- expr = CExpr_AssignmentPromotion(expr, thing->thetype, thing->qual, 1);
-
- stmt = CFunc_AppendStatement(ST_RETURN);
- stmt->expr = expr;
-
- if (IS_TYPE_POINTER_ONLY(thing->thetype))
- CFunc_AutoResultCheck(expr);
- }
-
- break;
-
- case TK_CASE:
- scancase(thing);
- return;
-
- case TK_DEFAULT:
- if (!thing->switchinfo) {
- CError_Error(CErrorStr169);
- return;
- }
-
- if (lex() != ':')
- CError_ErrorSkip(CErrorStr170);
- else
- tk = lex();
-
- if (thing->switchinfo->defaultlabel)
- CError_ErrorSkip(CErrorStr173);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = newlabel();
- stmt->label->stmt = stmt;
- thing->switchinfo->defaultlabel = stmt->label;
- statement(thing);
- return;
-
- case TK_SWITCH:
- if (lex() != '(')
- CError_ErrorSkip(CErrorStr114);
- else
- tk = lex();
-
- if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) {
- block = CFunc_NewDeclBlock();
- expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0);
- if (CScope_IsEmptyNameSpace(cscope_current)) {
- CFunc_RestoreBlock(block);
- block = NULL;
- }
- } else {
- expr = expression();
- block = NULL;
- }
-
- stmt = CFunc_AppendStatement(ST_SWITCH);
- stmt->expr = CExpr_ConvertToIntegral(expr);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- stmt->label = (CLabel *) lalloc(sizeof(SwitchInfo));
- ((SwitchInfo *) stmt->label)->defaultlabel = NULL;
- ((SwitchInfo *) stmt->label)->cases = NULL;
- ((SwitchInfo *) stmt->label)->x8 = stmt->expr->rtype;
-
- label = newlabel();
- subthing = *thing;
- subthing.loopBreak = label;
- subthing.switchinfo = (SwitchInfo *) stmt->label;
- CFunc_CompoundStatement(&subthing);
-
- if (!subthing.switchinfo->defaultlabel)
- subthing.switchinfo->defaultlabel = label;
-
- if (!subthing.switchinfo->cases) {
- stmt->type = ST_EXPRESSION;
- stmt2 = lalloc(sizeof(Statement));
- *stmt2 = *stmt;
- stmt->next = stmt2;
- stmt2->type = ST_GOTO;
- stmt2->label = subthing.switchinfo->defaultlabel;
- stmt2->dobjstack = cexcept_dobjstack;
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- if (block)
- CFunc_RestoreBlock(block);
- return;
-
- case TK_GOTO:
- if ((tk = lex()) != TK_IDENTIFIER) {
- if (tk == '*' && !copts.ANSIstrict) {
- tk = lex();
- stmt = CFunc_AppendStatement(ST_GOTOEXPR);
- stmt->expr = expression();
- if (!IS_TYPE_POINTER_ONLY(stmt->expr->rtype)) {
- CError_Error(CErrorStr146);
- stmt->expr = nullnode();
- stmt->expr->rtype = TYPE(&void_ptr);
- }
- } else {
- CError_Error(CErrorStr107);
- return;
- }
- } else {
- stmt = CFunc_AppendStatement(ST_GOTO);
- if (!(stmt->label = findlabel())) {
- stmt->label = newlabel();
- stmt->label->next = Labels;
- Labels = stmt->label;
- stmt->label->name = tkidentifier;
- }
- tk = lex();
- }
- break;
-
- case TK_BREAK:
- if (thing->loopBreak) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- stmt->label = thing->loopBreak;
- } else {
- CError_Error(CErrorStr169);
- }
- tk = lex();
- break;
-
- case TK_CONTINUE:
- if (thing->loopContinue) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- stmt->label = thing->loopContinue;
- } else {
- CError_Error(CErrorStr169);
- }
- tk = lex();
- break;
-
- case TK_FOR: {
- CLabel *forLabel1;
- CLabel *forLabel2;
- CLabel *forLabel3;
- ENode *forCond;
- ENode *forInc;
-
- if (lex() != '(')
- CError_ErrorSkip(CErrorStr114);
- else
- tk = lex();
-
- block = NULL;
- if (tk != ';') {
- if (!copts.cplusplus || !isdeclaration(1, 0, 0, 0)) {
- expr = expression();
- CExpr_CheckUnusedExpression(expr);
- } else {
- if (!copts.ARMscoping)
- block = CFunc_NewDeclBlock();
- expr = CFunc_ParseLocalDeclarationList(0, 1, 1, 0);
- if (block && CScope_IsEmptyNameSpace(cscope_current)) {
- CFunc_RestoreBlock(block);
- block = NULL;
- }
- }
-
- if (expr) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
- }
-
- if (tk == ';')
- CError_ResetErrorSkip();
- else
- CError_Error(CErrorStr123);
- } else {
- CError_ResetErrorSkip();
- }
-
- if ((tk = lex()) != ';') {
- if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) {
- if (!block)
- block = CFunc_NewDeclBlock();
- expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0);
- if (CScope_IsEmptyNameSpace(cscope_current)) {
- CFunc_RestoreBlock(block);
- block = NULL;
- }
- } else {
- expr = expression();
- CExpr_CheckUnwantedAssignment(expr);
- }
-
- forCond = CExpr_ConvertToCondition(expr);
-
- if (tk == ';')
- CError_ResetErrorSkip();
- else
- CError_Error(CErrorStr123);
- } else {
- CError_ResetErrorSkip();
- forCond = NULL;
- }
-
- if ((tk = lex()) != ')') {
- forInc = expression();
- CExpr_CheckUnusedExpression(forInc);
- if (tk == ')')
- CError_ResetErrorSkip();
- else
- CError_Error(CErrorStr115);
- } else {
- CError_ResetErrorSkip();
- forInc = NULL;
- }
-
- if (copts.warn_possunwant) {
- spaceskip = 0;
- if ((tk = lex()) == ';' && !spaceskip)
- CError_Warning(CErrorStr206);
- } else {
- tk = lex();
- }
-
- if (forCond) {
- stmt = CFunc_AppendStatement(ST_GOTO);
- label = newlabel();
- stmt->label = label;
- } else {
- label = newlabel();
- }
-
- CFunc_LoopIncrement();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- forLabel1 = stmt->label = newlabel();
- forLabel1->stmt = stmt;
-
- forLabel2 = newlabel();
- forLabel3 = newlabel();
-
- subthing = *thing;
- subthing.loopContinue = forLabel3;
- subthing.loopBreak = forLabel2;
-
- if (tk != '{') {
- DeclBlock *b = CFunc_NewDeclBlock();
- CFunc_CompoundStatement(&subthing);
- CFunc_RestoreBlock(b);
- } else {
- CFunc_CompoundStatement(&subthing);
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = forLabel3;
- forLabel3->stmt = stmt;
-
- if (forInc) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = forInc;
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- ifstatement(1, forCond, forLabel1, 1);
- CFunc_LoopDecrement();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = forLabel2;
- forLabel2->stmt = stmt;
-
- if (block)
- CFunc_RestoreBlock(block);
-
- return;
- }
-
- case TK_DO: {
- CLabel *label1;
- CLabel *label2;
- CLabel *label3;
-
- CFunc_LoopIncrement();
- stmt = CFunc_AppendStatement(ST_LABEL);
- label1 = stmt->label = newlabel();
- label1->stmt = stmt;
-
- label2 = newlabel();
- label3 = newlabel();
-
- subthing = *thing;
- subthing.loopContinue = label2;
- subthing.loopBreak = label3;
-
- tk = lex();
- CFunc_CompoundStatement(&subthing);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label2;
- label2->stmt = stmt;
-
- if (tk != TK_WHILE)
- CError_Error(CErrorStr105);
-
- if (lex() != '(')
- CError_ErrorSkip(CErrorStr114);
- else
- tk = lex();
-
- expr = CExpr_ConvertToCondition(expression());
- CExpr_CheckUnwantedAssignment(expr);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- ifstatement(1, expr, label1, 1);
-
- CFunc_LoopDecrement();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label3;
- label3->stmt = stmt;
- break;
- }
-
- case TK_WHILE: {
- CLabel *label1;
- CLabel *label2;
- CLabel *label3;
-
- if ((tk = lex()) != '(')
- CError_ErrorSkip(CErrorStr114);
- else
- tk = lex();
-
- if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) {
- block = CFunc_NewDeclBlock();
- expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0);
- if (CScope_IsEmptyNameSpace(cscope_current)) {
- CFunc_RestoreBlock(block);
- block = NULL;
- }
- } else {
- expr = expression();
- block = NULL;
- CExpr_CheckUnwantedAssignment(expr);
- }
- expr = CExpr_ConvertToCondition(expr);
-
- if (tk != ')') {
- CError_ErrorSkip(CErrorStr115);
- } else {
- if (copts.warn_possunwant) {
- spaceskip = 0;
- if ((tk = lex()) == ';' && !spaceskip)
- CError_Warning(CErrorStr206);
- } else {
- tk = lex();
- }
- }
-
- stmt = CFunc_AppendStatement(ST_GOTO);
- label1 = newlabel();
- stmt->label = label1;
-
- CFunc_LoopIncrement();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- label2 = stmt->label = newlabel();
- label2->stmt = stmt;
-
- label3 = newlabel();
-
- subthing = *thing;
- subthing.loopContinue = label1;
- subthing.loopBreak = label3;
-
- CFunc_CompoundStatement(&subthing);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label1;
- label1->stmt = stmt;
-
- ifstatement(1, expr, label2, 1);
-
- CFunc_LoopDecrement();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label3;
- label3->stmt = stmt;
-
- if (block)
- CFunc_RestoreBlock(block);
- return;
- }
-
- case TK_IF: {
- CLabel *label1;
- if ((tk = lex()) != '(')
- CError_ErrorSkip(CErrorStr114);
- else
- tk = lex();
-
- if (copts.cplusplus && !copts.ARMscoping && isdeclaration(1, 0, 0, '=')) {
- block = CFunc_NewDeclBlock();
- expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0);
- if (CScope_IsEmptyNameSpace(cscope_current)) {
- CFunc_RestoreBlock(block);
- block = NULL;
- }
- } else {
- expr = expression();
- block = NULL;
- CExpr_CheckUnwantedAssignment(expr);
- }
-
- expr = CExpr_ConvertToCondition(expr);
-
- label1 = newlabel();
- ifstatement(0, expr, label1, 0);
-
- if (tk != ')') {
- CError_ErrorSkip(CErrorStr115);
- } else {
- if (copts.warn_possunwant) {
- spaceskip = 0;
- if ((tk = lex()) == ';' && !spaceskip)
- CError_Warning(CErrorStr206);
- } else {
- tk = lex();
- }
- }
-
- CFunc_CompoundStatement(thing);
-
- if (tk == TK_ELSE) {
- if (copts.warn_possunwant) {
- spaceskip = 0;
- if ((tk = lex()) == ';' && !spaceskip)
- CError_Warning(CErrorStr206);
- } else {
- tk = lex();
- }
-
- stmt = CFunc_AppendStatement(ST_GOTO);
- label = stmt->label = newlabel();
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label1;
- label1->stmt = stmt;
-
- CFunc_CompoundStatement(thing);
-
- label1 = label;
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label1;
- label1->stmt = stmt;
-
- if (block)
- CFunc_RestoreBlock(block);
-
- return;
- }
-
- case '{':
- CFunc_CompoundStatement(thing);
- return;
-
- case TK_ASM:
- if (copts.cplusplus || !copts.ANSIstrict) {
- tk = lex();
- volatileasm = 0;
-
- if (tk == TK_VOLATILE || (tk == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__volatile__"))) {
- tk = lex();
- volatileasm = 1;
- }
-
- if (tk == '(') {
- InlineAsm_Assemble();
- if (tk == ')') {
- tk = lex();
- break;
- } else {
- CError_Error(CErrorStr115);
- return;
- }
- }
-
- if (tk == '{') {
- InlineAsm_Assemble();
- if (tk != '}') {
- CError_Error(CErrorStr130);
- return;
- }
- if ((tk = lex()) == ';')
- tk = lex();
- CError_ResetErrorSkip();
- return;
- }
-
- CError_Error(CErrorStr114);
- } else {
- CError_Error(CErrorStr121);
- }
- return;
-
- case TK_TRY:
- tk = lex();
- CExcept_ScanTryBlock(thing, 0);
- return;
-
- case TK_USING:
- if ((tk = lex()) == TK_NAMESPACE) {
- tk = lex();
- CScope_ParseUsingDirective(cscope_current);
- } else {
- CScope_ParseUsingDeclaration(cscope_current, 0, 0);
- }
- return;
-
- case TK_NAMESPACE:
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return;
- }
- name = tkidentifier;
- if ((tk = lex()) != '=') {
- CError_Error(CErrorStr121);
- return;
- }
-
- CScope_ParseNameSpaceAlias(name);
- break;
-
- case ';':
- break;
-
- case TK_IDENTIFIER:
- if (checklabel()) {
- stmt = CFunc_AppendStatement(ST_LABEL);
- if ((stmt->label = findlabel())) {
- if (stmt->label->stmt)
- CError_Error(CErrorStr171, tkidentifier->name);
- } else {
- stmt->label = newlabel();
- stmt->label->next = Labels;
- Labels = stmt->label;
- stmt->label->name = tkidentifier;
- }
-
- stmt->label->stmt = stmt;
- tk = lex();
- tk = lex();
- statement(thing);
- return;
- }
- tk = TK_IDENTIFIER;
-
- default:
- if (copts.cplusplus && isdeclaration(1, 0, 0, 0)) {
- CFunc_ParseLocalDeclarationList(0, 0, 0, 1);
- tk = lex();
- return;
- }
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expression();
- CExpr_CheckUnusedExpression(stmt->expr);
- }
-
- if (tk == ';') {
- CPrep_TokenStreamFlush();
- tk = lex();
- CError_ResetErrorSkip();
- } else {
- CError_ErrorSkip(CErrorStr123);
- }
-}
-
-void CFunc_CompoundStatement(DeclThing *thing) {
- DeclBlock *block;
-
- block = CFunc_NewDeclBlock();
-
- if (tk == '{') {
- tk = lex();
- if (!copts.cplusplus && isdeclaration(0, 0, 0, 0))
- CFunc_ParseLocalDeclarationList(0, 0, 0, 0);
-
- while (tk != '}')
- statement(thing);
-
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
- tk = lex();
- } else {
- statement(thing);
- }
-
- CFunc_RestoreBlock(block);
-}
-
-static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) {
- Object *newobj;
- Statement *stmt;
- ENode *expr;
- NameSpaceObjectList *nsol;
- ObjectList *list;
-
- newobj = lalloc(sizeof(Object));
- *newobj = *obj;
- newobj->type = type2;
-
- CFunc_SetupLocalVarInfo(newobj);
-
- obj->name = CParser_GetUniqueName();
- if (flag)
- obj->type = CDecl_NewPointerType(type1);
- else
- obj->type = type1;
-
- CError_ASSERT(2527, (nsol = CScope_FindName(cscope_current, newobj->name)) && nsol->object == OBJ_BASE(obj));
- nsol->object = OBJ_BASE(newobj);
-
- list = lalloc(sizeof(ObjectList));
- list->object = newobj;
- list->next = locals;
- locals = list;
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- expr = create_objectnode(obj);
- if (flag) {
- expr->rtype = CDecl_NewPointerType(type1);
- expr = makemonadicnode(expr, EINDIRECT);
- }
- expr->rtype = type1;
-
- if (type1 != type2)
- expr = promote(expr, type2);
-
- stmt->expr = makediadicnode(create_objectnode(newobj), expr, EASS);
-}
-
-static void CFunc_AdjustOldStyleArgs(void) {
- ObjectList *list;
-
- for (list = arguments; list; list = list->next) {
- if (IS_TYPE_FLOAT(list->object->type) && list->object->type->size < stdouble.size)
- CFunc_InsertArgumentCopyConversion(list->object, TYPE(&stdouble), list->object->type, 0);
- }
-}
-
-void CFunc_SetupNewFuncArgs(Object *func, FuncArg *args) {
- Object *obj;
- ObjectList *newlist;
-
- arguments = NULL;
-
- if (args != &elipsis && args != &oldstyle) {
- newlist = NULL;
-
- while (args && args != &elipsis) {
- IsCompleteType(args->type);
-
- obj = CParser_NewLocalDataObject(NULL, 0);
- obj->name = !args->name ? no_name_node : args->name;
- obj->type = args->type;
- obj->qual = args->qual;
- obj->sclass = args->sclass;
-
- CFunc_SetupLocalVarInfo(obj);
-
- if (IS_TYPE_CLASS(obj->type) && CClass_ReferenceArgument(TYPE_CLASS(obj->type))) {
- obj->type = CDecl_NewPointerType(obj->type);
- TPTR_QUAL(obj->type) = Q_REFERENCE | Q_RESTRICT;
- }
-
- if (obj->name == no_name_node && copts.ANSIstrict && !copts.cplusplus && !(func->qual & Q_MANGLE_NAME))
- CError_Error(CErrorStr127);
-
- if (newlist) {
- newlist->next = lalloc(sizeof(ObjectList));
- newlist = newlist->next;
- } else {
- newlist = lalloc(sizeof(ObjectList));
- arguments = newlist;
- }
-
- newlist->next = NULL;
- newlist->object = obj;
-
- args = args->next;
- }
- }
-}
-
-static ObjectList *CFunc_CopyObjectList(const FuncArg *args) {
- Object *obj;
- ObjectList *list;
- ObjectList *last;
-
- list = NULL;
-
- while (args) {
- if (list) {
- last->next = lalloc(sizeof(ObjectList));
- last = last->next;
- } else {
- last = lalloc(sizeof(ObjectList));
- list = last;
- }
-
- obj = CParser_NewLocalDataObject(NULL, 0);
- obj->name = args->name;
- obj->type = args->type;
- obj->qual = args->qual;
- obj->sclass = args->sclass;
- CFunc_SetupLocalVarInfo(obj);
-
- last->object = obj;
- last->next = NULL;
-
- args = args->next;
- }
-
- return list;
-}
-
-static void SetupFunctionArguments(Object *func, DeclInfo *di, Statement *firstStmt) {
- ObjectList *list;
- Object *resultobj;
- Object *obj;
- Type *type;
- DeclInfo my_di;
-
- if (TYPE_FUNC(func->type)->args) {
- if (di->x45) {
- arguments = CFunc_CopyObjectList(di->x18);
- while (1) {
- if (tk == '{')
- break;
-
- memclrw(&my_di, sizeof(my_di));
- CParser_GetDeclSpecs(&my_di, 0);
-
- type = my_di.thetype;
- if (my_di.storageclass && my_di.storageclass != TK_REGISTER)
- CError_Error(CErrorStr127);
-
- while (1) {
- my_di.thetype = type;
- my_di.name = NULL;
- scandeclarator(&my_di);
- if (!my_di.name) {
- CError_Error(CErrorStr107);
- break;
- }
-
- adjustargumenttype(&my_di);
- IsCompleteType(my_di.thetype);
-
- if ((obj = CFunc_IsInObjList(arguments, my_di.name))) {
- if (obj->type)
- CError_Error(CErrorStr333, obj);
- obj->type = my_di.thetype;
- obj->sclass = my_di.storageclass;
- obj->qual = my_di.qual;
- } else {
- CError_Error(CErrorStr127);
- }
-
- if (tk != ',')
- break;
- tk = lex();
- }
-
- if (tk != ';')
- CError_ErrorSkip(CErrorStr123);
- else
- tk = lex();
- }
-
- for (list = arguments; list; list = list->next) {
- if (!list->object->type)
- list->object->type = TYPE(&stsignedint);
- }
- } else {
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
- }
- }
-
- if (CMach_GetFunctionResultClass(TYPE_FUNC(func->type)) == 1) {
- resultobj = CParser_NewLocalDataObject(NULL, 0);
- resultobj->name = temp_argument_name;
- resultobj->type = CDecl_NewPointerType(TYPE_FUNC(func->type)->functype);
- CFunc_SetupLocalVarInfo(resultobj);
-
- list = lalloc(sizeof(ObjectList));
- list->object = resultobj;
- if (CABI_GetStructResultArgumentIndex(TYPE_FUNC(func->type))) {
- CError_ASSERT(2797, arguments);
- list->next = arguments->next;
- arguments->next = list;
- } else {
- list->next = arguments;
- arguments = list;
- }
- }
-
- for (list = arguments; list; list = list->next) {
- NameSpaceObjectList *nsol = CScope_InsertName(cscope_current, list->object->name);
- nsol->object = OBJ_BASE(list->object);
- }
-}
-
-NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func) {
- NameSpace *nspace;
- DeclBlock *block;
-
- nspace = CScope_NewListNameSpace(NULL, 0);
- nspace->parent = cscope_current;
- cscope_current = nspace;
-
- arguments = NULL;
- locals = NULL;
- Labels = NULL;
-
- localcount = 0;
- cfunc_staticvarcount = 0;
-
- CExcept_Setup();
-
- memclrw(stmt, sizeof(Statement));
- curstmt = stmt;
- stmt->type = ST_NOP;
- curstmtvalue = 1;
- stmt->value = 1;
-
- blockcount = 0;
- block = lalloc(sizeof(DeclBlock));
- memclrw(block, sizeof(DeclBlock));
- block->index = blockcount++;
- block->parent_nspace = cscope_current;
-
- firstblock = block;
- currentblock = block;
-
- return nspace;
-}
-
-CFuncSave *CFunc_GetGlobalCompilerState(void) {
- CFuncSave *state;
-
- if (!cscope_currentfunc && !cscope_currentclass && cscope_current == cscope_root)
- return NULL;
-
- locklheap();
- state = lalloc(sizeof(CFuncSave));
-
- CScope_SetNameSpaceScope(cscope_root, &state->scope);
-
- state->arguments = arguments;
- arguments = NULL;
-
- state->locals = locals;
- locals = NULL;
-
- state->labels = Labels;
- Labels = NULL;
-
- state->curstmt = curstmt;
- curstmt = NULL;
-
- state->firstblock = firstblock;
- firstblock = NULL;
-
- state->currentblock = currentblock;
- currentblock = NULL;
-
- state->cexcept_dobjstack = cexcept_dobjstack;
- cexcept_dobjstack = NULL;
-
- state->sinit_label = sinit_label;
- sinit_label = NULL;
-
- state->ainit_expr = ainit_expr;
- ainit_expr = NULL;
-
- state->ctor_chain = ctor_chain;
- ctor_chain = NULL;
-
- state->cinit_tempnodefunc = cinit_tempnodefunc;
- cinit_tempnodefunc = NULL;
-
- state->trychain = trychain;
- trychain = NULL;
-
- state->cparser_fileoffset = cparser_fileoffset;
- state->symdecltoken = symdecltoken;
-
- state->functionbodyoffset = functionbodyoffset;
- functionbodyoffset = 0;
-
- state->functionbodypath = functionbodypath;
- functionbodypath = NULL;
-
- state->symdecloffset = symdecloffset;
- symdecloffset = 0;
-
- state->symdeclend = symdeclend;
-
- state->sourceoffset = sourceoffset;
- sourceoffset = 0;
-
- state->sourcefilepath = sourcefilepath;
- sourcefilepath = NULL;
-
- state->curstmtvalue = curstmtvalue;
- curstmtvalue = 0;
-
- state->name_obj_check = name_obj_check;
- name_obj_check = NULL;
-
- state->check_arglist = check_arglist;
- check_arglist = NULL;
-
- state->blockcount = blockcount;
- blockcount = 0;
-
- state->localcount = localcount;
- localcount = 0;
-
- state->tk = tk;
- state->tkidentifier = tkidentifier;
-
- state->global_access = global_access;
-
- state->cexcept_hasdobjects = cexcept_hasdobjects;
- cexcept_hasdobjects = 0;
-
- state->sinit_first_object = sinit_first_object;
- sinit_first_object = NULL;
-
- state->ainit_only_one = ainit_only_one;
- ainit_only_one = 0;
-
- state->cfunc_is_extern_c = cfunc_is_extern_c;
- cfunc_is_extern_c = 0;
-
- state->temp_reference_init = temp_reference_init;
-
- return state;
-}
-
-void CFunc_SetGlobalCompilerState(CFuncSave *state) {
- if (state) {
- CScope_RestoreScope(&state->scope);
-
- arguments = state->arguments;
- locals = state->locals;
- Labels = state->labels;
- curstmt = state->curstmt;
- firstblock = state->firstblock;
- currentblock = state->currentblock;
- cexcept_dobjstack = state->cexcept_dobjstack;
- sinit_label = state->sinit_label;
- ainit_expr = state->ainit_expr;
- ctor_chain = state->ctor_chain;
- cinit_tempnodefunc = state->cinit_tempnodefunc;
- trychain = state->trychain;
- name_obj_check = state->name_obj_check;
- check_arglist = state->check_arglist;
- curstmtvalue = state->curstmtvalue;
- cparser_fileoffset = state->cparser_fileoffset;
- symdecltoken = state->symdecltoken;
- functionbodyoffset = state->functionbodyoffset;
- functionbodypath = state->functionbodypath;
- symdecloffset = state->symdecloffset;
- symdeclend = state->symdeclend;
- sourceoffset = state->sourceoffset;
- sourcefilepath = state->sourcefilepath;
- blockcount = state->blockcount;
- tk = state->tk;
- tkidentifier = state->tkidentifier;
- global_access = state->global_access;
- localcount = state->localcount;
- cexcept_hasdobjects = state->cexcept_hasdobjects;
- sinit_first_object = state->sinit_first_object;
- ainit_only_one = state->ainit_only_one;
- cfunc_is_extern_c = state->cfunc_is_extern_c;
- temp_reference_init = state->temp_reference_init;
-
- unlocklheap();
- }
-}
-
-void CFunc_Gen(Statement *stmt, Object *func, UInt8 unk) {
- Boolean flag;
- CI_FuncData packed;
-
- if ((TYPE_FUNC(func->type)->flags & FUNC_FLAGS_400000) && !anyerrors) {
- CInline_PackIFunctionData(&packed, stmt, func);
- flag = 1;
- } else {
- flag = 0;
- }
-
- CInline_GenFunc(stmt, func, unk);
-
- if (flag)
- CClass_DefineCovariantFuncs(func, &packed);
-}
-
-static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) {
- ObjMemberVar *ivar;
- CtorChain *scan;
-
- if (tclass->mode != CLASS_MODE_UNION) {
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (IS_TYPE_REFERENCE(ivar->type)) {
- for (scan = chain; scan; scan = scan->next) {
- if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar)
- break;
- }
-
- if (!scan)
- CError_Error(CErrorStr256, ivar->name->name);
- } else if (CParser_IsConst(ivar->type, ivar->qual)) {
- for (scan = chain; scan; scan = scan->next) {
- if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar)
- break;
- }
-
- if (!scan && !IS_TYPE_CLASS(ivar->type))
- CError_Error(CErrorStr255, ivar->name->name);
- }
- }
- }
-}
-
-void CFunc_CheckClassCtors(TypeClass *tclass) {
- CFunc_CheckCtorInitializer(tclass, NULL);
-}
-
-static void CFunc_ParseCtorInitializer(void) {
- CtorChain *chain;
- ENodeList *args;
- TypeClass *tclass;
- ObjMemberVar *ivar;
- ClassList *base;
- VClassList *vbase;
- ENode *expr;
- Type *origtype;
-
- ctor_chain = NULL;
-
- if (tk == ':') {
- do {
- tclass = NULL;
- switch ((tk = lex())) {
- case TK_IDENTIFIER:
- for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->name == tkidentifier && lookahead() == '(')
- goto do_ivar;
- }
- for (base = cscope_currentclass->bases; base; base = base->next) {
- if (base->base->classname == tkidentifier) {
- if (lookahead() == '(') {
- tclass = base->base;
- tk = lex();
- } else {
- tkidentifier = base->base->classname;
- }
- break;
- }
- }
- break;
-
- case TK_COLON_COLON:
- break;
-
- default:
- CError_Error(CErrorStr212);
- return;
- }
-
- if (!tclass)
- tclass = CClass_GetQualifiedClass();
-
- if (tclass) {
- for (vbase = cscope_currentclass->vbases; vbase; vbase = vbase->next) {
- if (vbase->base == tclass)
- break;
- }
-
- if (vbase) {
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_VBase && chain->u.vbase == vbase) {
- CError_Error(CErrorStr212);
- return;
- }
- }
-
- chain = lalloc(sizeof(CtorChain));
- chain->what = CtorChain_VBase;
- chain->u.vbase = vbase;
- } else {
- for (base = cscope_currentclass->bases; base; base = base->next) {
- if (base->base == tclass)
- break;
- }
-
- if (base) {
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_Base && chain->u.base == base) {
- CError_Error(CErrorStr212);
- return;
- }
- }
-
- chain = lalloc(sizeof(CtorChain));
- chain->what = CtorChain_Base;
- chain->u.base = base;
- } else {
- CError_Error(CErrorStr212);
- return;
- }
- }
- } else {
- for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->name == tkidentifier)
- break;
- }
-
- if (ivar) {
- do_ivar:
- for (chain = ctor_chain; chain; chain = chain->next) {
- if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar)
- CError_Error(CErrorStr212);
- }
-
- chain = lalloc(sizeof(CtorChain));
- chain->what = CtorChain_MemberVar;
- chain->u.membervar = ivar;
- } else {
- CError_Error(CErrorStr212);
- return;
- }
-
- tk = lex();
- }
-
- if (tk != '(') {
- CError_Error(CErrorStr114);
- return;
- }
-
- tk = lex();
- args = CExpr_ScanExpressionList(1);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return;
- }
-
- switch (chain->what) {
- case CtorChain_Base:
- expr = CABI_MakeThisExpr(NULL, chain->u.base->offset);
- chain->objexpr = CExpr_ConstructObject(chain->u.base->base, expr, args, 1, 0, 0, 0, 1);
- break;
- case CtorChain_VBase:
- expr = CABI_MakeThisExpr(chain->u.vbase->base, chain->u.vbase->offset);
- chain->objexpr = CExpr_ConstructObject(chain->u.vbase->base, expr, args, 1, 0, 0, 0, 1);
- break;
- case CtorChain_MemberVar:
- expr = CABI_MakeThisExpr(cscope_currentclass, chain->u.membervar->offset);
- expr->flags = chain->u.membervar->qual & ENODE_FLAG_QUALS;
- switch (chain->u.membervar->type->type) {
- case TYPECLASS:
- chain->objexpr = CExpr_ConstructObject(TYPE_CLASS(chain->u.membervar->type), expr, args, 1, 1, 0, 1, 1);
- break;
- case TYPEARRAY:
- if (args) {
- CError_Error(CErrorStr212);
- continue;
- }
- chain->objexpr = NULL;
- break;
- default:
- if (!args) {
- args = lalloc(sizeof(ENodeList));
- args->next = NULL;
- args->node = CExpr_DoExplicitConversion(chain->u.membervar->type, chain->u.membervar->qual, NULL);
- }
- if (args->next) {
- CError_Error(CErrorStr212);
- return;
- }
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = chain->u.membervar->type;
- if (IS_TYPE_BITFIELD(origtype = expr->rtype)) {
- expr->data.monadic = makemonadicnode(expr->data.monadic, EBITFIELD);
- expr->data.monadic->rtype = origtype;
- expr->rtype = TYPE_BITFIELD(origtype)->bitfieldtype;
- }
-
- chain->objexpr = makediadicnode(expr, CExpr_AssignmentPromotion(args->node, expr->rtype, expr->flags, 1), EASS);
- }
- break;
- default:
- CError_FATAL(3286);
- }
-
- chain->next = ctor_chain;
- ctor_chain = chain;
- } while ((tk = lex()) == ',');
- }
-}
-
-static void CFunc_FunctionRedefinedCheck(Object *func) {
- if (TYPE_FUNC(func->type)->flags & FUNC_AUTO_GENERATED)
- CError_Error(CErrorStr333, func);
-
- if ((TYPE_FUNC(func->type)->flags & FUNC_DEFINED) && func->datatype != DINLINEFUNC)
- CError_Error(CErrorStr333, func);
-
- TYPE_FUNC(func->type)->flags |= FUNC_DEFINED;
-}
-
-static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) {
- Object *obj;
- Object *aliasobj;
- DeclInfo di;
-
- memclrw(&di, sizeof(di));
- di.name = name;
- di.storageclass = TK_STATIC;
- di.qual = Q_CONST;
- di.thetype = CDecl_NewArrayType(TYPE(&stchar), strlen(str) + 1);
-
- obj = CParser_NewGlobalDataObject(&di);
- aliasobj = CParser_NewAliasObject(obj, 0);
- obj->nspace = cscope_root;
- obj->datatype = DDATA;
- CFunc_NameLocalStaticDataObject(obj, obj->name->name);
-
- return aliasobj;
-}
-
-void CFunc_ParseFuncDef(Object *func, DeclInfo *di, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) {
- Boolean has_try;
- Object *nameobj_func;
- Object *nameobj_FUNCTION;
- Object *nameobj_pretty;
- char *prettyname;
- Statement *stmt18;
- Statement *stmt16;
- Statement firstStmt;
- DeclThing thing;
- CScopeSave scope;
-
- nameobj_func = NULL;
- nameobj_FUNCTION = NULL;
- nameobj_pretty = NULL;
- prettyname = NULL;
-
- CError_ASSERT(3373, IS_TYPE_FUNC(func->type));
-
- CFunc_FunctionRedefinedCheck(func);
- CParser_UpdateObject(func, di);
-
- if (!is_method) {
- CScope_SetFunctionScope(func, &scope);
- if (tclass)
- cscope_current = tclass->nspace;
- } else {
- CScope_SetMethodScope(func, tclass, is_static, &scope);
- }
-
- if (nspace)
- cscope_current = nspace;
-
- if (cscope_currentclass)
- CClass_MemberDef(func, cscope_currentclass);
-
- cfunc_is_extern_c = di->is_extern_c;
-
- CError_ASSERT(3392, IS_TYPE_FUNC(func->type));
- if (di->x45 && (func->qual & Q_ASM))
- CError_Error(CErrorStr176);
-
- if (cparamblkptr->precompile == 1 && !(func->qual & Q_INLINE))
- CError_ErrorTerm(CErrorStr180);
-
- if (di->x49)
- CError_Error(CErrorStr127);
-
- CFunc_FuncGenSetup(&firstStmt, func);
- if (!IS_TYPE_VOID(TYPE_FUNC(func->type)->functype))
- IsCompleteType(TYPE_FUNC(func->type)->functype);
-
- SetupFunctionArguments(func, di, &firstStmt);
-
- stmt18 = curstmt;
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
- functionbodyoffset = sourceoffset;
- firstStmt.sourceoffset = sourceoffset;
- functionbodypath = sourcefilepath;
- firstStmt.sourcefilepath = sourcefilepath;
-
- if (di->x45)
- CFunc_AdjustOldStyleArgs();
-
- if (di->x1C)
- CScope_MergeNameSpace(cscope_current, di->x1C);
-
- if (tk == TK_TRY) {
- tk = lex();
- has_try = 1;
- } else {
- has_try = 0;
- }
-
- if (CClass_IsConstructor(func)) {
- CError_ASSERT(3445, cscope_currentclass);
- CFunc_ParseCtorInitializer();
- CFunc_CheckCtorInitializer(cscope_currentclass, ctor_chain);
- }
-
- CPrep_TokenStreamFlush();
-
- if (!(func->qual & Q_ASM)) {
- if (tk == '{') {
- if (!has_try)
- tk = lex();
- } else {
- CError_ErrorSkip(CErrorStr135);
- has_try = 0;
- }
-
- if (func->name) {
- nameobj_func = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__func__"));
- nameobj_FUNCTION = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__FUNCTION__"));
- prettyname = CError_GetObjectName(func);
- nameobj_pretty = CFunc_DeclareFuncName(prettyname, GetHashNameNode("__PRETTY_FUNCTION__"));
- }
-
- if (!copts.cplusplus)
- CFunc_ParseLocalDeclarationList(0, 0, 0, 0);
-
- thing.switchinfo = NULL;
- thing.loopContinue = NULL;
- thing.loopBreak = NULL;
- thing.thetype = TYPE_FUNC(func->type)->functype;
- thing.qual = TYPE_FUNC(func->type)->qual;
-
- if (has_try) {
- CExcept_ScanTryBlock(&thing, CClass_IsConstructor(func) || CClass_IsDestructor(func));
- if (tk != 0)
- CPrep_UnLex();
- tk = '}';
- } else {
- while (tk != '}')
- statement(&thing);
- }
-
- stmt16 = curstmt;
-
- if (stmt16->type != ST_RETURN && stmt16->type != ST_GOTO) {
- CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath);
- CFunc_AppendStatement(ST_RETURN);
-
- curstmt->dobjstack = NULL;
- curstmt->expr = NULL;
-
- if (
- (copts.cplusplus || copts.c9x) &&
- !strcmp(func->name->name, "main") &&
- TYPE_FUNC(func->type)->functype == TYPE(&stsignedint)
- )
- curstmt->expr = intconstnode(TYPE(&stsignedint), 0);
-
- if (
- stmt16->type == ST_EXPRESSION &&
- stmt16->expr->type == EFUNCCALL &&
- stmt16->expr->rtype == &stvoid &&
- (stmt16->expr->flags & ENODE_FLAG_VOLATILE)
- )
- curstmt->flags = curstmt->flags | StmtFlag_8;
- }
-
- CheckCLabels();
-
- if (nameobj_func && (nameobj_func->flags & OBJECT_USED))
- CInit_DeclareData(nameobj_func->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1);
- if (nameobj_FUNCTION && (nameobj_FUNCTION->flags & OBJECT_USED))
- CInit_DeclareData(nameobj_FUNCTION->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1);
- if (nameobj_pretty && (nameobj_pretty->flags & OBJECT_USED))
- CInit_DeclareData(nameobj_pretty->u.alias.object, prettyname, NULL, strlen(prettyname) + 1);
-
- if (!fatalerrors) {
- if (CClass_IsConstructor(func))
- CABI_TransConstructor(func, stmt18, cscope_currentclass, NULL, has_try);
- if (CClass_IsDestructor(func))
- CABI_TransDestructor(func, func, &firstStmt, cscope_currentclass, 0);
-
- CFunc_DestructorCleanup(&firstStmt);
- CFunc_CodeCleanup(&firstStmt);
- symdeclend = CPrep_GetFileOffsetInfo(&cparser_fileoffset);
- CFunc_Gen(&firstStmt, func, di->x45);
- }
- } else {
- if (tk == '{') {
- in_assembler = 1;
- tk = lex();
- in_assembler = 0;
- } else {
- CError_ErrorSkip(CErrorStr135);
- }
-
- CFunc_ParseLocalDeclarationList(1, 0, 0, 0);
- Assembler(func);
- }
-
- if (tk != '}')
- CError_Error(CErrorStr130);
-
- CScope_RestoreScope(&scope);
-}
-
-void InitExpr_Register(ENode *expr, Object *object) {
- InitExpr *initexpr;
- InitExpr *scan;
-
- if (
- cparamblkptr->precompile == 1 &&
- object->sclass != TK_STATIC &&
- !(object->qual & (Q_20000 | Q_WEAK))
- )
- {
- CError_Error(CErrorStr180);
- return;
- }
-
- if (copts.suppress_init_code)
- return;
-
- initexpr = galloc(sizeof(InitExpr));
- initexpr->next = NULL;
- initexpr->object = object;
- initexpr->expr = CInline_CopyExpression(expr, CopyMode1);
-
- if (init_expressions) {
- scan = init_expressions;
- while (scan->next)
- scan = scan->next;
- scan->next = initexpr;
- } else {
- init_expressions = initexpr;
- }
-}
-
-void CFunc_GenerateDummyFunction(Object *func) {
- NameSpace *nspace;
- Boolean saveDebugInfo;
- Statement firstStmt;
-
- if (!anyerrors) {
- nspace = CFunc_FuncGenSetup(&firstStmt, NULL);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_CodeCleanup(&firstStmt);
- CFunc_Gen(&firstStmt, func, 0);
-
- cscope_current = nspace->parent;
- copts.filesyminfo = saveDebugInfo;
- }
-}
-
-void CFunc_GenerateSingleExprFunc(Object *func, ENode *expr) {
- NameSpace *nspace;
- Boolean saveDebugInfo;
- Statement firstStmt;
- Statement *stmt;
-
- if (cparamblkptr->precompile == 1) {
- CError_Error(CErrorStr180);
- return;
- }
-
- if (!anyerrors) {
- nspace = CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
-
- CFunc_CodeCleanup(&firstStmt);
- CInline_GenFunc(&firstStmt, func, 0);
-
- cscope_current = nspace->parent;
- copts.filesyminfo = saveDebugInfo;
- }
-}
-
-void CFunc_GenerateDummyCtorFunc(Object *func, Object *real_ctor) {
- ENode *expr;
- NameSpace *nspace;
- FuncArg *arg1;
- FuncArg *arg0;
- ENodeList *list;
- Boolean saveDebugInfo;
- Statement firstStmt;
- Statement *stmt;
-
- if (cparamblkptr->precompile == 1) {
- CError_Error(CErrorStr180);
- return;
- }
-
- if (!anyerrors) {
- cscope_currentfunc = func;
-
- nspace = CFunc_FuncGenSetup(&firstStmt, func);
-
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args);
-
- expr = CExpr_NewENode(EFUNCCALL);
- expr->type = EFUNCCALL;
- expr->cost = 200;
- expr->rtype = TYPE(&void_ptr);
- expr->data.funccall.funcref = CExpr_MakeObjRefNode(real_ctor, 0);
- expr->data.funccall.functype = TYPE_FUNC(func->type);
-
- CError_ASSERT(3716, IS_TYPE_FUNC(real_ctor->type));
- CError_ASSERT(3717, TYPE_FUNC(real_ctor->type)->flags & FUNC_METHOD);
- CError_ASSERT(3718, arg0 = TYPE_FUNC(real_ctor->type)->args);
- CError_ASSERT(3720, arg1 = arg0->next);
- CError_ASSERT(3721, arguments);
-
- list = lalloc(sizeof(ENodeList));
- expr->data.funccall.args = list;
- list->node = create_objectnode(arguments->object);
-
- if (TYPE_METHOD(real_ctor->type)->theclass->flags & CLASS_HAS_VBASES) {
- CError_ASSERT(3727, arg1 = arg1->next);
- CError_ASSERT(3728, arguments->next);
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = create_objectnode(arguments->next->object);
- }
-
- while (arg1) {
- CError_ASSERT(3737, arg1->dexpr);
- list->next = lalloc(sizeof(ENodeList));
- list = list->next;
- list->node = CExpr_GetDefaultArgument(expr->data.funccall.funcref, arg1);
- arg1 = arg1->next;
- }
-
- list->next = NULL;
-
- stmt = CFunc_AppendStatement(ST_RETURN);
- stmt->expr = expr;
-
- CFunc_CodeCleanup(&firstStmt);
- CInline_GenFunc(&firstStmt, func, 0);
-
- cscope_current = nspace->parent;
- cscope_currentfunc = NULL;
- copts.filesyminfo = saveDebugInfo;
- }
-}
diff --git a/compiler_and_linker/unsorted/CIRTransform.c b/compiler_and_linker/unsorted/CIRTransform.c
deleted file mode 100644
index b91f6af..0000000
--- a/compiler_and_linker/unsorted/CIRTransform.c
+++ /dev/null
@@ -1,534 +0,0 @@
-#include "compiler/CIRTransform.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CDecl.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct CIRTransTemp {
- struct CIRTransTemp *next;
- Object *object;
- Boolean flag;
-} CIRTransTemp;
-
-typedef struct MultiAccessOperand {
- Object *object;
- Object *tempobj;
- ENode *ass;
- Type *type;
- Type *bitfieldType;
-} MultiAccessOperand;
-
-// no idea what this is for...
-typedef struct StrangeRuntimeFunction {
- Object *object;
- short unk;
- char name[1];
-} StrangeRuntimeFunction;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static TypeFunc cirtrans_rtfunc8 = {
- TYPEFUNC, 0, NULL, NULL, TYPE(&void_ptr), 0, 0
-};
-static TypeFunc cirtrans_rtfunc4 = {
- TYPEFUNC, 0, NULL, NULL, TYPE(&stunsignedlong), 0, 0
-};
-static TypeFunc cirtrans_rtfunc2 = {
- TYPEFUNC, 0, NULL, NULL, TYPE(&stsignedshort), 0, 0
-};
-
-static CIRTransTemp *cirtrans_temps;
-Boolean modulo_generated;
-Boolean bigswitch_generated;
-Boolean alloca_called;
-
-// forward decls
-static ENode *CIRTrans_TransExpr(ENode *expr, Boolean flag);
-
-void CIRTrans_Setup(void) {
-}
-
-void CIRTrans_Cleanup(void) {
-}
-
-static Object *CIRTrans_GetRuntimeFunction(StrangeRuntimeFunction *rtfunc, Type *type) {
- Object *object;
-
- object = rtfunc->object;
- if (!object) {
- object = CParser_NewFunctionObject(NULL);
- rtfunc->object = object;
-
- object->nspace = cscope_root;
- object->name = GetHashNameNodeExport(rtfunc->name);
- object->flags = OBJECT_INTERNAL;
-
- if (type) {
- switch (type->size) {
- case 2:
- object->type = TYPE(&cirtrans_rtfunc2);
- break;
- case 4:
- object->type = TYPE(&cirtrans_rtfunc4);
- break;
- case 8:
- object->type = TYPE(&cirtrans_rtfunc8);
- break;
- default:
- CError_FATAL(427);
- }
- } else {
- object->type = TYPE(&cirtrans_rtfunc8);
- }
- }
-
- return object;
-}
-
-static Object *CIRTrans_GetTemporary(Type *type) {
- CIRTransTemp *temp;
-
- for (temp = cirtrans_temps; temp; temp = temp->next) {
- if (temp->object->type->size == type->size && !temp->flag) {
- temp->flag = 1;
- return temp->object;
- }
- }
-
- temp = oalloc(sizeof(CIRTransTemp));
- temp->next = cirtrans_temps;
- cirtrans_temps = temp;
-
- temp->object = create_temp_object(type);
- temp->flag = 1;
- return temp->object;
-}
-
-static ENode *CIRTrans_CheckRuntimeAssign(ENode *expr) {
- ENode *inner;
-
- if (ENODE_IS(expr->data.diadic.right, EINDIRECT)) {
- inner = expr->data.diadic.right->data.monadic;
- if (
- ENODE_IS(inner, EFUNCCALL) &&
- (inner->flags & ENODE_FLAG_80) &&
- inner->data.funccall.args &&
- ENODE_IS(inner->data.funccall.args->node, EOBJREF)
- )
- {
- CError_ASSERT(502, ENODE_IS(expr->data.diadic.left, EINDIRECT));
- inner->data.funccall.args->node = expr->data.diadic.left->data.monadic;
- inner->flags &= ~ENODE_FLAG_80;
- return expr->data.diadic.right;
- }
- }
-
- return expr;
-}
-
-static void CIRTrans_SetupMultiAccessOperand(MultiAccessOperand *mop, ENode *expr) {
- memclrw(mop, sizeof(MultiAccessOperand));
-
- mop->type = expr->rtype;
-
- CError_ASSERT(522, ENODE_IS(expr, EINDIRECT));
- expr = expr->data.monadic;
-
- if (ENODE_IS(expr, EOBJREF)) {
- mop->object = expr->data.objref;
- } else {
- if (ENODE_IS(expr, EBITFIELD)) {
- mop->bitfieldType = expr->rtype;
- expr = expr->data.monadic;
- }
- expr->rtype = CDecl_NewPointerType(mop->type);
- mop->tempobj = create_temp_object(expr->rtype);
- mop->ass = makediadicnode(create_objectnode(mop->tempobj), expr, EASS);
- }
-}
-
-static ENode *CIRTrans_GetMultiAccessOperand(MultiAccessOperand *mop) {
- ENode *expr;
-
- if (mop->object == NULL) {
- expr = create_objectnode(mop->tempobj);
- if (mop->bitfieldType) {
- expr = makemonadicnode(expr, EBITFIELD);
- expr->rtype = mop->bitfieldType;
- }
- expr = makemonadicnode(expr, EINDIRECT);
- } else {
- expr = create_objectnode(mop->object);
- }
-
- expr->rtype = mop->type;
- return expr;
-}
-
-static ENode *CIRTrans_InitMultiAccessExpression(MultiAccessOperand *mop, ENode *expr) {
- if (mop->ass) {
- expr = makediadicnode(mop->ass, expr, ECOMMA);
- expr->rtype = expr->data.diadic.right->rtype;
- }
- return expr;
-}
-
-ENode *CIRTrans_TransformOpAss(ENode *expr) {
- ENodeType nt;
- ENode *expr2;
- MultiAccessOperand mop;
-
- if (!ENODE_IS(expr->data.diadic.left, EINDIRECT)) {
- CError_Error(CErrorStr142);
- return nullnode();
- }
-
- CIRTrans_SetupMultiAccessOperand(&mop, expr->data.diadic.left);
-
- switch (expr->type) {
- case EMULASS:
- nt = EMUL;
- break;
- case EDIVASS:
- nt = EDIV;
- break;
- case EMODASS:
- nt = EMODULO;
- break;
- case EADDASS:
- nt = EADD;
- break;
- case ESUBASS:
- nt = ESUB;
- break;
- case ESHLASS:
- nt = ESHL;
- break;
- case ESHRASS:
- nt = ESHR;
- break;
- case EANDASS:
- nt = EAND;
- break;
- case EXORASS:
- nt = EXOR;
- break;
- case EORASS:
- nt = EOR;
- break;
- default:
- CError_FATAL(622);
- }
-
- expr2 = CIRTrans_GetMultiAccessOperand(&mop);
-
- if (!IS_TYPE_POINTER_ONLY(expr2->rtype)) {
- expr2 = CExpr_NewDyadicNode(expr2, nt, expr->data.diadic.right);
- if (expr2->rtype != expr->data.diadic.left->rtype) {
- expr2 = makemonadicnode(expr2, ETYPCON);
- expr2->rtype = expr->data.diadic.left->rtype;
- }
- } else {
- expr2 = makediadicnode(expr2, expr->data.diadic.right, nt);
- }
-
- if (IS_TYPE_FLOAT(expr2->rtype))
- expr2 = CExpr_BinaryFloatExpression(expr2);
-
- expr2 = makediadicnode(CIRTrans_GetMultiAccessOperand(&mop), expr2, EASS);
- return CIRTrans_InitMultiAccessExpression(&mop, expr2);
-}
-
-static void CIRTrans_TransIncDec() {
- // empty, never called
-}
-
-static ENode *CIRTrans_TransIntConst(ENode *expr) {
- Object *obj;
- UInt8 data[16];
-
- CMach_InitIntMem(expr->rtype, expr->data.intval, data);
-
- obj = CParser_NewGlobalDataObject(NULL);
- obj->name = CParser_GetUniqueName();
- obj->type = expr->rtype;
- obj->sclass = TK_STATIC;
- obj->datatype = DDATA;
- CScope_AddGlobalObject(obj);
- CInit_DeclareData(obj, data, NULL, obj->type->size);
- return create_objectnode(obj);
-}
-
-static ENode *CIRTrans_TransFloatConst(ENode *expr) {
- Object *obj;
- UInt8 data[16];
-
- CMach_InitFloatMem(expr->rtype, expr->data.floatval, data);
-
- obj = CParser_NewGlobalDataObject(NULL);
- obj->name = CParser_GetUniqueName();
- obj->type = expr->rtype;
- obj->sclass = TK_STATIC;
- obj->datatype = DDATA;
- CScope_AddGlobalObject(obj);
- CInit_DeclareData(obj, data, NULL, obj->type->size);
- return create_objectnode(obj);
-}
-
-static ENode *CIRTrans_TransUnary(ENode *expr, Type *type, StrangeRuntimeFunction *rtfunc) {
- if (type->size > 4) {
- expr = funccallexpr(
- CIRTrans_GetRuntimeFunction(rtfunc, type),
- create_objectrefnode(CIRTrans_GetTemporary(type)),
- expr,
- NULL,
- NULL);
- expr->flags |= ENODE_FLAG_80;
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = type;
- return expr;
- } else {
- expr = funccallexpr(
- CIRTrans_GetRuntimeFunction(rtfunc, type),
- expr,
- NULL,
- NULL,
- NULL);
- expr->rtype = type;
- return expr;
- }
-}
-
-static ENode *CIRTrans_TransBinary(ENode *expr, StrangeRuntimeFunction *rtfunc) {
- ENode *expr2;
-
- if (expr->rtype->size > 4) {
- expr2 = funccallexpr(
- CIRTrans_GetRuntimeFunction(rtfunc, expr->rtype),
- create_objectrefnode(CIRTrans_GetTemporary(expr->rtype)),
- expr->data.diadic.left,
- expr->data.diadic.right,
- NULL);
- expr2->flags |= ENODE_FLAG_80;
- expr2 = makemonadicnode(expr2, EINDIRECT);
- expr2->rtype = expr->rtype;
- return expr2;
- } else {
- expr2 = funccallexpr(
- CIRTrans_GetRuntimeFunction(rtfunc, expr->rtype),
- expr->data.diadic.left,
- expr->data.diadic.right,
- NULL,
- NULL);
- expr2->rtype = expr->rtype;
- return expr2;
- }
-}
-
-static ENodeList *CIRTrans_TransExprList(ENodeList *list) {
- ENodeList *scan;
-
- for (scan = list; scan; scan = scan->next)
- scan->node = CIRTrans_TransExpr(scan->node, 1);
-
- return list;
-}
-
-static ENode *CIRTrans_TransExpr(ENode *expr, Boolean flag) {
- switch (expr->type) {
- case EINDIRECT:
- case EFORCELOAD:
- case EBITFIELD:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, flag);
- break;
- case EPOSTINC:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, 1);
- break;
- case EPOSTDEC:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, 1);
- break;
- case EPREINC:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, 1);
- break;
- case EPREDEC:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, 1);
- break;
- case ETYPCON:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, flag);
- if (!flag)
- return expr->data.monadic;
- break;
- case EBINNOT:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, flag);
- break;
- case ELOGNOT:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, flag);
- break;
- case EMONMIN:
- expr->data.monadic = CIRTrans_TransExpr(expr->data.monadic, flag);
- break;
- case EADD:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case ESUB:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EMUL:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- case EDIV:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EMODULO:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case ESHL:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case ESHR:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EROTL:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EROTR:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EAND:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EXOR:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EOR:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- if (!flag) {
- expr->type = ECOMMA;
- expr->rtype = expr->data.diadic.right->rtype;
- return expr;
- }
- break;
- case ELAND:
- case ELOR:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, 1);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EMULV:
- case EADDV:
- case ESUBV:
- case EPMODULO:
- case EBCLR:
- case EBTST:
- case EBSET:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, flag);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case EASS:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, 1);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, 1);
- break;
- case EMULASS:
- case EDIVASS:
- case EADDASS:
- case ESUBASS:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, 1);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, 1);
- break;
- case EMODASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, 1);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, 1);
- break;
- case ECOMMA:
- expr->data.diadic.left = CIRTrans_TransExpr(expr->data.diadic.left, 0);
- expr->data.diadic.right = CIRTrans_TransExpr(expr->data.diadic.right, flag);
- break;
- case ECOND:
- expr->data.cond.cond = CIRTrans_TransExpr(expr->data.cond.cond, 1);
- expr->data.cond.expr1 = CIRTrans_TransExpr(expr->data.cond.expr1, 1);
- expr->data.cond.expr2 = CIRTrans_TransExpr(expr->data.cond.expr2, 1);
- break;
- case EMFPOINTER:
- expr->data.mfpointer.accessnode = CIRTrans_TransExpr(expr->data.mfpointer.accessnode, flag);
- expr->data.mfpointer.mfpointer = CIRTrans_TransExpr(expr->data.mfpointer.mfpointer, flag);
- break;
- case EFUNCCALL:
- case EFUNCCALLP:
- if (
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- !strcmp(expr->data.funccall.funcref->data.objref->name->name, "__alloca")
- )
- alloca_called = 1;
- expr->data.funccall.funcref = CIRTrans_TransExpr(expr->data.funccall.funcref, 1);
- expr->data.funccall.args = CIRTrans_TransExprList(expr->data.funccall.args);
- break;
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CIRTrans_TransExpr(expr->data.nullcheck.nullcheckexpr, 1);
- expr->data.nullcheck.condexpr = CIRTrans_TransExpr(expr->data.nullcheck.condexpr, 1);
- break;
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- expr->data.newexception.initexpr = CIRTrans_TransExpr(expr->data.newexception.initexpr, 1);
- expr->data.newexception.tryexpr = CIRTrans_TransExpr(expr->data.newexception.tryexpr, 1);
- break;
- case EINITTRYCATCH:
- expr->data.itc.initexpr = CIRTrans_TransExpr(expr->data.itc.initexpr, 1);
- expr->data.itc.tryexpr = CIRTrans_TransExpr(expr->data.itc.tryexpr, 1);
- expr->data.itc.catchexpr = CIRTrans_TransExpr(expr->data.itc.catchexpr, 1);
- expr->data.itc.result = CIRTrans_TransExpr(expr->data.itc.result, 1);
- break;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case ELABEL:
- case EMEMBER:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- break;
- default:
- CError_FATAL(1947);
- }
-
- return expr;
-}
-
-void CIRTrans_Transform(void) {
- cirtrans_temps = NULL;
-}
diff --git a/compiler_and_linker/unsorted/CInit.c b/compiler_and_linker/unsorted/CInit.c
deleted file mode 100644
index c2d2299..0000000
--- a/compiler_and_linker/unsorted/CInit.c
+++ /dev/null
@@ -1,3082 +0,0 @@
-#include "compiler/CInit.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrec.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-TempNodeCB cinit_tempnodefunc;
-InitInfo *cinit_initinfo;
-static PooledString *cinit_stringlist;
-static PooledString *cinit_pooledstringlist;
-static PooledString *cinit_pooledwstringlist;
-static ObjectList *cinit_tentative;
-static TypeClass *cinit_loop_class;
-static ENodeList *cinit_fdtnode;
-static Boolean cinit_fdtambig;
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct CInit_1C {
- struct CInit_1C *next;
- Type *type;
- ENode *expr;
- SInt32 offset;
-} CInit_1C;
-
-typedef struct CInit_Stuff {
- struct CInit_Stuff *x0;
- struct CInit_Stuff *x4;
- char *buffer;
- SInt32 xC;
- SInt32 size;
- SInt32 bufferSize;
- SInt32 x18;
- CInit_1C *x1C;
- OLinkList *list;
- Boolean flag;
-} CInit_Stuff;
-
-typedef enum {
- Stage0,
- Stage1,
- Stage2,
- Stage3,
- Stage4
-} Stage;
-
-typedef struct CInit_Stuff2 {
- ENode *expr;
- ENode myexpr;
- Stage stage;
- Boolean x23;
- SInt32 x24;
- Type *type;
-} CInit_Stuff2;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// forward decls
-static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32 qual, Boolean flag);
-static void CInit_Type(Type *type, UInt32 qual, Boolean flag);
-
-void CInit_Init(void) {
- cinit_tempnodefunc = NULL;
- cinit_initinfo = NULL;
- cinit_stringlist = NULL;
- cinit_pooledstringlist = NULL;
- cinit_pooledwstringlist = NULL;
- cinit_tentative = NULL;
-}
-
-static void CInit_SetupInitInfo(InitInfo *info, Object *obj) {
- memclrw(info, sizeof(InitInfo));
- info->obj = obj;
- info->next = cinit_initinfo;
- cinit_initinfo = info;
-}
-
-static void CInit_CleanupInitInfo(InitInfo *info) {
- cinit_initinfo = info->next;
-}
-
-static void CInit_SetupInitInfoBuffer(Type *type) {
- SInt32 size = type->size;
- cinit_initinfo->size = size;
-
- if (!size)
- size = 512;
- else if (size & 1)
- size++;
-
- cinit_initinfo->buffer = lalloc(size);
- cinit_initinfo->bufferSize = size;
- memclrw(cinit_initinfo->buffer, size);
-}
-
-static void CInit_SetData(void *data, SInt32 offset, SInt32 size) {
- SInt32 end;
- char *buffer;
-
- end = offset + size;
- if (end > cinit_initinfo->size)
- cinit_initinfo->size = end;
-
- if (end > cinit_initinfo->bufferSize) {
- if (cinit_initinfo->obj->type->size == 0) {
- if (end < 8000)
- end += 0x400;
- else
- end += 0x4000;
- }
- if (end & 1)
- end++;
-
- buffer = lalloc(end);
- memclrw(buffer, end);
- memcpy(buffer, cinit_initinfo->buffer, cinit_initinfo->bufferSize);
- cinit_initinfo->buffer = buffer;
- cinit_initinfo->bufferSize = end;
- }
-
- if (data)
- memcpy(cinit_initinfo->buffer + offset, data, size);
-}
-
-typedef struct CInit_Initializer {
- struct CInit_Initializer *next;
- struct CInit_Initializer *sublist;
- ENode *expr;
- TStreamElement element;
-} CInit_Initializer;
-
-static CInit_Initializer *CInit_ParseInitializerList(void) {
- CInit_Initializer *r30;
- CInit_Initializer *r29;
- CInit_Initializer *tmp;
-
- if ((tk = lex()) == '}')
- return NULL;
-
- r30 = NULL;
- do {
- if (r30) {
- tmp = lalloc(sizeof(CInit_Initializer));
- r29->next = tmp;
- r29 = tmp;
- }
- if (!r30) {
- r30 = r29 = lalloc(sizeof(CInit_Initializer));
- }
- r29->next = NULL;
-
- if (tk == '{') {
- r29->element = *CPrep_CurStreamElement();
- r29->sublist = CInit_ParseInitializerList();
- r29->expr = NULL;
- tk = lex();
- } else {
- r29->sublist = NULL;
- r29->expr = conv_assignment_expression();
- r29->element = *CPrep_CurStreamElement();
- }
-
- if (tk == '}')
- return r30;
-
- if (tk != ',') {
- CError_Error(CErrorStr116);
- return r30;
- }
- } while ((tk = lex()) != '}');
-
- return r30;
-}
-
-static CInit_Initializer *CInit_ParseInitializerClause(void) {
- CInit_Initializer *init;
-
- init = lalloc(sizeof(CInit_Initializer));
- init->next = NULL;
- if (tk != '{') {
- init->sublist = NULL;
- init->expr = conv_assignment_expression();
- init->element = *CPrep_CurStreamElement();
- } else {
- init->element = *CPrep_CurStreamElement();
- init->expr = NULL;
- init->sublist = CInit_ParseInitializerList();
- tk = lex();
- }
-
- return init;
-}
-
-static ENode *CInit_ParseInitializer(ENode *expr) {
- CInt64 save_int;
- Float save_float;
- SInt32 save_size;
- short t;
-
- switch (tk) {
- case TK_INTCONST:
- case TK_FLOATCONST:
- save_int = tkintconst;
- save_float = tkfloatconst;
- save_size = tksize;
- t = lookahead();
- tkintconst = save_int;
- tkfloatconst = save_float;
- tksize = save_size;
-
- switch (t) {
- case ',':
- case ';':
- case '}':
- memclrw(expr, sizeof(ENode));
- switch (tk) {
- case TK_INTCONST:
- expr->type = EINTCONST;
- expr->rtype = atomtype();
- expr->data.intval = tkintconst;
- break;
- case TK_FLOATCONST:
- expr->type = EFLOATCONST;
- expr->rtype = atomtype();
- expr->data.floatval = tkfloatconst;
- break;
- }
- tk = lex();
- CPrep_TokenStreamFlush();
- return expr;
- }
- }
-
- expr = assignment_expression();
- CPrep_TokenStreamFlush();
- return expr;
-}
-
-static Stage CInit_ParseNextInit(CInit_Stuff2 *s) {
- DeclInfo di;
- short t;
-
- s->expr = NULL;
- if (tk == ';') {
- s->stage = Stage4;
- return Stage4;
- }
- switch (s->stage) {
- case Stage0:
- if (s->x23) {
- if (tk == '(') {
- tk = lex();
- CParser_GetDeclSpecs(&di, 1);
- s->type = di.thetype;
- if (tk == ')')
- tk = lex();
- else
- CError_Error(CErrorStr115);
-
- if (tk == '(')
- tk = lex();
- else
- CError_Error(CErrorStr114);
- s->x24++;
- t = lookahead();
- if (t == TK_UU_VECTOR || (t == TK_IDENTIFIER && !strcmp("vector", tkidentifier->name)))
- CInit_ParseNextInit(s);
- s->stage = Stage1;
- return Stage1;
- }
- } else {
- if (tk == '{') {
- tk = lex();
- s->x24 = 0;
- s->stage = Stage1;
- return Stage1;
- }
- }
- s->expr = CInit_ParseInitializer(&s->myexpr);
- s->stage = Stage2;
- return Stage2;
- case Stage1:
- break;
- case Stage2:
- case Stage3:
- if (tk == ',') {
- tk = lex();
- break;
- }
- if (s->x24) {
- if (tk != ')')
- CError_Error(CErrorStr174);
- if (s->x24 > 1) {
- s->x24--;
- tk = lex();
- CInit_ParseNextInit(s);
- }
- } else {
- if (tk != '}')
- CError_Error(CErrorStr174);
- }
- s->stage = Stage3;
- return Stage3;
- default:
- CError_FATAL(389);
- }
-
- switch (tk) {
- case '{':
- tk = lex();
- s->stage = Stage1;
- return Stage1;
- case '}':
- s->stage = Stage3;
- return Stage3;
- case '(':
- if (s->x23) {
- tk = lex();
- s->stage = Stage1;
- return Stage1;
- }
- case ')':
- if (s->x23 && s->x24) {
- if (s->x24 > 1) {
- s->x24--;
- tk = lex();
- CInit_ParseNextInit(s);
- }
- s->stage = Stage3;
- return Stage3;
- }
- default:
- s->expr = CInit_ParseInitializer(&s->myexpr);
- s->stage = Stage2;
- return Stage2;
- }
-}
-
-static void CInit_CloseInitList(void) {
- if (tk == ',' && copts.cplusplus)
- tk = lex();
-
- if (tk != '}')
- CError_ErrorSkip(CErrorStr130);
- else
- tk = lex();
-}
-
-static Boolean CInit_IsAllZero(char *buf, SInt32 size) {
- SInt32 i;
-
- if (copts.explicit_zero_data)
- return 0;
-
- for (i = 0; i < size; i++)
- if (buf[i]) return 0;
-
- return 1;
-}
-
-static Boolean CInit_ClassNeedsConstruction(TypeClass *tclass) {
- return CClass_Constructor(tclass) || CClass_Destructor(tclass);
-}
-
-static Boolean CInit_IsSimpleStructArrayInit(Type *type) {
- switch (type->type) {
- case TYPESTRUCT:
- return 1;
- case TYPEARRAY:
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (!IS_TYPE_CLASS(type))
- return 1;
- case TYPECLASS:
- return !CInit_ClassNeedsConstruction(TYPE_CLASS(type));
- default:
- return 0;
- }
-}
-
-static Boolean CInit_IsSimpleInit(Type *type) {
- switch (type->type) {
- case TYPEPOINTER:
- return (TYPE_POINTER(type)->qual & Q_REFERENCE) == 0;
- case TYPEARRAY:
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (!IS_TYPE_CLASS(type))
- return 1;
- case TYPECLASS:
- return !CInit_ClassNeedsConstruction(TYPE_CLASS(type));
- default:
- return 1;
- }
-}
-
-static Object *CInit_GetInitObject(Object *obj) {
- if (obj->datatype == DALIAS) {
- CError_ASSERT(521, !obj->u.alias.offset);
- obj = obj->u.alias.object;
- }
- return obj;
-}
-
-static Object *CInit_CreateStaticDataObject(Type *type, UInt32 qual, HashNameNode *name) {
- Object *obj;
- DeclInfo di;
-
- memclrw(&di, sizeof(DeclInfo));
- di.thetype = type;
- di.name = name ? name : CParser_GetUniqueName();
- di.qual = qual;
- di.storageclass = TK_STATIC;
- di.is_extern_c = 1;
-
- obj = CParser_NewGlobalDataObject(&di);
- obj->nspace = cscope_root;
- return obj;
-}
-
-static Type *CInit_GetRegMemType(void) {
- return CDecl_NewStructType(void_ptr.size * 3, CMach_GetTypeAlign((Type *) &void_ptr));
-}
-
-static Object *CInit_CreateStaticData(Type *type) {
- Object *obj = CInit_CreateStaticDataObject(type, 0, NULL);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- return obj;
-}
-
-static void CInit_InitNonConst(CInit_Stuff *s, Type *type, ENode *expr) {
- CInit_1C *entry;
- CInit_1C *scan;
- MWVector128 *vec;
-
- if (s->x4->flag || IS_TYPE_VECTOR(type)) {
- if (IS_TYPE_VECTOR(type) && ENODE_IS(expr, EVECTOR128CONST)) {
- vec = (MWVector128 *) (s->buffer + s->size);
- *vec = expr->data.vector128val;
- CMach_InitVectorMem(type, *vec, vec, 1);
- }
-
- entry = lalloc(sizeof(CInit_1C));
- memclrw(entry, sizeof(CInit_1C));
- entry->next = NULL;
- entry->type = type;
- entry->expr = expr;
- entry->offset = s->xC + s->size;
- if ((scan = s->x4->x1C)) {
- while (scan->next)
- scan = scan->next;
- scan->next = entry;
- } else {
- s->x4->x1C = entry;
- }
- } else {
- CError_Error(CErrorStr124);
- }
-}
-
-static CInit_Stuff *CInit_GrowBuffer(CInit_Stuff *s, SInt32 size) {
- CInit_Stuff *newbuf;
-
- newbuf = lalloc(sizeof(CInit_Stuff));
- memclrw(newbuf, sizeof(CInit_Stuff));
- newbuf->x4 = s->x4;
- newbuf->buffer = lalloc(size);
- newbuf->xC = s->xC + s->size;
- newbuf->bufferSize = size;
- s->x0 = newbuf;
- memset(newbuf->buffer, 0, newbuf->bufferSize);
- return newbuf;
-}
-
-Boolean CInit_RelocInitCheck(ENode *expr, Object **objptr, CInt64 *valptr, Boolean flag) {
- Object *objcheck1;
- Object *objcheck2;
- CInt64 valcheck1;
- CInt64 valcheck2;
-
- *objptr = NULL;
- valptr->lo = 0;
- valptr->hi = 0;
-
- while (1) {
- switch (expr->type) {
- case EINTCONST:
- *valptr = expr->data.intval;
- return 1;
- case EOBJREF:
- objcheck1 = CInit_GetInitObject(expr->data.objref);
- if (objcheck1->datatype == DLOCAL && !flag)
- return 0;
- *objptr = objcheck1;
- return 1;
- case ESTRINGCONST:
- CInit_RewriteString(expr, 0);
- continue;
- case ETYPCON:
- do {
- if (expr->rtype->size != expr->data.monadic->rtype->size)
- return 0;
- expr = expr->data.monadic;
- if (!IS_TYPE_POINTER_ONLY(expr->rtype) && !IS_TYPE_INT(expr->rtype))
- return 0;
- } while (ENODE_IS(expr, ETYPCON));
- continue;
- case EADD:
- if (!CInit_RelocInitCheck(expr->data.diadic.left, &objcheck1, &valcheck1, flag))
- return 0;
- if (!CInit_RelocInitCheck(expr->data.diadic.right, &objcheck2, &valcheck2, flag))
- return 0;
-
- if (objcheck1) {
- if (objcheck2)
- return 0;
- *objptr = objcheck1;
- } else {
- *objptr = objcheck1;
- }
-
- *valptr = CMach_CalcIntDiadic(TYPE(&stunsignedlong), valcheck1, '+', valcheck2);
- return 1;
- case ESUB:
- if (!CInit_RelocInitCheck(expr->data.diadic.left, &objcheck1, &valcheck1, flag))
- return 0;
- if (!CInit_RelocInitCheck(expr->data.diadic.right, &objcheck2, &valcheck2, flag))
- return 0;
-
- if (objcheck2)
- return 0;
-
- *objptr = objcheck1;
- *valptr = CMach_CalcIntDiadic(TYPE(&stunsignedlong), valcheck1, '-', valcheck2);
- return 1;
- default:
- return 0;
- }
- }
-}
-
-static void CInit_InitTypePointer(CInit_Stuff *s, ENode *expr, TypePointer *tptr, UInt32 qual) {
- Object *obj;
- CInt64 val;
- OLinkList *list;
-
- expr = CExpr_AssignmentPromotion(expr, TYPE(tptr), qual & (Q_CONST | Q_VOLATILE), 1);
- if (IS_TYPE_POINTER_ONLY(expr->rtype) || ENODE_IS(expr, EINTCONST)) {
- if (CInit_RelocInitCheck(expr, &obj, &val, 0)) {
- if (obj) {
- list = lalloc(sizeof(OLinkList));
- list->next = s->x4->list;
- list->obj = obj;
- list->somevalue = CInt64_GetULong(&val);
- list->offset = s->xC + s->size;
- s->x4->list = list;
- } else {
- CMach_InitIntMem(TYPE(&stunsignedlong), val, s->buffer + s->size);
- }
- } else {
- CInit_InitNonConst(s, TYPE(tptr), expr);
- }
- } else {
- CError_Error(CErrorStr174);
- }
-}
-
-static void CInit_InitTypeInt(CInit_Stuff *s, ENode *expr, TypeIntegral *tint, UInt32 qual) {
- expr = CExpr_AssignmentPromotion(expr, TYPE(tint), qual & (Q_CONST | Q_VOLATILE), 1);
- if (IS_TYPE_INT(expr->rtype)) {
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(TYPE(tint), expr->data.intval, s->buffer + s->size);
- } else if (ENODE_IS(expr, ETYPCON) && IS_TYPE_POINTER_ONLY(expr->data.monadic->rtype) && expr->rtype->size == 4 && (copts.cplusplus || !copts.ANSIstrict)) {
- CInit_InitTypePointer(s, expr->data.monadic, TYPE_POINTER(expr->data.monadic->rtype), qual);
- } else {
- CInit_InitNonConst(s, TYPE(tint), expr);
- }
- } else {
- CError_Error(CErrorStr174);
- }
-}
-
-static void CInit_InitTypeFloat(CInit_Stuff *s, ENode *expr, TypeIntegral *tint, UInt32 qual) {
- expr = CExpr_AssignmentPromotion(expr, TYPE(tint), qual & (Q_CONST | Q_VOLATILE), 1);
- if (IS_TYPE_FLOAT(expr->rtype)) {
- if (ENODE_IS(expr, EFLOATCONST)) {
- CMach_InitFloatMem(TYPE(tint), expr->data.floatval, s->buffer + s->size);
- } else {
- CInit_InitNonConst(s, TYPE(tint), expr);
- }
- } else {
- CError_Error(CErrorStr174);
- }
-}
-
-static void CInit_InitTypeEnum(CInit_Stuff *s, ENode *expr, TypeEnum *tenum, UInt32 qual) {
- expr = CExpr_AssignmentPromotion(expr, TYPE(tenum), qual & (Q_CONST | Q_VOLATILE), 1);
- if (IS_TYPE_ENUM(expr->rtype)) {
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(tenum->enumtype, expr->data.intval, s->buffer + s->size);
- } else {
- CInit_InitNonConst(s, TYPE(tenum), expr);
- }
- } else {
- CError_Error(CErrorStr174);
- }
-}
-
-static void CInit_InitTypeMemberPointer(CInit_Stuff *s, ENode *expr, TypeMemberPointer *tmptr, UInt32 qual) {
- expr = CExpr_AssignmentPromotion(expr, TYPE(tmptr), qual & (Q_CONST | Q_VOLATILE), 1);
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(TYPE(&stsignedlong), expr->data.intval, s->buffer + s->size);
- } else {
- CInit_InitNonConst(s, TYPE(tmptr), expr);
- }
-}
-
-static void CInit_SetBitfield(TypeBitfield *tbitfield, UInt8 *buffer, CInt64 val) {
- int i;
- int pos;
- int step;
-
- if (copts.littleendian) {
- pos = tbitfield->offset;
- step = 1;
- } else {
- pos = tbitfield->bitlength + tbitfield->offset - 1;
- step = -1;
- }
- for (i = 0; i < tbitfield->bitlength; i++, pos += step) {
- if (CInt64_GetULong(&val) & 1) {
- if (copts.littleendian) {
- buffer[pos >> 3] |= 1 << (pos & 7);
- } else {
- buffer[pos >> 3] |= 0x80 >> (pos & 7);
- }
- }
- val = CInt64_ShrU(val, cint64_one);
- }
-}
-
-static void CInit_InitTypeBitfield(CInit_Stuff *s, ENode *expr, TypeBitfield *tbitfield, UInt32 qual) {
- Type *inner;
-
- inner = tbitfield->bitfieldtype;
- if (IS_TYPE_ENUM(inner))
- inner = TYPE_ENUM(inner)->enumtype;
- expr = CExpr_AssignmentPromotion(expr, inner, qual & (Q_CONST | Q_VOLATILE), 1);
-
- if (IS_TYPE_INT(expr->rtype)) {
- if (ENODE_IS(expr, EINTCONST)) {
- CInit_SetBitfield(tbitfield, (UInt8 *) s->buffer + s->size, expr->data.intval);
- } else {
- CInit_InitNonConst(s, TYPE(tbitfield), expr);
- }
- } else {
- CError_Error(CErrorStr174);
- }
-}
-
-static void CInit_InitTypeArray(CInit_Stuff *s, CInit_Stuff2 *s2, TypePointer *tptr, UInt32 qual, Boolean errorflag) {
- SInt32 targetsize;
- SInt32 start;
- SInt32 i;
- Boolean flag;
- Boolean is_zero_size;
- SInt32 size;
- SInt32 tmp;
- Boolean is_char_ptr;
- Boolean is_wchar_ptr;
-
- is_zero_size = tptr->size == 0;
- targetsize = tptr->target->size;
- if (!targetsize) {
- CError_Error(CErrorStr145);
- return;
- }
-
- is_char_ptr = IS_TYPE_INT(tptr->target) && (targetsize == 1);
- is_wchar_ptr = IS_TYPE_INT(tptr->target) && (targetsize == stwchar.size);
- switch (s2->stage) {
- case Stage1:
- flag = 1;
- if (CInit_ParseNextInit(s2) == Stage3) {
- if (is_zero_size)
- CError_Error(CErrorStr174);
- tk = lex();
- return;
- }
- break;
- case Stage2:
- flag = 0;
- break;
- }
- switch (s2->stage) {
- case Stage1:
- case Stage2:
- break;
- default:
- CError_Error(CErrorStr174);
- return;
- }
-
- if (s2->stage == Stage2)
- s2->expr = pointer_generation(s2->expr);
-
- if (s2->stage == Stage2 && ENODE_IS(s2->expr, ESTRINGCONST) && (is_char_ptr || is_wchar_ptr)) {
- if (IS_TYPE_POINTER_ONLY(s2->expr->rtype) && tptr->target->size != TYPE_POINTER(s2->expr->rtype)->target->size)
- CError_Warning(CErrorStr174);
- size = tmp = s2->expr->data.string.size;
- if (is_zero_size) {
- tptr->size = s2->expr->data.string.size;
- if (s->bufferSize < tmp)
- s = CInit_GrowBuffer(s, tmp);
- memcpy(s->buffer, s2->expr->data.string.data, size);
- s->size = size;
- } else {
- if (s2->expr->data.string.size > tptr->size) {
- if (copts.cplusplus || (s2->expr->data.string.size - 1) > tptr->size)
- CError_Error(CErrorStr147);
- s2->expr->data.string.size = tptr->size;
- size = tptr->size;
- }
- memcpy(s->buffer + s->size, s2->expr->data.string.data, size);
- }
- } else {
- if (!flag && errorflag) {
- CError_Error(CErrorStr174);
- return;
- }
-
- start = s->size;
- i = 0;
- while (1) {
- if (is_zero_size) {
- size = (i + 1) * targetsize;
- s->size = start + size - targetsize - s->xC;
- if (s->size + targetsize > s->bufferSize)
- s = CInit_GrowBuffer(s, targetsize * 16);
- CInit_InitType(s, s2, tptr->target, qual, 0);
- tptr->size = size;
- s->size = start + size - s->xC;
- } else {
- if (tptr->size <= i * targetsize) {
- i--;
- CError_Error(CErrorStr147);
- }
- s->size = start + i * targetsize;
- CInit_InitType(s, s2, tptr->target, qual, 0);
- if (!flag && tptr->size <= (i + 1) * targetsize)
- break;
- }
-
- switch (CInit_ParseNextInit(s2)) {
- case Stage1:
- case Stage2:
- break;
- case Stage3:
- if (flag)
- tk = lex();
- return;
- default:
- CError_Error(CErrorStr130);
- return;
- }
-
- i++;
- }
- }
-
- if (flag) {
- switch (CInit_ParseNextInit(s2)) {
- case Stage3:
- tk = lex();
- return;
- case Stage2:
- CError_Error(CErrorStr147);
- return;
- default:
- CError_Error(CErrorStr130);
- }
- }
-}
-
-static void CInit_InitTypeStruct(CInit_Stuff *s, CInit_Stuff2 *s2, const TypeStruct *tstruct, UInt32 qual, Boolean errorflag) {
- StructMember *member;
- SInt32 start;
- Boolean flag;
- SInt32 count;
- TypePointer arraytype;
- MWVector128 *vecp;
- int i;
-
- count = 0;
- if (s2->type)
- tstruct = TYPE_STRUCT(s2->type);
-
- if (!(member = tstruct->members)) {
- CError_Error(CErrorStr145);
- return;
- }
-
- switch (s2->stage) {
- case Stage1:
- flag = 1;
- if (CInit_ParseNextInit(s2) == Stage3) {
- tk = lex();
- return;
- }
- break;
- case Stage2:
- flag = 0;
- break;
- }
-
- switch (s2->stage) {
- case Stage1:
- case Stage2:
- break;
- default:
- CError_Error(CErrorStr174);
- return;
- }
-
- if (!flag && s2->stage == Stage2 && (errorflag || s2->expr->rtype == TYPE(tstruct))) {
- s2->expr = CExpr_AssignmentPromotion(s2->expr, TYPE(tstruct), qual, 1);
- if (IS_TYPE_STRUCT(s2->expr->rtype))
- CInit_InitNonConst(s, TYPE(tstruct), s2->expr);
- return;
- }
-
- start = s->size;
- while (1) {
- s->size = start + member->offset;
- if (!member->type->size) {
- if (!errorflag || !IS_TYPE_ARRAY(member->type)) {
- CError_Error(CErrorStr147);
- if (!IS_TYPE_ARRAY(member->type))
- return;
- }
-
- arraytype = *TYPE_POINTER(member->type);
- CInit_InitTypeArray(s, s2, &arraytype, member->qual, 1);
- s->x18 = arraytype.size;
- } else {
- CInit_InitType(s, s2, member->type, member->qual, 0);
- }
-
- count++;
- if (IS_TYPESTRUCT_VECTOR(tstruct) && s2->expr)
- CError_ASSERT(1218, !ENODE_IS(s2->expr, EVECTOR128CONST));
-
- do {
- member = member->next;
- } while (member && (member->qual & Q_WEAK));
-
- if (!member || tstruct->stype == STRUCT_TYPE_UNION) {
- if (flag) {
- switch (CInit_ParseNextInit(s2)) {
- case Stage3:
- if (IS_TYPESTRUCT_VECTOR(tstruct)) {
- vecp = (MWVector128 *) (s->buffer + start);
- CMach_InitVectorMem(TYPE(tstruct), *vecp, vecp, 0);
- }
- tk = lex();
- return;
- case Stage2:
- CError_Error(CErrorStr147);
- return;
- default:
- CError_Error(CErrorStr130);
- return;
- }
- }
- return;
- } else {
- switch (CInit_ParseNextInit(s2)) {
- case Stage1:
- case Stage2:
- continue;
- case Stage3:
- if (flag)
- tk = lex();
- if (IS_TYPESTRUCT_VECTOR(tstruct)) {
- switch (TYPE_STRUCT(tstruct)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- if (count != 16) {
- if (count == 1) {
- UInt8 val, *p;
- p = (UInt8 *) s->buffer;
- val = p[0];
- for (i = 1; i < 16; i++)
- p[i] = val;
- } else {
- CError_Error(CErrorStr174);
- }
- }
- break;
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- if (count != 8) {
- if (count == 1) {
- SInt16 val, *p;
- p = (SInt16 *) s->buffer;
- val = p[0];
- for (i = 1; i < 8; i++)
- p[i] = val;
- } else {
- CError_Error(CErrorStr174);
- }
- }
- break;
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- case STRUCT_VECTOR_FLOAT:
- if (count != 4) {
- if (count == 1) {
- UInt32 val, *p;
- p = (UInt32 *) s->buffer;
- val = p[0];
- for (i = 1; i < 4; i++)
- p[i] = val;
- } else {
- CError_Error(CErrorStr174);
- }
- }
- break;
- }
- }
- return;
- default:
- CError_Error(CErrorStr174);
- return;
- }
- }
- }
-}
-
-static ObjMemberVar *CInit_FindNextMember(ObjMemberVar *ivar) {
- ObjMemberVar *scan = ivar;
- while (1) {
- scan = scan->next;
- if (!scan)
- return NULL;
- if (!scan->anonunion)
- return scan;
- if (scan->offset > ivar->offset)
- return scan;
- if (IS_TYPE_BITFIELD(scan->type) && IS_TYPE_BITFIELD(ivar->type) && TYPE_BITFIELD(scan->type)->offset != TYPE_BITFIELD(ivar->type)->offset)
- return scan;
- }
-}
-
-static void CInit_InitTypeClass(CInit_Stuff *s, CInit_Stuff2 *s2, TypeClass *tclass, UInt32 qual, Boolean errorflag) {
- ObjMemberVar *ivar;
- SInt32 start;
- Boolean flag;
- SInt32 last_offset;
- TypePointer arraytype;
-
- if (tclass->bases || tclass->vtable) {
- CError_Error(CErrorStr174);
- return;
- }
-
- switch (s2->stage) {
- case Stage1:
- flag = 1;
- if (CInit_ParseNextInit(s2) == Stage3) {
- tk = lex();
- return;
- }
- break;
- case Stage2:
- flag = 0;
- break;
- }
-
- switch (s2->stage) {
- case Stage1:
- case Stage2:
- break;
- default:
- CError_Error(CErrorStr174);
- return;
- }
-
- if (!flag && s2->stage == Stage2 && (errorflag || s2->expr->rtype == TYPE(tclass) || CExpr_CanImplicitlyConvert(s2->expr, TYPE(tclass), 0))) {
- s2->expr = CExpr_AssignmentPromotion(s2->expr, TYPE(tclass), qual, 1);
- if (IS_TYPE_CLASS(s2->expr->rtype))
- CInit_InitNonConst(s, TYPE(tclass), s2->expr);
- return;
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->access != ACCESSPUBLIC) {
- CError_Error(CErrorStr174);
- break;
- }
- }
-
- if (!(ivar = tclass->ivars)) {
- CError_Error(CErrorStr147);
- return;
- }
- start = s->size;
- while (1) {
- s->size = start + ivar->offset;
- if (!ivar->type->size) {
- if (!errorflag || !IS_TYPE_ARRAY(ivar->type)) {
- CError_Error(CErrorStr147);
- if (!IS_TYPE_ARRAY(ivar->type))
- return;
- }
-
- arraytype = *TYPE_POINTER(ivar->type);
- CInit_InitTypeArray(s, s2, &arraytype, ivar->qual, 1);
- s->x18 = arraytype.size;
- } else {
- CInit_InitType(s, s2, ivar->type, ivar->qual, 0);
- }
-
- last_offset = ivar->offset;
- if (!(ivar = CInit_FindNextMember(ivar)) || (tclass->mode == CLASS_MODE_UNION && ivar->offset == last_offset)) {
- if (flag) {
- switch (CInit_ParseNextInit(s2)) {
- case Stage3:
- tk = lex();
- return;
- case Stage2:
- CError_Error(CErrorStr147);
- return;
- default:
- CError_Error(CErrorStr130);
- return;
- }
- }
- return;
- } else {
- switch (CInit_ParseNextInit(s2)) {
- case Stage1:
- case Stage2:
- continue;
- case Stage3:
- if (flag)
- tk = lex();
- break;
- default:
- CError_Error(CErrorStr174);
- }
- return;
- }
- }
-}
-
-static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32 qual, Boolean errorflag) {
- Boolean flag;
-
- switch (type->type) {
- case TYPEVOID:
- CError_Error(CErrorStr174);
- break;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEBITFIELD:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- switch (s2->stage) {
- case Stage1:
- flag = 1;
- CInit_ParseNextInit(s2);
- break;
- case Stage2:
- flag = 0;
- break;
- }
- if (s2->stage != Stage2) {
- CError_Error(CErrorStr174);
- return;
- }
-
- switch (type->type) {
- case TYPEINT:
- CInit_InitTypeInt(s, s2->expr, TYPE_INTEGRAL(type), qual);
- break;
- case TYPEFLOAT:
- CInit_InitTypeFloat(s, s2->expr, TYPE_INTEGRAL(type), qual);
- break;
- case TYPEENUM:
- CInit_InitTypeEnum(s, s2->expr, TYPE_ENUM(type), qual);
- break;
- case TYPEPOINTER:
- CInit_InitTypePointer(s, s2->expr, TYPE_POINTER(type), qual);
- break;
- case TYPEMEMBERPOINTER:
- CInit_InitTypeMemberPointer(s, s2->expr, TYPE_MEMBER_POINTER(type), qual);
- break;
- case TYPEBITFIELD:
- CInit_InitTypeBitfield(s, s2->expr, TYPE_BITFIELD(type), qual);
- break;
- default:
- CError_FATAL(1542);
- }
-
- if (flag) {
- switch (CInit_ParseNextInit(s2)) {
- case Stage3:
- tk = lex();
- break;
- case Stage2:
- CError_Error(CErrorStr147);
- break;
- default:
- CError_Error(CErrorStr130);
- }
- }
- break;
- case TYPESTRUCT:
- CInit_InitTypeStruct(s, s2, TYPE_STRUCT(type), qual, errorflag);
- break;
- case TYPEARRAY:
- CInit_InitTypeArray(s, s2, TYPE_POINTER(type), qual, errorflag);
- break;
- case TYPECLASS:
- CInit_InitTypeClass(s, s2, TYPE_CLASS(type), qual, errorflag);
- break;
- default:
- CError_FATAL(1573);
- }
-}
-
-static void CInit_InitData(CInit_Stuff *s, Type *type, UInt32 qual, Boolean flag) {
- CInit_Stuff2 s2;
- SInt32 size;
- CInit_Stuff *tmp;
- char *buffer;
-
- locklheap();
- memclrw(s, sizeof(CInit_Stuff));
- s->x4 = s;
- if (type->size == 0) {
- if (IS_TYPE_ARRAY(type))
- s->bufferSize = 16 * TYPE_POINTER(type)->target->size;
- else
- CError_Error(CErrorStr145);
- } else {
- s->bufferSize = type->size;
- }
-
- s->buffer = lalloc(s->bufferSize);
- memset(s->buffer, 0, s->bufferSize);
- s->flag = flag;
-
- s2.stage = Stage0;
- s2.x23 = 0;
- if (IS_TYPE_VECTOR(type)) {
- s2.x23 = 1;
- s->flag = 1;
- }
- if (IS_TYPE_ARRAY(type) && IS_TYPE_VECTOR(TYPE_POINTER(type)->target)) {
- s->flag = 1;
- }
-
- s2.type = NULL;
- s2.x24 = 0;
- CInit_ParseNextInit(&s2);
- CInit_InitType(s, &s2, type, qual, 1);
-
- if ((size = type->size + s->x18)) {
- if (s->x0) {
- buffer = lalloc(size);
- for (tmp = s; tmp; tmp = tmp->x0) {
- CError_ASSERT(1647, (tmp->xC + tmp->size) <= size);
- memcpy(buffer + tmp->xC, tmp->buffer, tmp->size);
- }
- s->buffer = buffer;
- }
- } else {
- CError_Error(CErrorStr174);
- }
-
- s->size = size;
- s->x0 = NULL;
- unlocklheap();
-}
-
-static ENode *CInit_InitConcat(ENode *a1, ENode *a2, SInt32 offset, Type *type, ENode *a5) {
- ENode *r30;
- ENode *r28;
- ENode *tmp;
-
- r28 = lalloc(sizeof(ENode));
- *r28 = *a2;
- if (offset)
- r28 = makediadicnode(r28, intconstnode(TYPE(&stunsignedlong), offset), EADD);
-
- if (IS_TYPE_BITFIELD(type)) {
- tmp = makemonadicnode(r28, EBITFIELD);
- tmp->rtype = type;
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = TYPE_BITFIELD(type)->bitfieldtype;
- } else {
- tmp = makemonadicnode(r28, EINDIRECT);
- tmp->rtype = type;
- }
-
- r30 = makediadicnode(tmp, a5, EASS);
- if (!a1) {
- return r30;
- } else {
- tmp = makediadicnode(a1, r30, ECOMMA);
- tmp->rtype = r30->rtype;
- return tmp;
- }
-}
-
-static ENode *CInit_RegisterDtorObject(Type *type, Object *dtor, ENode *objexpr) {
- ENode *expr;
-
- if (copts.no_static_dtors)
- return objexpr;
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->flags = 0;
- expr->rtype = CDecl_NewPointerType(type);
- expr->data.funccall.funcref = create_objectrefnode(Xgreg_func);
- expr->data.funccall.functype = TYPE_FUNC(Xgreg_func->type);
- expr->data.funccall.args = lalloc(sizeof(ENodeList));
- expr->data.funccall.args->node = objexpr;
- expr->data.funccall.args->next = lalloc(sizeof(ENodeList));
- expr->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- expr->data.funccall.args->next->next = lalloc(sizeof(ENodeList));
- expr->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType()));
- expr->data.funccall.args->next->next->next = NULL;
-
- return expr;
-}
-
-static Boolean CInit_ConstructGlobalObject(Object *obj, TypeClass *tclass, ENode *valueexpr, SInt32 offset, Boolean flag) {
- NameSpaceObjectList *ctor;
- Object *dtor;
- ENodeList *list;
- ENode *expr;
- Boolean ctorflag;
-
- ctor = CClass_Constructor(tclass);
- dtor = CClass_Destructor(tclass);
- if (!ctor && !dtor)
- return 0;
-
- if (flag && !ctor && tk == '=' && lookahead() == '{')
- return 0;
-
- if (flag && tk == '(') {
- tk = lex();
- list = CExpr_ScanExpressionList(1);
- if (tk == ')')
- tk = lex();
- else
- CError_Error(CErrorStr115);
- } else if (valueexpr) {
- list = lalloc(sizeof(ENodeList));
- list->node = valueexpr;
- list->next = NULL;
- } else {
- list = NULL;
- }
-
- expr = create_objectrefnode(obj);
- if (offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
-
- if (ctor) {
- ctorflag = 1;
- if (tk == '=') {
- ctorflag = 0;
- if (list)
- CError_Error(CErrorStr174);
-
- list = lalloc(sizeof(ENodeList));
- list->next = NULL;
- tk = lex();
- list->node = conv_assignment_expression();
- }
-
- expr = CExpr_ConstructObject(tclass, expr, list, 0, 1, 0, 1, ctorflag);
- if (expr->rtype->type != TYPEPOINTER) {
- CError_Error(CErrorStr174);
- return 1;
- }
- } else {
- if (list)
- CError_Error(CErrorStr174);
- }
-
- if (dtor)
- expr = CInit_RegisterDtorObject(TYPE(tclass), dtor, expr);
-
- if (cinit_initinfo->x16)
- cinit_initinfo->init_expr_register_cb(expr);
- else
- InitExpr_Register(expr, obj);
-
- return 1;
-}
-
-static Boolean CInit_ConstructAutoObject(TypeClass *tclass, ENode *expr, SInt32 offset, Boolean flag) {
- ENodeList *r30;
- ENode *r29;
- NameSpaceObjectList *ctor;
- Object *dtor;
- Boolean r24;
-
- ctor = CClass_Constructor(tclass);
- dtor = CClass_Destructor(tclass);
- if (!ctor && !dtor)
- return 0;
-
- if (dtor)
- CClass_CheckStaticAccess(NULL, tclass, dtor->access);
-
- if (flag && !ctor && tk == '=' && lookahead() == '{')
- return 0;
-
- if (flag && tk == '(') {
- tk = lex();
- r30 = CExpr_ScanExpressionList(1);
- if (tk == ')')
- tk = lex();
- else
- CError_Error(CErrorStr115);
- } else if (expr) {
- r30 = lalloc(sizeof(ENodeList));
- r30->node = expr;
- r30->next = NULL;
- } else {
- r30 = NULL;
- }
-
- if (ctor) {
- r24 = 1;
- if (tk == '=') {
- if (r30)
- CError_Error(CErrorStr174);
- r30 = lalloc(sizeof(ENodeList));
- r30->next = NULL;
- tk = lex();
- r30->node = conv_assignment_expression();
- r24 = 0;
- }
-
- if (!dtor) {
- r29 = create_objectrefnode(cinit_initinfo->obj1C);
- if (offset)
- r29 = makediadicnode(r29, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- } else {
- r29 = cinit_initinfo->register_object_cb(TYPE(tclass), cinit_initinfo->obj1C, offset, 0);
- }
-
- r29 = CExpr_ConstructObject(tclass, r29, r30, 0, 1, 0, 1, r24);
- if (!IS_TYPE_POINTER_ONLY(r29->rtype)) {
- CError_Error(CErrorStr174);
- return 1;
- }
- r29 = makemonadicnode(r29, EINDIRECT);
- r29->rtype = TYPE_POINTER(r29->rtype)->target;
- cinit_initinfo->insert_expr_cb(r29);
- } else {
- if (r30)
- CError_Error(CErrorStr174);
- if (dtor)
- r29 = cinit_initinfo->register_object_cb(TYPE(tclass), cinit_initinfo->obj1C, offset, 0);
- cinit_initinfo->insert_expr_cb(r29);
- }
-
- return 1;
-}
-
-static void CInit_ExprPointer(TypePointer *tptr, ENode *expr) {
- Object *obj;
- CInt64 val;
- OLinkList *list;
-
- if (CInit_RelocInitCheck(expr, &obj, &val, 0)) {
- if (obj) {
- list = lalloc(sizeof(OLinkList));
- list->next = cinit_initinfo->list;
- list->obj = obj;
- list->somevalue = CInt64_GetULong(&val);
- list->offset = cinit_initinfo->expr_offset;
- cinit_initinfo->list = list;
- } else {
- CMach_InitIntMem(TYPE(&stunsignedlong), val, cinit_initinfo->buffer + cinit_initinfo->expr_offset);
- }
- } else if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(TYPE(tptr), expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
-
- cinit_initinfo->expr_offset += 4;
-}
-
-static void CInit_ExprInt(TypeIntegral *tint, ENode *expr) {
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(TYPE(tint), expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset);
- } else if (ENODE_IS(expr, ETYPCON) && IS_TYPE_POINTER_ONLY(expr->data.monadic->rtype) && expr->rtype->size == 4 && (copts.cplusplus || !copts.ANSIstrict)) {
- CInit_ExprPointer(TYPE_POINTER(expr->data.monadic->rtype), expr->data.monadic);
- } else if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(TYPE(tint), expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
-
- cinit_initinfo->expr_offset += tint->size;
-}
-
-static void CInit_ExprFloat(TypeIntegral *tint, ENode *expr) {
- if (ENODE_IS(expr, EFLOATCONST)) {
- CMach_InitFloatMem(TYPE(tint), expr->data.floatval, cinit_initinfo->buffer + cinit_initinfo->expr_offset);
- } else if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(TYPE(tint), expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
-
- cinit_initinfo->expr_offset += tint->size;
-}
-
-static void CInit_ExprEnum(TypeEnum *tenum, ENode *expr) {
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(tenum->enumtype, expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset);
- } else if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(TYPE(tenum), expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
-
- cinit_initinfo->expr_offset += tenum->size;
-}
-
-static void CInit_ExprMemberPointer(TypeMemberPointer *tmptr, ENode *expr) {
- if (ENODE_IS(expr, EINTCONST)) {
- CMach_InitIntMem(TYPE(&stsignedlong), expr->data.intval, cinit_initinfo->buffer + cinit_initinfo->expr_offset);
- } else if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(TYPE(tmptr), expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
-
- cinit_initinfo->expr_offset += tmptr->size;
-}
-
-static void CInit_TypeExpr(Type *type, ENode *expr) {
- switch (type->type) {
- case TYPEINT:
- CInit_ExprInt(TYPE_INTEGRAL(type), expr);
- break;
- case TYPEFLOAT:
- CInit_ExprFloat(TYPE_INTEGRAL(type), expr);
- break;
- case TYPEENUM:
- CInit_ExprEnum(TYPE_ENUM(type), expr);
- break;
- case TYPEPOINTER:
- CInit_ExprPointer(TYPE_POINTER(type), expr);
- break;
- case TYPEMEMBERPOINTER:
- CInit_ExprMemberPointer(TYPE_MEMBER_POINTER(type), expr);
- break;
- case TYPESTRUCT:
- case TYPECLASS:
- if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(type, expr, 0);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr124);
- }
- break;
- case TYPEARRAY:
- CError_Error(CErrorStr174);
- break;
- default:
- CError_FATAL(2082);
- }
-}
-
-static void CInit_Bitfield(TypeBitfield *tbitfield) {
- Boolean r30;
- ENode *expr;
- ENode myexpr;
-
- r30 = tk == '{';
- if (r30)
- tk = lex();
-
- expr = CInit_ParseInitializer(&myexpr);
- expr = CExpr_AssignmentPromotion(
- expr,
- IS_TYPE_ENUM(tbitfield->bitfieldtype) ? TYPE_ENUM(tbitfield->bitfieldtype)->enumtype : tbitfield->bitfieldtype,
- 0,
- 1);
- if (ENODE_IS(expr, EINTCONST))
- CInit_SetBitfield(tbitfield, (UInt8 *) cinit_initinfo->buffer + cinit_initinfo->expr_offset, expr->data.intval);
- else
- CError_Error(CErrorStr124);
-
- if (r30)
- CInit_CloseInitList();
-}
-
-static void CInit_Array(TypePointer *tptr, UInt32 qual, Boolean flag) {
- SInt32 start;
- SInt32 i;
- SInt32 targetsize1;
- SInt32 targetsize2;
- Boolean in_block;
- Boolean is_char_ptr;
- Boolean needs_construction;
- Boolean is_wchar_ptr;
-
- targetsize1 = tptr->target->size;
- targetsize2 = tptr->target->size;
- if (!tptr->target->size) {
- if (!IS_TYPE_ARRAY(tptr->target)) {
- CError_Error(CErrorStr145);
- return;
- }
- targetsize1 = tptr->target->size;
- targetsize2 = tptr->target->size;
- if (!tptr->target->size) {
- CError_Error(CErrorStr145);
- return;
- }
- }
-
- is_char_ptr = IS_TYPE_INT(tptr->target) && (tptr->target->size == 1);
- is_wchar_ptr = IS_TYPE_INT(tptr->target) && (tptr->target->size == stwchar.size);
-
- in_block = 1;
- if (flag && !(tk == TK_STRING && is_char_ptr) && !(tk == TK_STRING_WIDE && is_wchar_ptr)) {
- if (tk != '{') {
- CError_ErrorSkip(CErrorStr135);
- return;
- }
- tk = lex();
- } else {
- if (tk == '{')
- tk = lex();
- else
- in_block = 0;
- }
-
- if ((tk == TK_STRING && is_char_ptr) || (tk == TK_STRING_WIDE && is_wchar_ptr)) {
- if (tptr->size) {
- if (tksize > tptr->size) {
- if (copts.cplusplus || (tksize - (is_wchar_ptr ? stwchar.size : 1)) > tptr->size)
- CError_Error(CErrorStr147);
- tksize = tptr->size;
- }
- memcpy(cinit_initinfo->buffer + cinit_initinfo->expr_offset, tkstring, tksize);
- } else {
- tptr->size = tksize;
- CInit_SetData(tkstring, cinit_initinfo->expr_offset, tptr->size);
- }
- cinit_initinfo->expr_offset += tptr->size;
- tk = lex();
- if (in_block)
- CInit_CloseInitList();
- return;
- }
-
- if (IS_TYPE_CLASS(tptr->target) && CInit_ClassNeedsConstruction(TYPE_CLASS(tptr->target)))
- needs_construction = 1;
- else
- needs_construction = 0;
-
- start = cinit_initinfo->expr_offset;
- i = 0;
- while (1) {
- if (tk == '}') {
- innerloop:
- if (tptr->size) {
- if (needs_construction) {
- while (tptr->size > (i * targetsize1)) {
- cinit_initinfo->expr_offset = start + i * targetsize2;
- if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(tptr->target, NULL, 1);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr174);
- }
- i++;
- }
- }
- } else {
- tptr->size = i * targetsize1;
- }
- cinit_initinfo->expr_offset = start + tptr->size;
- if (in_block)
- tk = lex();
- return;
- }
-
- if (!tptr->size) {
- cinit_initinfo->expr_offset = start + i * targetsize2;
- CInit_SetData(NULL, cinit_initinfo->expr_offset, targetsize2);
- if (needs_construction) {
- if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(tptr->target, conv_assignment_expression(), 1);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr174);
- }
- } else {
- CInit_Type(tptr->target, qual, 0);
- }
- } else {
- if (tptr->size <= i * targetsize1) {
- i--;
- CError_Error(CErrorStr147);
- }
-
- cinit_initinfo->expr_offset = start + i * targetsize2;
- if (needs_construction) {
- if (cinit_initinfo->expr_cb) {
- cinit_initinfo->expr_cb(tptr->target, conv_assignment_expression(), 1);
- cinit_initinfo->expr_cb_called = 1;
- } else {
- CError_Error(CErrorStr174);
- }
- } else {
- CInit_Type(tptr->target, qual, 0);
- }
-
- if (!in_block) {
- if (tptr->size <= (i + 1) * targetsize1)
- return;
- }
- }
-
- if (tk != '}') {
- if (tk != ',') {
- CError_ErrorSkip(CErrorStr121);
- in_block = 0;
- i++;
- goto innerloop;
- }
- tk = lex();
- }
- i++;
- }
-}
-
-static void CInit_Struct(TypeStruct *tstruct, Boolean flag) {
- StructMember *member;
- SInt32 start;
- Boolean in_block;
-
- if (!(member = tstruct->members)) {
- CError_Error(CErrorStr145);
- return;
- }
-
- if (tstruct->stype == STRUCT_TYPE_UNION) {
- if (tk == '{') {
- tk = lex();
- CInit_Type(member->type, member->qual, 0);
- if (tk == '}')
- tk = lex();
- } else {
- CInit_Type(member->type, member->qual, 0);
- }
- return;
- }
-
- if (IS_TYPE_VECTOR(tstruct) && tk != '{') {
- CInit_TypeExpr(TYPE(tstruct), CExpr_AssignmentPromotion(conv_assignment_expression(), TYPE(tstruct), 0, 1));
- return;
- }
-
- if (tk != '{') {
- if (flag)
- CError_ErrorSkip(CErrorStr135);
- in_block = 0;
- } else {
- in_block = 1;
- tk = lex();
- }
-
- start = cinit_initinfo->expr_offset;
- while (1) {
- if (tk == '}')
- break;
-
- cinit_initinfo->expr_offset = start + member->offset;
- if (!member->type->size && IS_TYPE_ARRAY(member->type)) {
- CError_Error(CErrorStr147);
- break;
- }
-
- CInit_Type(member->type, member->qual, 0);
- if (tk == '}')
- break;
-
- if (tk != ',') {
- CError_Error(CErrorStr121);
- break;
- }
-
- do {
- member = member->next;
- } while (member && (member->qual & Q_WEAK));
-
- if (!member) {
- if (!in_block)
- break;
- if ((tk = lex()) != '}') {
- CError_Error(CErrorStr147);
- break;
- }
- } else {
- tk = lex();
- }
- }
-
- cinit_initinfo->expr_offset = start + tstruct->size;
- if (tk == '}' && in_block)
- tk = lex();
-}
-
-static void CInit_Class(TypeClass *tclass, Boolean flag) {
- ObjMemberVar *ivar;
- SInt32 start;
- Boolean in_block;
-
- if (tk == '{') {
- in_block = 1;
- tk = lex();
- } else {
- in_block = 0;
- }
-
- if (tclass->bases || tclass->vtable) {
- CError_Error(CErrorStr174);
- return;
- }
-
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->access != ACCESSPUBLIC)
- break;
- }
-
- if (!ivar && !CClass_Constructor(tclass) && (!CClass_Destructor(tclass) || in_block)) {
- if ((ivar = tclass->ivars)) {
- start = cinit_initinfo->expr_offset;
- while (1) {
- if (tk == '}')
- break;
-
- if (!ivar->type->size && IS_TYPE_ARRAY(ivar->type)) {
- CError_Error(CErrorStr147);
- break;
- }
-
- cinit_initinfo->expr_offset = start + ivar->offset;
- CInit_Type(ivar->type, ivar->qual, 0);
-
- if (tk == '}')
- break;
-
- if (tk != ',') {
- CError_Error(CErrorStr121);
- break;
- }
-
- do {
- ivar = ivar->next;
- } while (ivar && ivar->anonunion);
-
- if (!ivar) {
- if (!in_block)
- break;
- if ((tk = lex()) != '}') {
- CError_Error(CErrorStr147);
- break;
- }
- } else {
- tk = lex();
- }
- }
- } else {
- if (in_block && tk != '}')
- CError_Error(CErrorStr147);
- }
- } else {
- if (in_block)
- CError_Error(CErrorStr174);
- CInit_TypeExpr(TYPE(tclass), CExpr_AssignmentPromotion(conv_assignment_expression(), TYPE(tclass), 0, 1));
- }
-
- cinit_initinfo->expr_offset = start + tclass->size;
- if (tk == '}' && in_block)
- tk = lex();
-}
-
-static void CInit_Type(Type *type, UInt32 qual, Boolean flag) {
- ENode *expr;
- ENode myexpr;
-
- switch (type->type) {
- case TYPEVOID:
- CError_Error(CErrorStr174);
- break;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEPOINTER:
- case TYPEMEMBERPOINTER:
- if (tk == '{') {
- tk = lex();
- expr = CInit_ParseInitializer(&myexpr);
- expr = CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1);
- CInit_CloseInitList();
- } else {
- expr = CInit_ParseInitializer(&myexpr);
- expr = CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1);
- }
- CInit_TypeExpr(type, expr);
- break;
- case TYPEBITFIELD:
- CInit_Bitfield(TYPE_BITFIELD(type));
- break;
- case TYPEARRAY:
- CInit_Array(TYPE_POINTER(type), qual, flag);
- break;
- case TYPESTRUCT:
- CInit_Struct(TYPE_STRUCT(type), flag);
- break;
- case TYPECLASS:
- CInit_Class(TYPE_CLASS(type), flag);
- break;
- default:
- CError_FATAL(2482);
- }
-}
-
-static void CInit_GlobalStaticInit(Type *type, ENode *valueexpr, Boolean flag) {
- ENode *expr;
- ENode *tmp;
-
- cinit_initinfo->x15 = 1;
- if (flag) {
- CInit_ConstructGlobalObject(cinit_initinfo->obj, TYPE_CLASS(type), valueexpr, cinit_initinfo->expr_offset, 0);
- } else {
- expr = create_objectrefnode(cinit_initinfo->obj);
- if (!IS_TYPE_POINTER_ONLY(expr->rtype)) {
- CError_Error(CErrorStr174);
- return;
- }
- TYPE_POINTER(expr->rtype)->target = type;
-
- if (cinit_initinfo->expr_offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD);
-
- tmp = makemonadicnode(expr, EINDIRECT);
- tmp->rtype = type;
- expr = makediadicnode(tmp, valueexpr, EASS);
- if (cinit_initinfo->x16)
- cinit_initinfo->init_expr_register_cb(expr);
- else
- InitExpr_Register(expr, cinit_initinfo->obj);
- }
-}
-
-static void CInit_AutoInit(Type *type, ENode *valueexpr, Boolean flag) {
- ENode *expr;
- ENode *tmp;
- Type *copy;
- SInt32 size;
-
- if (flag) {
- CInit_ConstructAutoObject(TYPE_CLASS(type), valueexpr, cinit_initinfo->expr_offset, 0);
- } else {
- if (IS_TYPE_ARRAY(type) && (type->size & 1)) {
- copy = galloc(sizeof(TypePointer));
- *TYPE_POINTER(copy) = *TYPE_POINTER(type);
- type = copy;
- copy->size++;
- }
- expr = create_objectrefnode(cinit_initinfo->obj1C);
- if (!IS_TYPE_POINTER_ONLY(expr->rtype)) {
- CError_Error(CErrorStr174);
- return;
- }
- TYPE_POINTER(expr->rtype)->target = type;
-
- if (cinit_initinfo->expr_offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD);
-
- tmp = makemonadicnode(expr, EINDIRECT);
- tmp->rtype = type;
- expr = makediadicnode(tmp, valueexpr, EASS);
- if (!copts.cplusplus)
- CError_Error(CErrorStr124);
- cinit_initinfo->insert_expr_cb(expr);
- }
-}
-
-static SInt32 CInit_AdjustObjectDataSize(Object *obj) {
- if (obj->type->size <= 1)
- return obj->type->size;
- if (obj->type->size & 1)
- return obj->type->size + 1;
- else
- return obj->type->size;
-}
-
-static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB expr_cb, Boolean flag) {
- Object *r31;
- ENode *expr;
- ENode *tmpexpr;
- Type *inner;
- Type *copy;
- SInt32 size;
- Boolean lastflag;
- SInt16 cv;
-
- cinit_initinfo->expr_cb = expr_cb;
- expr = NULL;
-
- if (tk == '(') {
- if (IS_TYPE_ARRAY(type))
- CError_Error(CErrorStr174);
- tk = lex();
- expr = CExpr_AssignmentPromotion(assignment_expression(), type, qual, 1);
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
- goto jump_ahead;
- }
-
- tk = lex();
- switch (type->type) {
- case TYPECLASS:
- if (tk == '{' && CClass_Constructor(TYPE_CLASS(type)))
- CError_Error(CErrorStr174);
- case TYPESTRUCT:
- if (tk != '{')
- goto generic_type;
- case TYPEARRAY:
- if (!obj) {
- if (IS_TYPE_ARRAY(type)) {
- inner = type;
- while (IS_TYPE_ARRAY(inner))
- inner = TYPE_POINTER(inner)->target;
-
- if (IS_TYPE_CLASS(inner) && CInit_ClassNeedsConstruction(TYPE_CLASS(inner))) {
- CInit_SetupInitInfoBuffer(type);
- cinit_initinfo->obj = cinit_initinfo->obj1C;
- CInit_Type(type, cinit_initinfo->obj->qual, 1);
- return 0;
- }
- if (type->size & 1) {
- copy = galloc(sizeof(TypePointer));
- *TYPE_POINTER(copy) = *TYPE_POINTER(type);
- type = copy;
- type->size++;
- }
- }
-
- obj = CInit_CreateStaticDataObject(type, qual, NULL);
- cinit_initinfo->obj = obj;
- expr = create_objectnode(obj);
- cinit_initinfo->obj1C = obj;
- }
- CInit_SetupInitInfoBuffer(type);
- CInit_Type(type, obj->qual, 1);
- CError_ASSERT(2639, obj->type->size == (size = cinit_initinfo->size));
- if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, size)) {
- CInit_AdjustObjectDataSize(obj);
- CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
- } else {
- CInit_AdjustObjectDataSize(obj);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- return expr;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPEPOINTER:
- case TYPEMEMBERPOINTER:
- generic_type:
- if (obj)
- cv = obj->qual & Q_CV;
- else
- cv = cinit_initinfo->obj1C->qual & Q_CV;
-
- if (tk == '{') {
- tk = lex();
- expr = assignment_expression();
- CInit_CloseInitList();
- } else {
- expr = assignment_expression();
- }
- expr = CExpr_AssignmentPromotion(expr, type, cv, 1);
- jump_ahead:
- if (obj == NULL)
- r31 = cinit_initinfo->obj1C;
- else
- r31 = obj;
-
- if (is_const_object(r31)) {
- switch (r31->type->type) {
- case TYPEINT:
- case TYPEENUM:
- if (ENODE_IS(expr, EINTCONST)) {
- r31->u.data.u.intconst = expr->data.intval;
- goto common_8068C;
- }
- break;
- case TYPEFLOAT:
- if (ENODE_IS(expr, EFLOATCONST)) {
- Float fl;
- r31->u.data.u.floatconst = galloc(sizeof(Float));
- fl = CMach_CalcFloatConvert(r31->type, expr->data.floatval);
- *r31->u.data.u.floatconst = fl;
- goto common_8068C;
- }
- break;
- case TYPEPOINTER:
- tmpexpr = expr;
- while (ENODE_IS(tmpexpr, ETYPCON))
- tmpexpr = tmpexpr->data.monadic;
- if (!ENODE_IS(tmpexpr, EINTCONST))
- break;
- r31->u.data.u.intconst = tmpexpr->data.intval;
- common_8068C:
- r31->qual |= Q_INLINE_DATA;
- if (!obj) {
- r31->sclass = TK_STATIC;
- r31->datatype = DDATA;
- r31->u.data.linkname = CParser_AppendUniqueName(r31->name->name);
- } else if (r31->sclass != TK_STATIC || (r31->flags & OBJECT_FLAGS_2)) {
- CInit_ExportConst(r31);
- }
- return NULL;
- }
- }
-
- if (!obj || (flag && copts.cplusplus)) {
- if (obj) {
- IsCompleteType(obj->type);
- CError_ASSERT(2747, obj->type->size == type->size);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- return expr;
- }
-
- CInit_SetupInitInfoBuffer(type);
- CInit_TypeExpr(type, expr);
- CError_ASSERT(2756, obj->type->size == cinit_initinfo->size);
-
- IsCompleteType(obj->type);
- CInit_AdjustObjectDataSize(obj);
- lastflag = !cinit_initinfo->x15 && is_const_object(r31);
- if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) {
- if (lastflag)
- CInit_DeclareReadOnlyData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
- else
- CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
- } else {
- if (lastflag)
- CInit_DeclareReadOnlyData(obj, NULL, NULL, obj->type->size);
- else
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- break;
-
- default:
- CError_FATAL(2776);
- }
-
- return NULL;
-}
-
-void CInit_ExportConst(Object *obj) {
- char buffer[64];
-
- if (obj->flags & OBJECT_DEFINED)
- return;
-
- switch (obj->type->type) {
- case TYPEINT:
- CMach_InitIntMem(obj->type, obj->u.data.u.intconst, buffer);
- break;
- case TYPEENUM:
- CMach_InitIntMem(TYPE_ENUM(obj->type)->enumtype, obj->u.data.u.intconst, buffer);
- break;
- case TYPEPOINTER:
- CMach_InitIntMem(TYPE(&stunsignedlong), obj->u.data.u.intconst, buffer);
- break;
- case TYPEFLOAT:
- CMach_InitFloatMem(obj->type, *obj->u.data.u.floatconst, buffer);
- break;
- default:
- CError_FATAL(2807);
- }
-
- if (is_const_object(obj))
- CInit_DeclareReadOnlyData(obj, buffer, NULL, obj->type->size);
- else
- CInit_DeclareData(obj, buffer, NULL, obj->type->size);
-}
-
-static ENode *CInit_ClassInitLoopCallBack(ENode *expr) {
- return CExpr_ConstructObject(cinit_loop_class, expr, NULL, 0, 1, 0, 1, 1);
-}
-
-Statement *CInit_ConstructClassArray(Statement *stmt, TypeClass *tclass, Object *ctor, Object *dtor, ENode *firstarg, SInt32 count) {
- ENode *dtor_expr;
-
- if (stmt)
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- else
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
-
- if (dtor)
- dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- else
- dtor_expr = nullnode();
-
- stmt->expr = CExpr_FuncCallSix(
- carr_func,
- firstarg,
- create_objectrefnode(ctor),
- dtor_expr,
- intconstnode(TYPE(&stunsignedlong), tclass->size),
- intconstnode(TYPE(&stunsignedlong), count),
- NULL
- );
-
- return stmt;
-}
-
-static void CInit_InitializeClassArray(Object *obj, TypeClass *tclass, Boolean flag) {
- Object *ctor;
- Object *dtor;
- SInt32 count;
- SInt32 i;
- ENode *expr;
- SInt32 offset;
- ENode *dtor_expr;
- Statement *stmt;
- TypeFunc *tfunc;
- Object *funcobj;
-
- dtor = CClass_Destructor(tclass);
- count = obj->type->size / tclass->size;
- if (CClass_Constructor(tclass)) {
- ctor = CClass_DefaultConstructor(tclass);
- if (!ctor) {
- ctor = CClass_DummyDefaultConstructor(tclass);
- if (!ctor) {
- CError_Error(CErrorStr203);
- return;
- }
- }
- } else {
- ctor = NULL;
- }
-
- if (count <= 1 || (!flag && count <= 8)) {
- if (flag) {
- for (i = 0; i < count; i++) {
- CInit_ConstructGlobalObject(obj, tclass, NULL, i * tclass->size, 0);
- }
- } else {
- for (i = 0; i < count; i++) {
- offset = i * tclass->size;
- expr = create_objectrefnode(obj);
- if (offset)
- expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD);
- if (ctor)
- expr = CExpr_ConstructObject(tclass, expr, NULL, 0, 1, 0, 1, 1);
- cinit_initinfo->insert_expr_cb(expr);
- if (dtor)
- CExcept_RegisterDestructorObject(obj, offset, dtor, 1);
- }
- if (dtor) {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = nullnode();
- }
- }
- } else {
- if (ctor) {
- if (!flag && !dtor) {
- CInit_ConstructClassArray(NULL, tclass, ctor, dtor, create_objectrefnode(obj), count);
- expr = nullnode();
- } else {
- if (dtor)
- dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- else
- dtor_expr = nullnode();
- expr = CExpr_FuncCallSix(
- carr_func,
- create_objectrefnode(obj),
- create_objectrefnode(ctor),
- dtor_expr,
- intconstnode(TYPE(&stunsignedlong), tclass->size),
- intconstnode(TYPE(&stunsignedlong), count),
- NULL
- );
- }
- } else {
- expr = nullnode();
- }
-
- if (flag) {
- if (dtor && !copts.no_static_dtors) {
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = &stvoid;
- CDecl_SetFuncFlags(tfunc, 1);
-
- funcobj = CParser_NewCompilerDefFunctionObject();
- funcobj->name = CParser_AppendUniqueName("__arraydtor");
- funcobj->type = TYPE(tfunc);
- funcobj->sclass = TK_STATIC;
- funcobj->qual = Q_INLINE;
-
- CParser_RegisterSingleExprFunction(funcobj, funccallexpr(
- darr_func,
- create_objectrefnode(obj),
- create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)),
- intconstnode(TYPE(&stsignedlong), tclass->size),
- intconstnode(TYPE(&stsignedlong), count)
- ));
-
- expr = makediadicnode(expr, nullnode(), ECOMMA);
- expr->rtype = TYPE(&void_ptr);
-
- expr = funccallexpr(
- Xgreg_func,
- expr,
- create_objectrefnode(funcobj),
- create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType())),
- NULL
- );
- }
- if (cinit_initinfo->x16)
- cinit_initinfo->init_expr_register_cb(expr);
- else
- InitExpr_Register(expr, obj);
- } else {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = expr;
- if (dtor) {
- CExcept_RegisterLocalArray(stmt, obj, dtor, count, tclass->size);
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = nullnode();
- }
- }
- }
-}
-
-static ENode *CInit_AutoTempNode(Type *type, Boolean flag) {
- ENode *node;
- node = CExpr_NewETEMPNode(type, 0);
- if (IS_TYPE_CLASS(type) && CClass_Destructor(TYPE_CLASS(type)))
- node->data.temp.needs_dtor = 1;
- return node;
-}
-
-static ENode *CInit_GlobalTempNode(Type *type, Boolean flag) {
- Object *dtor;
- ENode *node;
- ENode *funcnode;
-
- node = create_objectrefnode(CInit_CreateStaticData(type));
- if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type))) && !copts.no_static_dtors) {
- if (flag)
- CError_Error(CErrorStr190);
-
- funcnode = galloc(sizeof(ENode));
- funcnode->type = EFUNCCALL;
- funcnode->cost = 200;
- funcnode->flags = 0;
- funcnode->rtype = CDecl_NewPointerType(type);
- funcnode->data.funccall.funcref = create_objectrefnode(Xgreg_func);
- funcnode->data.funccall.functype = TYPE_FUNC(Xgreg_func->type);
- funcnode->data.funccall.args = lalloc(sizeof(ENodeList));
- funcnode->data.funccall.args->node = node;
- funcnode->data.funccall.args->next = lalloc(sizeof(ENodeList));
- funcnode->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1));
- funcnode->data.funccall.args->next->next = lalloc(sizeof(ENodeList));
- funcnode->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType()));;
- funcnode->data.funccall.args->next->next->next = NULL;
- node = funcnode;
- }
- return node;
-}
-
-static void CInit_RefInit(Type *type, ENode *expr, Boolean flag) {
- ENode *objexpr;
-
- objexpr = create_objectrefnode(cinit_initinfo->obj);
- if (!IS_TYPE_POINTER_ONLY(objexpr->rtype)) {
- CError_Error(CErrorStr174);
- return;
- }
- TYPE_POINTER(objexpr->rtype)->target = type;
-
- if (cinit_initinfo->expr_offset)
- objexpr = makediadicnode(objexpr, intconstnode(TYPE(&stunsignedlong), cinit_initinfo->expr_offset), EADD);
-
- objexpr = makemonadicnode(objexpr, EINDIRECT);
- objexpr->rtype = type;
-
- expr = makediadicnode(objexpr, expr, EASS);
- if (cinit_initinfo->x16)
- cinit_initinfo->init_expr_register_cb(expr);
- else
- InitExpr_Register(expr, cinit_initinfo->obj);
-}
-
-static Boolean CInit_IsDtorTemp(ENode *expr) {
- return ENODE_IS(expr, ETEMP) && expr->data.temp.needs_dtor;
-}
-
-static void CInit_FindDtorTemp(ENode *expr) {
- ENodeList *list;
-
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.right;
-
- if (IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_CLASS(TYPE_POINTER(expr->rtype)->target)) {
- switch (expr->type) {
- case ETYPCON:
- CInit_FindDtorTemp(expr->data.monadic);
- break;
- case EADD:
- case ESUB:
- CInit_FindDtorTemp(expr->data.diadic.left);
- CInit_FindDtorTemp(expr->data.diadic.right);
- break;
- case EFUNCCALL:
- case EFUNCCALLP:
- if ((list = expr->data.funccall.args)) {
- if (CInit_IsDtorTemp(list->node) || ((list = list->next) && CInit_IsDtorTemp(list->node))) {
- if (!cinit_fdtnode)
- cinit_fdtnode = list;
- else
- cinit_fdtambig = 1;
- }
- }
- break;
- }
- }
-}
-
-static void CInit_RefTempTransform(Type *type, ENode *expr) {
- Object *obj;
-
- CError_ASSERT(3164, IS_TYPE_POINTER_ONLY(type));
-
- if (IS_TYPE_CLASS(TYPE_POINTER(type)->target)) {
- cinit_fdtnode = NULL;
- cinit_fdtambig = 0;
- CInit_FindDtorTemp(expr);
- if (cinit_fdtnode) {
- CError_ASSERT(3172, !cinit_fdtambig);
- obj = create_temp_object(cinit_fdtnode->node->data.temp.type);
- cinit_initinfo->register_object_cb(cinit_fdtnode->node->data.temp.type, obj, 0, 0);
- cinit_fdtnode->node = create_objectrefnode(obj);
- }
- }
-}
-
-static Boolean CInit_InitReference(Object *obj, Boolean flag) {
- ENode *expr;
-
- if (tk == '=') {
- cinit_tempnodefunc = flag ? CInit_AutoTempNode : CInit_GlobalTempNode;
- tk = lex();
- expr = CExpr_AssignmentPromotion(assignment_expression(), obj->type, obj->qual & (Q_CONST | Q_VOLATILE), 1);
- cinit_tempnodefunc = NULL;
-
- if (flag) {
- CInit_RefTempTransform(obj->type, expr);
- expr = makediadicnode(create_objectnode2(obj), expr, EASS);
- cinit_initinfo->insert_expr_cb(expr);
- } else {
- cinit_initinfo->expr_cb = CInit_RefInit;
- CInit_SetupInitInfoBuffer(obj->type);
- CInit_ExprPointer(TYPE_POINTER(obj->type), expr);
- CError_ASSERT(3213, obj->type->size == cinit_initinfo->size);
-
- if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) {
- IsCompleteType(obj->type);
- CInit_AdjustObjectDataSize(obj);
- CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
- } else {
- IsCompleteType(obj->type);
- CInit_AdjustObjectDataSize(obj);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- }
-
- return 1;
- }
-
- return 0;
-}
-
-ENode *CInit_AutoObject(Object *obj, Type *type, UInt32 qual) {
- CInit_Stuff s;
- CInit_1C *entry;
- ENode *expr;
- ENode *indirect_expr;
- ENode *obj_expr;
- ENode *const_expr;
- Type *newtype;
- Object *newobj;
-
- CInit_InitData(&s, type, qual, copts.cplusplus || copts.gcc_extensions || copts.c9x || !obj);
- if (!obj && !cscope_currentfunc) {
- obj = CParser_NewCompilerDefDataObject();
- obj->name = CParser_GetUniqueName();
- obj->type = type;
- obj->qual = qual;
- obj->sclass = TK_STATIC;
- CScope_AddGlobalObject(obj);
- }
-
- if (IS_TYPE_VECTOR(type) && !s.x1C) {
- if (obj)
- obj_expr = create_objectrefnode(obj);
- else
- obj_expr = CExpr_NewETEMPNode(type, 1);
-
- const_expr = CExpr_NewENode(EVECTOR128CONST);
- const_expr->rtype = type;
- const_expr->data.vector128val = *((MWVector128 *) s.buffer);
-
- indirect_expr = makemonadicnode(obj_expr, EINDIRECT);
- indirect_expr->rtype = type;
-
- expr = makediadicnode(indirect_expr, const_expr, EASS);
- if (!obj) {
- ENode *tmp = lalloc(sizeof(ENode));
- *tmp = *obj_expr;
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = type;
- tmp->flags = qual & ENODE_FLAG_QUALS;
- expr = makecommaexpression(expr, tmp);
- }
- return expr;
- }
-
- if (s.x18) {
- type = CDecl_NewStructType(type->size + s.x18, CMach_GetTypeAlign(type));
- if (obj)
- obj->type = type;
- }
-
- if (obj)
- obj_expr = create_objectrefnode(obj);
- else
- obj_expr = CExpr_NewETEMPNode(type, 1);
-
- newtype = type;
- if (IS_TYPE_ARRAY(type))
- newtype = CDecl_NewStructType(type->size, CMach_GetTypeAlign(type));
- newobj = CInit_CreateStaticDataObject(newtype, 0, NULL);
- if (s.list || !CInit_IsAllZero(s.buffer, s.size))
- CInit_DeclareReadOnlyData(newobj, s.buffer, s.list, s.size);
- else
- CInit_DeclareReadOnlyData(newobj, NULL, NULL, s.size);
-
- indirect_expr = makemonadicnode(obj_expr, EINDIRECT);
- indirect_expr->rtype = newtype;
- expr = makediadicnode(indirect_expr, create_objectnode(newobj), EASS);
-
- for (entry = s.x1C; entry; entry = entry->next) {
- expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr);
- }
-
- if (!obj) {
- ENode *tmp = lalloc(sizeof(ENode));
- *tmp = *obj_expr;
- tmp = makemonadicnode(tmp, EINDIRECT);
- tmp->rtype = type;
- tmp->flags = qual & ENODE_FLAG_QUALS;
- expr = makecommaexpression(expr, tmp);
- } else if (IS_TYPE_ARRAY(type)) {
- expr = makecommaexpression(expr, create_objectnode(obj));
- }
-
- return expr;
-}
-
-static void CInit_GlobalObject(Object *obj) {
- CInit_Stuff s;
- CInit_1C *entry;
- ENode *obj_expr;
- ENode *expr;
-
- CInit_InitData(&s, obj->type, obj->qual, copts.cplusplus);
- obj_expr = create_objectrefnode(obj);
-
- IsCompleteType(obj->type);
-
- if (!s.x1C && is_const_object(obj))
- CInit_DeclareReadOnlyData(obj, s.buffer, s.list, s.size);
- else
- CInit_DeclareData(obj, s.buffer, s.list, s.size);
-
- if (s.x1C) {
- entry = s.x1C;
- expr = NULL;
- while (entry) {
- if (!ENODE_IS(entry->expr, EVECTOR128CONST))
- expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr);
- entry = entry->next;
- }
-
- if (expr)
- InitExpr_Register(expr, obj);
- }
-}
-
-void CInit_InitializeAutoData(Object *obj, InsertExprCB insert_cb, RegisterObjectCB register_cb) {
- ENode *expr;
- Type *type;
- InitInfo initinfo;
-
- if (CInit_IsSimpleStructArrayInit(obj->type)) {
- if (tk == '=' || (tk == '(' && copts.cplusplus)) {
- if (tk == '(') {
- tk = lex();
- expr = conv_assignment_expression();
- if (tk != ')')
- CError_Error(CErrorStr115);
- tk = lex();
- } else if (tk == '=' && ((tk = lex()) == '{' || IS_TYPE_ARRAY(obj->type))) {
- insert_cb(CInit_AutoObject(obj, obj->type, obj->qual));
- return;
- } else {
- expr = conv_assignment_expression();
- }
- expr = CExpr_AssignmentPromotion(expr, obj->type, obj->qual & (Q_CONST | Q_VOLATILE), 1);
- insert_cb(makediadicnode(create_objectnode2(obj), expr, EASS));
- } else if (copts.cplusplus && is_const_object(obj)) {
- CError_Error(CErrorStr224);
- }
-
- return;
- }
-
- CInit_SetupInitInfo(&initinfo, obj);
- initinfo.obj1C = obj;
- initinfo.insert_expr_cb = insert_cb;
- initinfo.register_object_cb = register_cb;
-
- if (IS_TYPE_CLASS(obj->type) && CInit_ConstructAutoObject(TYPE_CLASS(obj->type), NULL, 0, 1)) {
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 1)) {
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (tk != '=' && (tk != '(' || !copts.cplusplus)) {
- if (IS_TYPE_ARRAY(obj->type)) {
- type = obj->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type)) {
- if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) {
- CInit_InitializeClassArray(obj, TYPE_CLASS(type), 0);
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
- CFunc_CheckClassCtors(TYPE_CLASS(type));
- }
- }
-
- if (IS_TYPE_CLASS(obj->type))
- CFunc_CheckClassCtors(TYPE_CLASS(obj->type));
-
- if ((IS_TYPE_REFERENCE(obj->type) || is_const_object(obj)) && copts.cplusplus)
- CError_Error(CErrorStr224);
- } else {
- if (obj->type->size || IS_TYPE_ARRAY(obj->type)) {
- if ((expr = CInit_GenericData(NULL, obj->type, obj->qual, CInit_AutoInit, 0)))
- insert_cb(makediadicnode(create_objectnode2(obj), expr, EASS));
- } else {
- CError_Error(CErrorStr145);
- }
- }
-
- if (IS_TYPE_CLASS(obj->type) && CClass_Destructor(TYPE_CLASS(obj->type)))
- register_cb(obj->type, obj, 0, 0);
-
- CInit_CleanupInitInfo(&initinfo);
-}
-
-void CInit_InitializeStaticData(Object *obj, InitExprRegisterCB cb) {
- ENode *expr;
- Type *type;
- InitInfo initinfo;
- CInit_Stuff s;
- CInit_1C *entry;
- ENode *obj_expr;
-
- if (CInit_IsSimpleStructArrayInit(obj->type)) {
- if (tk == '=' || (tk == '(' && copts.cplusplus)) {
- if (tk == '=')
- tk = lex();
- CInit_InitData(&s, obj->type, obj->qual, copts.cplusplus);
-
- IsCompleteType(obj->type);
-
- if (!s.x1C && is_const_object(obj))
- CInit_DeclareReadOnlyData(obj, s.buffer, s.list, s.size);
- else
- CInit_DeclareData(obj, s.buffer, s.list, s.size);
-
- if (s.x1C) {
- obj_expr = create_objectrefnode(obj);
- entry = s.x1C;
- expr = NULL;
- while (entry) {
- expr = CInit_InitConcat(expr, obj_expr, entry->offset, entry->type, entry->expr);
- entry = entry->next;
- }
- cb(expr);
- }
- } else {
- if (copts.cplusplus && is_const_object(obj))
- CError_Error(CErrorStr224);
-
- if (is_const_object(obj))
- CInit_DeclareReadOnlyData(obj, NULL, NULL, obj->type->size);
- else
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- return;
- }
-
- CInit_SetupInitInfo(&initinfo, obj);
- initinfo.x16 = 1;
- initinfo.init_expr_register_cb = cb;
-
- if (IS_TYPE_CLASS(obj->type) && CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 1)) {
- IsCompleteType(obj->type);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 0)) {
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (tk != '=' && (tk != '(' || !copts.cplusplus)) {
- if (IsCompleteType(obj->type))
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
-
- if (IS_TYPE_ARRAY(obj->type)) {
- type = obj->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type)) {
- if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) {
- CInit_InitializeClassArray(obj, TYPE_CLASS(type), 1);
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
- CFunc_CheckClassCtors(TYPE_CLASS(type));
- }
- }
-
- if (IS_TYPE_CLASS(obj->type))
- CFunc_CheckClassCtors(TYPE_CLASS(obj->type));
-
- if ((IS_TYPE_REFERENCE(obj->type) || is_const_object(obj)) && copts.cplusplus)
- CError_Error(CErrorStr224);
- } else {
- if (obj->type->size || IS_TYPE_ARRAY(obj->type)) {
- if ((expr = CInit_GenericData(obj, obj->type, obj->qual, CInit_GlobalStaticInit, 1)))
- cb(makediadicnode(create_objectnode2(obj), expr, EASS));
- } else {
- CError_Error(CErrorStr145);
- }
- }
-
- CInit_CleanupInitInfo(&initinfo);
-}
-
-void CInit_InitializeData(Object *obj) {
- Object *dtor;
- ObjectList *list;
- CInt64 val;
- InitInfo initinfo;
- Boolean needs_construction;
- Type *type;
-
- if (tk == ':') {
- tk = lex();
- obj->datatype = DABSOLUTE;
- val = CExpr_IntegralConstExpr();
- obj->u.address = CInt64_GetULong(&val);
- return;
- }
-
- if (tk != '=' && (tk != '(' || !copts.cplusplus)) {
- if (obj->sclass != TK_EXTERN) {
- if (!copts.cplusplus) {
- if (IsCompleteType(obj->type)) {
- for (list = cinit_tentative; list; list = list->next) {
- if (list->object == obj)
- break;
- }
- if (!list) {
- list = galloc(sizeof(ObjectList));
- list->object = obj;
- list->next = cinit_tentative;
- cinit_tentative = list;
- obj->qual |= Q_1000000;
- }
- }
- } else {
- if (obj->flags & OBJECT_DEFINED)
- CError_Error(CErrorStr329, obj);
- obj->flags = obj->flags | OBJECT_DEFINED;
-
- needs_construction = 0;
- if (IS_TYPE_ARRAY(obj->type)) {
- type = obj->type;
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
- if (IS_TYPE_CLASS(type)) {
- if (CInit_ClassNeedsConstruction(TYPE_CLASS(type))) {
- CInit_SetupInitInfo(&initinfo, obj);
- CInit_InitializeClassArray(obj, TYPE_CLASS(type), 1);
- CInit_CleanupInitInfo(&initinfo);
- needs_construction = 1;
- } else {
- CFunc_CheckClassCtors(TYPE_CLASS(type));
- }
- }
- } else {
- if (IS_TYPE_CLASS(obj->type)) {
- if (CInit_ClassNeedsConstruction(TYPE_CLASS(obj->type))) {
- CInit_SetupInitInfo(&initinfo, obj);
- CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 0);
- CInit_CleanupInitInfo(&initinfo);
- needs_construction = 1;
- } else {
- CFunc_CheckClassCtors(TYPE_CLASS(obj->type));
- }
- }
- }
-
- if (!needs_construction && copts.cplusplus) {
- if (IS_TYPE_REFERENCE(obj->type) || is_const_object(obj))
- CError_Error(CErrorStr224);
- }
- if (IsCompleteType(obj->type))
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
- }
- return;
- }
-
- if (obj->flags & OBJECT_DEFINED)
- CError_Error(CErrorStr329, obj);
-
- if (CInit_IsSimpleStructArrayInit(obj->type)) {
- if (tk == '=')
- tk = lex();
- else
- CError_Error(CErrorStr121);
- CInit_GlobalObject(obj);
- return;
- }
-
- CInit_SetupInitInfo(&initinfo, obj);
- if (IS_TYPE_CLASS(obj->type) && CInit_ConstructGlobalObject(obj, TYPE_CLASS(obj->type), NULL, 0, 1)) {
- IsCompleteType(obj->type);
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (IS_TYPE_REFERENCE(obj->type) && CInit_InitReference(obj, 0)) {
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (obj->type->size == 0 && !IS_TYPE_ARRAY(obj->type)) {
- CError_Error(CErrorStr145);
- CInit_CleanupInitInfo(&initinfo);
- return;
- }
-
- if (copts.cplusplus)
- CInit_GenericData(obj, obj->type, obj->qual, &CInit_GlobalStaticInit, 0);
- else
- CInit_GenericData(obj, obj->type, obj->qual, NULL, 0);
-
- if (IS_TYPE_CLASS(obj->type) && (dtor = CClass_Destructor(TYPE_CLASS(obj->type))))
- InitExpr_Register(CInit_RegisterDtorObject(obj->type, dtor, create_objectrefnode(obj)), obj);
-
- CInit_CleanupInitInfo(&initinfo);
-}
-
-Object *CInit_DeclareString(char *data, SInt32 size, Boolean ispascal, Boolean iswide) {
- PooledString *str;
- Object *obj;
- PooledString *scan;
-
- if (!copts.dont_reuse_strings) {
- for (scan = cinit_stringlist; scan; scan = scan->next) {
- if (scan->size == size && scan->ispascal == ispascal && scan->iswide == iswide && !memcmp(scan->data, data, size))
- return scan->obj;
- }
- }
-
- obj = CParser_NewCompilerDefDataObject();
- obj->name = CParser_GetUniqueName();
- if (iswide) {
- obj->type = CDecl_NewArrayType(CParser_GetWCharType(), size);
- } else {
- obj->type = CDecl_NewArrayType(ispascal ? TYPE(&stunsignedchar) : TYPE(&stchar), size);
- }
- obj->sclass = TK_STATIC;
- CScope_AddGlobalObject(obj);
-
- if (!iswide && !ispascal && size == (strlen(data) + 1))
- obj->section = SECT_TEXT_CSTRING;
- else
- obj->section = SECT_CONST;
-
- if (copts.readonly_strings)
- CInit_DeclareReadOnlyData(obj, data, NULL, obj->type->size);
- else
- CInit_DeclareData(obj, data, NULL, obj->type->size);
-
- str = galloc(sizeof(PooledString));
- str->next = cinit_stringlist;
- cinit_stringlist = str;
- str->obj = obj;
- str->offset = 0;
- str->size = size;
- str->ispascal = ispascal;
- str->iswide = iswide;
- str->data = galloc(size);
- memcpy(str->data, data, size);
-
- return obj;
-}
-
-PooledString *CInit_DeclarePooledString(char *data, SInt32 size, Boolean ispascal) {
- PooledString *str;
- Object *obj;
- PooledString *scan;
- SInt32 offset;
-
- if (!copts.dont_reuse_strings) {
- for (scan = cinit_pooledstringlist; scan; scan = scan->next) {
- if (scan->size == size && scan->ispascal == ispascal && !memcmp(scan->data, data, size))
- return scan;
- }
- }
-
- if (cinit_pooledstringlist) {
- obj = cinit_pooledstringlist->obj;
- offset = cinit_pooledstringlist->offset + cinit_pooledstringlist->size;
- } else {
- obj = CInit_CreateStaticDataObject(
- CDecl_NewArrayType(ispascal ? TYPE(&stunsignedchar) : TYPE(&stchar), size),
- 0, GetHashNameNodeExport("@stringBase0"));
- obj->section = SECT_CONST;
- offset = 0;
- }
-
- str = galloc(sizeof(PooledString));
- str->next = cinit_pooledstringlist;
- cinit_pooledstringlist = str;
- str->obj = obj;
- str->offset = offset;
- str->size = size;
- str->ispascal = ispascal;
- str->data = galloc(size);
- memcpy(str->data, data, size);
- return str;
-}
-
-PooledString *CInit_DeclarePooledWString(char *data, SInt32 size) {
- PooledString *str;
- Object *obj;
- PooledString *scan;
- SInt32 offset;
-
- if (!copts.dont_reuse_strings) {
- for (scan = cinit_pooledwstringlist; scan; scan = scan->next) {
- if (scan->size == size && !memcmp(scan->data, data, size))
- return scan;
- }
- }
-
- if (cinit_pooledwstringlist) {
- obj = cinit_pooledwstringlist->obj;
- offset = cinit_pooledwstringlist->offset + cinit_pooledwstringlist->size;
- } else {
- obj = CInit_CreateStaticDataObject(
- CDecl_NewArrayType(CParser_GetWCharType(), size),
- 0, GetHashNameNodeExport("@wstringBase0"));
- obj->section = SECT_CONST;
- offset = 0;
- }
-
- str = galloc(sizeof(PooledString));
- str->next = cinit_pooledwstringlist;
- cinit_pooledwstringlist = str;
- str->obj = obj;
- str->offset = offset;
- str->size = size;
- str->ispascal = 0;
- str->data = galloc(size);
- memcpy(str->data, data, size);
- return str;
-}
-
-void CInit_RewriteString(ENode *expr, Boolean flag) {
- PooledString *str;
- Boolean is_wide;
-
- if (cparamblkptr->precompile == 1)
- CError_Error(CErrorStr180);
-
- CError_ASSERT(4220, expr->rtype->type == TYPEPOINTER);
-
- is_wide = TYPE_POINTER(expr->rtype)->target->size != 1;
- if (copts.poolstrings) {
- if (is_wide)
- str = CInit_DeclarePooledWString(expr->data.string.data, expr->data.string.size);
- else
- str = CInit_DeclarePooledString(expr->data.string.data, expr->data.string.size, expr->data.string.ispascal);
-
- if (str->offset) {
- expr->type = EADD;
- expr->data.diadic.right = intconstnode(TYPE(&stunsignedlong), str->offset);
- expr->data.diadic.left = create_objectrefnode(str->obj);
- expr->cost = 1;
- } else {
- expr->type = EOBJREF;
- expr->data.objref = str->obj;
- }
- } else {
- expr->type = EOBJREF;
- expr->data.objref = CInit_DeclareString(expr->data.string.data, expr->data.string.size, expr->data.string.ispascal, is_wide);
- }
-}
-
-void CInit_DeclarePooledStrings(void) {
- SInt32 size;
- char *buffer;
- PooledString *str;
-
- size = 0;
- for (str = cinit_pooledstringlist; str; str = str->next)
- size += str->size;
-
- if (size) {
- cinit_pooledstringlist->obj->type = CDecl_NewArrayType(TYPE(&stchar), size);
- buffer = galloc(size);
- for (str = cinit_pooledstringlist; str; str = str->next)
- memcpy(buffer + str->offset, str->data, str->size);
-
- if (copts.readonly_strings)
- CInit_DeclareReadOnlyData(cinit_pooledstringlist->obj, buffer, NULL, size);
- else
- CInit_DeclareData(cinit_pooledstringlist->obj, buffer, NULL, size);
- }
-
- size = 0;
- for (str = cinit_pooledwstringlist; str; str = str->next)
- size += str->size;
-
- if (size) {
- cinit_pooledwstringlist->obj->type = CDecl_NewArrayType(CParser_GetWCharType(), size);
- buffer = galloc(size);
- for (str = cinit_pooledwstringlist; str; str = str->next)
- memcpy(buffer + str->offset, str->data, str->size);
-
- if (copts.readonly_strings)
- CInit_DeclareReadOnlyData(cinit_pooledwstringlist->obj, buffer, NULL, size);
- else
- CInit_DeclareData(cinit_pooledwstringlist->obj, buffer, NULL, size);
- }
-}
-
-static void declaredata(Object *obj, void *data, OLinkList *list, SInt32 size, Boolean is_readonly) {
- OLinkList *scan;
- UInt32 qual;
-
- qual = obj->qual;
-
- if (cparamblkptr->precompile == 1) {
- PreComp_StaticData(obj, data, list, size);
- } else {
- obj->flags = obj->flags | OBJECT_DEFINED;
- if (!fatalerrors) {
- for (scan = list; scan; scan = scan->next)
- CInline_ObjectAddrRef(scan->obj);
- if (copts.filesyminfo)
- CPrep_SetSourceFile(&cparser_fileoffset);
- if (is_readonly)
- ObjGen_DeclareReadOnlyData(obj, data, list, size);
- else
- ObjGen_DeclareData(obj, data, list, size);
- obj->qual = qual;
- }
- }
-}
-
-void CInit_DeclareData(Object *obj, void *data, OLinkList *list, SInt32 size) {
- declaredata(obj, data, list, size, 0);
-}
-
-void CInit_DeclareReadOnlyData(Object *obj, void *data, OLinkList *list, SInt32 size) {
- declaredata(obj, data, list, size, 1);
-}
-
-void CInit_DefineTentativeData(void) {
- ObjectList *list;
-
- for (list = cinit_tentative; list; list = list->next) {
- if (!(list->object->flags & OBJECT_DEFINED))
- CInit_DeclareData(list->object, NULL, NULL, list->object->type->size);
- }
-
- cinit_tentative = NULL;
-}
diff --git a/compiler_and_linker/unsorted/CInline.c b/compiler_and_linker/unsorted/CInline.c
deleted file mode 100644
index de51ab7..0000000
--- a/compiler_and_linker/unsorted/CInline.c
+++ /dev/null
@@ -1,4206 +0,0 @@
-#include "compiler/CInline.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/COptimizer.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/Switch.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct IDTrans {
- struct IDTrans *next;
- SInt32 from;
- SInt32 to;
-} IDTrans;
-
-typedef struct LabelTrans {
- struct LabelTrans *next;
- CLabel **labelptr;
- short id;
-} LabelTrans;
-
-typedef struct UIDTemp {
- struct UIDTemp *next;
- Object *object;
- SInt32 uid;
-} UIDTemp;
-
-typedef struct CI_Export {
- struct CI_Export *next;
- Object *object;
- CI_FuncData *funcdata;
- Boolean xC;
-} CI_Export;
-
-typedef struct AObject {
- Object *object;
- ENode *expr1;
- ENode *expr2;
-} AObject;
-
-typedef struct CI_StmtLink {
- struct CI_StmtLink *next;
- Statement *stmt;
- CI_Statement *ciStmt;
-} CI_StmtLink;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static CInlineCopyMode enode_copymode;
-static Boolean enode_globalcopy;
-static IDTrans *enode_idtrans;
-static Object **local_dobjects;
-static AObject *local_aobjects;
-static CI_Var *loc_args;
-static CI_Var *loc_vars;
-static Boolean inline_expanded;
-static Boolean any_inline_expanded;
-static short cinline_level;
-static LabelTrans *cinline_label_trans;
-static Statement *cinline_first_stmt;
-static ENode *cinline_stmtlevelexpr[16];
-static short cinline_stmtlevelexprs;
-static Boolean cinline_unconditionalpart;
-static Boolean cinline_serialize_stmt;
-static CI_Export *cinline_exportlist; // type?
-static CI_Action *cinline_actionlist;
-CI_Action *cinline_tactionlist;
-static ObjectList *cinline_freflist;
-static Boolean cinline_gendeps;
-static Statement *cinline_serial_stmt;
-static Statement *cinline_cur_serial_stmt;
-static UIDTemp *cinline_uid_temps;
-static Boolean cinline_has_sideeffect;
-static SInt32 inline_max_size;
-static Boolean recursive_inline;
-static Object *expanding_function;
-static Boolean cinline_funccallfound;
-
-// forward decls
-static ENode *CInline_FoldConst(ENode *expr);
-static ENode *CInline_CopyNodes(ENode *node);
-static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 size, SInt32 level);
-static ENode *CInline_SerializeExpr(ENode *expr);
-static void CInline_AddFRefList_InlineFunc(CI_FuncData *data);
-
-void CInline_Init(void) {
- cinline_exportlist = NULL;
- cinline_actionlist = NULL;
- cinline_tactionlist = NULL;
- cinline_gendeps = 0;
-}
-
-static ENode *CInline_MakeNotNot(ENode *expr) {
- expr = CInline_FoldConst(expr);
-
- if (!ENODE_IS(expr, EINTCONST)) {
- expr = makemonadicnode(expr, ELOGNOT);
- expr->rtype = CParser_GetBoolType();
- expr = makemonadicnode(expr, ELOGNOT);
- } else {
- expr->data.intval = CInt64_Not(CInt64_Not(expr->data.intval));
- }
-
- return expr;
-}
-
-static ENode *CInline_FoldConst(ENode *expr) {
- ENode *inner;
- ENode *right;
- ENode *left;
- ENodeList *list;
-
- switch (expr->type) {
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case ELABEL:
- case EOBJLIST:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
-
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- expr->data.monadic = CInline_FoldConst(expr->data.monadic);
- inner = expr->data.monadic;
- switch (inner->type) {
- case EINTCONST:
- if (!ENODE_IS(expr, ELOGNOT)) {
- inner->data.intval = CMach_CalcIntMonadic(
- expr->rtype, CParser_GetOperator(expr->type), inner->data.intval);
- } else {
- inner->data.intval = CInt64_Not(inner->data.intval);
- }
- inner->rtype = expr->rtype;
- return inner;
-
- case EFLOATCONST:
- if (ENODE_IS(expr, ELOGNOT)) {
- inner->type = EINTCONST;
- CInt64_SetLong(&inner->data.intval, CMach_FloatIsZero(inner->data.floatval));
- } else {
- inner->data.floatval = CMach_CalcFloatMonadic(
- expr->rtype, CParser_GetOperator(expr->type), inner->data.floatval);
- }
- inner->rtype = expr->rtype;
- return inner;
- }
-
- return expr;
-
- case ETYPCON:
- expr->data.monadic = CInline_FoldConst(expr->data.monadic);
- switch (expr->data.monadic->type) {
- case EINTCONST:
- switch (expr->rtype->type) {
- case TYPEFLOAT:
- expr->type = EFLOATCONST;
- expr->data.floatval = CMach_CalcFloatConvertFromInt(
- expr->data.monadic->rtype, expr->data.monadic->data.intval);
- return expr;
-
- case TYPEINT:
- expr->type = EINTCONST;
- expr->data.intval = CExpr_IntConstConvert(
- expr->rtype, expr->data.monadic->rtype, expr->data.monadic->data.intval);
- break;
- }
- break;
-
- case EFLOATCONST:
- switch (expr->rtype->type) {
- case TYPEFLOAT:
- expr->type = EFLOATCONST;
- expr->data.floatval = CMach_CalcFloatConvert(
- expr->rtype, expr->data.monadic->data.floatval);
- return expr;
-
- case TYPEINT:
- expr->type = EINTCONST;
- expr->data.intval = CMach_CalcIntConvertFromFloat(
- expr->rtype, expr->data.monadic->data.floatval);
- return expr;
- }
- break;
- }
-
- return expr;
-
- case EPOSTINC:
- case EPOSTDEC:
- expr->data.monadic = CInline_FoldConst(expr->data.monadic);
- switch (expr->data.monadic->type) {
- case EINTCONST:
- case EFLOATCONST:
- expr->data.monadic->rtype = expr->rtype;
- return expr->data.monadic;
- }
-
- return expr;
-
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EFORCELOAD:
- case EBITFIELD:
- expr->data.monadic = CInline_FoldConst(expr->data.monadic);
- return expr;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- case EADD:
- case ESUB:
- case ESHL:
- case ESHR:
- case EAND:
- case EXOR:
- case EOR:
- expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left);
- expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right);
- if ((left = expr->data.diadic.left)->type == (right = expr->data.diadic.right)->type) {
- switch (left->type) {
- case EINTCONST:
- left->data.intval = CMach_CalcIntDiadic(
- expr->rtype,
- expr->data.diadic.left->data.intval,
- CParser_GetOperator(expr->type),
- right->data.intval);
- left->rtype = expr->rtype;
- return left;
-
- case EFLOATCONST:
- left->data.floatval = CMach_CalcFloatDiadic(
- expr->rtype,
- expr->data.diadic.left->data.floatval,
- CParser_GetOperator(expr->type),
- right->data.floatval);
- left->rtype = expr->rtype;
- return left;
- }
- }
-
- return expr;
-
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left);
- expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right);
- if ((left = expr->data.diadic.left)->type == (right = expr->data.diadic.right)->type) {
- switch (left->type) {
- case EINTCONST:
- left->data.intval = CMach_CalcIntDiadic(
- left->rtype,
- expr->data.diadic.left->data.intval,
- CParser_GetOperator(expr->type),
- right->data.intval);
- left->rtype = expr->rtype;
- return left;
-
- case EFLOATCONST:
- CInt64_SetLong(&left->data.intval, CMach_CalcFloatDiadicBool(
- left->rtype,
- expr->data.diadic.left->data.floatval,
- CParser_GetOperator(expr->type),
- right->data.floatval
- ));
- left->type = EINTCONST;
- left->rtype = expr->rtype;
- return left;
- }
- }
-
- return expr;
-
- case ELAND:
- expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left);
- if (iszero(expr->data.diadic.left))
- return expr->data.diadic.left;
- if (isnotzero(expr->data.diadic.left))
- return CInline_MakeNotNot(expr->data.diadic.right);
-
- expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right);
- if (isnotzero(expr->data.diadic.right))
- return CInline_MakeNotNot(expr->data.diadic.left);
-
- return expr;
-
- case ELOR:
- expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left);
- if (iszero(expr->data.diadic.left))
- return CInline_MakeNotNot(expr->data.diadic.right);
- if (isnotzero(expr->data.diadic.left))
- return CInline_MakeNotNot(expr->data.diadic.left);
-
- expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right);
- if (iszero(expr->data.diadic.right))
- return CInline_MakeNotNot(expr->data.diadic.left);
-
- return expr;
-
- 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 EROTL:
- case EROTR:
- expr->data.diadic.left = CInline_FoldConst(expr->data.diadic.left);
- expr->data.diadic.right = CInline_FoldConst(expr->data.diadic.right);
- return expr;
-
- case ECOND:
- expr->data.cond.cond = CInline_FoldConst(expr->data.cond.cond);
- if (isnotzero(expr->data.cond.cond))
- return CInline_FoldConst(expr->data.cond.expr1);
- if (iszero(expr->data.cond.cond))
- return CInline_FoldConst(expr->data.cond.expr2);
-
- expr->data.cond.expr1 = CInline_FoldConst(expr->data.cond.expr1);
- expr->data.cond.expr2 = CInline_FoldConst(expr->data.cond.expr2);
- return expr;
-
- case EMFPOINTER:
- expr->data.mfpointer.accessnode = CInline_FoldConst(expr->data.mfpointer.accessnode);
- expr->data.mfpointer.mfpointer = CInline_FoldConst(expr->data.mfpointer.mfpointer);
- return expr;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- expr->data.funccall.funcref = CInline_FoldConst(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- list->node = CInline_FoldConst(list->node);
- return expr;
-
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CInline_FoldConst(expr->data.nullcheck.nullcheckexpr);
- expr->data.nullcheck.condexpr = CInline_FoldConst(expr->data.nullcheck.condexpr);
- return expr;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- expr->data.emember->expr = CInline_FoldConst(expr->data.emember->expr);
- return expr;
-
- default:
- CError_FATAL(421);
- return expr;
- }
-}
-
-// unknown name
-CW_INLINE SInt32 CInline_GetLocalID2(Object *object) {
- ObjectList *list;
- SInt32 counter;
-
- for (list = locals, counter = 0; list; list = list->next) {
- if (list->object->datatype == DLOCAL) {
- if (list->object == object)
- return counter;
- counter++;
- }
- }
-
- return -1;
-}
-
-SInt32 CInline_GetLocalID(Object *object) {
- ObjectList *list;
- SInt32 counter;
-
- if (object) {
- for (list = arguments, counter = 0; list; list = list->next, counter++) {
- if (list->object == object) {
- loc_args[counter].xD = 1;
- loc_args[counter].xE = 0;
- return counter - 0x7FFFFFFF;
- }
- }
-
- counter = CInline_GetLocalID2(object);
- CError_ASSERT(465, counter >= 0);
- loc_vars[counter].xD = 1;
- return counter + 1;
- }
-
- return 0;
-}
-
-static Boolean CInline_IsTrivialExpression(ENode *expr) {
- while (1) {
- switch (expr->type) {
- case EINTCONST:
- case EFLOATCONST:
- case EOBJREF:
- case EARGOBJ:
- case ELOCOBJ:
- case EOBJLIST:
- case EVECTOR128CONST:
- return 0;
-
- case ESTRINGCONST:
- return copts.dont_reuse_strings;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- return CInline_IsTrivialExpression(expr->data.emember->expr);
- return 0;
-
- case EINDIRECT:
- if (ENODE_IS(expr->data.monadic, EOBJREF)) {
- if (expr->data.monadic->data.objref->datatype == DLOCAL &&
- !(expr->data.monadic->data.objref->flags & OBJECT_FLAGS_2))
- return 0;
-
- if (is_const_object(expr->data.monadic->data.objref))
- return 0;
-
- return 1;
- }
-
- return 1;
-
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EFORCELOAD:
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EFUNCCALL:
- case EFUNCCALLP:
- case EMFPOINTER:
- case ENULLCHECK:
- case EPRECOMP:
- case ETEMP:
- case ELABEL:
- case EINSTRUCTION:
- return 1;
-
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- continue;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 ECOMMA:
- case EROTL:
- case EROTR:
- if (CInline_IsTrivialExpression(expr->data.diadic.left))
- return 1;
- expr = expr->data.diadic.right;
- continue;
-
- case ECOND:
- if (CInline_IsTrivialExpression(expr->data.cond.cond))
- return 1;
- if (CInline_IsTrivialExpression(expr->data.cond.expr1))
- return 1;
- expr = expr->data.cond.expr2;
- continue;
-
- default:
- CError_FATAL(582);
- }
- }
-}
-
-Boolean CInline_ExpressionHasSideEffect(ENode *expr) {
- while (1) {
- switch (expr->type) {
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case EARGOBJ:
- case ELOCOBJ:
- case ELABEL:
- case EOBJLIST:
- case EVECTOR128CONST:
- return 0;
-
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EFUNCCALL:
- case EFUNCCALLP:
- case EINSTRUCTION:
- return 1;
-
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- continue;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 ECOMMA:
- case EROTL:
- case EROTR:
- if (CInline_ExpressionHasSideEffect(expr->data.diadic.left))
- return 1;
- expr = expr->data.diadic.right;
- continue;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- return CInline_ExpressionHasSideEffect(expr->data.emember->expr);
- return 0;
-
- case EMFPOINTER:
- if (CInline_ExpressionHasSideEffect(expr->data.mfpointer.accessnode))
- return 1;
- expr = expr->data.mfpointer.mfpointer;
- continue;
-
- case ENULLCHECK:
- if (CInline_ExpressionHasSideEffect(expr->data.nullcheck.nullcheckexpr))
- return 1;
- expr = expr->data.nullcheck.condexpr;
- continue;
-
- case ECOND:
- if (CInline_ExpressionHasSideEffect(expr->data.cond.cond))
- return 1;
- if (CInline_ExpressionHasSideEffect(expr->data.cond.expr1))
- return 1;
- expr = expr->data.cond.expr2;
- continue;
-
- default:
- CError_FATAL(689);
- }
- }
-}
-
-static ENode *CInline_CopyExpressionSave(ENode *expr) {
- CInlineCopyMode save_copymode;
- Boolean save_globalcopy;
- IDTrans *save_idtrans;
-
- save_globalcopy = enode_globalcopy;
- enode_globalcopy = 1;
-
- save_copymode = enode_copymode;
- enode_copymode = CopyMode4;
-
- save_idtrans = enode_idtrans;
- enode_idtrans = NULL;
-
- expr = CInline_CopyNodes(expr);
-
- enode_globalcopy = save_globalcopy;
- enode_copymode = save_copymode;
- enode_idtrans = save_idtrans;
-
- return expr;
-}
-
-static SInt32 CInline_TranslateID(SInt32 id) {
- IDTrans *trans;
-
- for (trans = enode_idtrans; trans; trans = trans->next) {
- if (trans->from == id)
- return trans->to;
- }
-
- trans = lalloc(sizeof(IDTrans));
- trans->next = enode_idtrans;
- enode_idtrans = trans;
-
- trans->from = id;
- trans->to = CParser_GetUniqueID();
-
- return trans->to;
-}
-
-static short CInline_GetLabelStatementNumber(HashNameNode *name) {
- Statement *stmt;
- short i;
-
- for (stmt = cinline_first_stmt, i = 0; stmt; stmt = stmt->next, i++) {
- if (stmt->type == ST_LABEL && stmt->label->uniquename == name)
- return i;
- }
-
- CError_FATAL(742);
- return 0;
-}
-
-static ENodeList *CInline_CopyNodeList(ENodeList *list) {
- ENodeList *copy;
- ENodeList *first;
- ENodeList *last;
-
- first = NULL;
- while (list) {
- if (enode_globalcopy)
- copy = galloc(sizeof(ENodeList));
- else
- copy = lalloc(sizeof(ENodeList));
-
- copy->node = CInline_CopyNodes(list->node);
- copy->next = NULL;
-
- if (first) {
- last->next = copy;
- last = copy;
- } else {
- first = last = copy;
- }
-
- list = list->next;
- }
-
- return first;
-}
-
-static EMemberInfo *CInline_CopyEMemberInfo(EMemberInfo *mi) {
- EMemberInfo *copy;
-
- if (enode_globalcopy)
- copy = galloc(sizeof(EMemberInfo));
- else
- copy = lalloc(sizeof(EMemberInfo));
-
- *copy = *mi;
- if (copy->path)
- copy->path = CClass_GetPathCopy(copy->path, enode_globalcopy);
- if (copy->expr)
- copy->expr = CInline_CopyNodes(copy->expr);
-
- return copy;
-}
-
-static ENode *CInline_CopyNodes(ENode *node) {
- ENode *copy;
-
- if (enode_globalcopy)
- copy = galloc(sizeof(ENode));
- else
- copy = lalloc(sizeof(ENode));
-
- while (1) {
- *copy = *node;
- switch (copy->type) {
- case ETEMPLDEP:
- switch (copy->data.templdep.subtype) {
- case TDE_PARAM:
- case TDE_SIZEOF:
- case TDE_ALIGNOF:
- case TDE_QUALNAME:
- case TDE_OBJ:
- break;
- case TDE_CAST:
- copy->data.templdep.u.cast.args = CInline_CopyNodeList(copy->data.templdep.u.cast.args);
- break;
- case TDE_SOURCEREF:
- copy->data.templdep.u.sourceref.expr = CInline_CopyNodes(copy->data.templdep.u.sourceref.expr);
- break;
- case TDE_ADDRESS_OF:
- copy->data.templdep.u.monadic = CInline_CopyNodes(copy->data.templdep.u.monadic);
- break;
- default:
- CError_FATAL(840);
- }
- break;
-
- case ETEMP:
- if (enode_copymode == CopyMode3 && copy->data.temp.uniqueid)
- copy->data.temp.uniqueid = CInline_TranslateID(copy->data.temp.uniqueid);
- break;
-
- case ELABEL:
- switch (enode_copymode) {
- case CopyMode2:
- copy->data.precompid = CInline_GetLabelStatementNumber(copy->data.label->uniquename);
- return copy;
- case CopyMode3:
- case CopyMode4: {
- LabelTrans *trans = lalloc(sizeof(LabelTrans));
- trans->next = cinline_label_trans;
- cinline_label_trans = trans;
- trans->id = copy->data.precompid;
- trans->labelptr = &copy->data.label;
- return copy;
- }
- }
- break;
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJLIST:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- break;
-
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- copy->data.monadic = CInline_CopyNodes(copy->data.monadic);
- break;
-
- ENODE_CASE_DIADIC_ALL:
- copy->data.diadic.left = CInline_CopyNodes(copy->data.diadic.left);
- copy->data.diadic.right = CInline_CopyNodes(copy->data.diadic.right);
- break;
-
- case ECOND:
- copy->data.cond.cond = CInline_CopyNodes(copy->data.cond.cond);
- copy->data.cond.expr1 = CInline_CopyNodes(copy->data.cond.expr1);
- copy->data.cond.expr2 = CInline_CopyNodes(copy->data.cond.expr2);
- break;
-
- case EMFPOINTER:
- copy->data.mfpointer.accessnode = CInline_CopyNodes(copy->data.mfpointer.accessnode);
- copy->data.mfpointer.mfpointer = CInline_CopyNodes(copy->data.mfpointer.mfpointer);
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- copy->data.funccall.funcref = CInline_CopyNodes(copy->data.funccall.funcref);
- copy->data.funccall.args = CInline_CopyNodeList(copy->data.funccall.args);
- break;
-
- case ENULLCHECK:
- copy->data.nullcheck.precompid = CInline_TranslateID(copy->data.nullcheck.precompid);
- copy->data.nullcheck.nullcheckexpr = CInline_CopyNodes(copy->data.nullcheck.nullcheckexpr);
- copy->data.nullcheck.condexpr = CInline_CopyNodes(copy->data.nullcheck.condexpr);
- break;
-
- case EPRECOMP:
- copy->data.precompid = CInline_TranslateID(copy->data.precompid);
- break;
-
- case EINDIRECT:
- if (
- enode_copymode == CopyMode4 &&
- ENODE_IS(copy->data.monadic, EARGOBJ) &&
- local_aobjects[copy->data.monadic->data.longval].object == NULL
- )
- {
- CError_ASSERT(910, local_aobjects[copy->data.monadic->data.longval].expr1);
- copy = CInline_CopyExpressionSave(local_aobjects[copy->data.monadic->data.longval].expr1);
- if (copy->rtype != node->rtype) {
- if (IS_TYPE_INT(copy->rtype) && IS_TYPE_INT(node->rtype))
- copy = makemonadicnode(copy, ETYPCON);
- copy->rtype = node->rtype;
- }
- return copy;
- }
-
- copy->data.monadic = CInline_CopyNodes(copy->data.monadic);
- break;
-
- case EOBJREF:
- if (enode_copymode == CopyMode2) {
- ObjectList *list;
- int i;
-
- if (node->data.objref->datatype == DALIAS) {
- CExpr_AliasTransform(node);
- continue;
- }
-
- if (node->data.objref->datatype == DDATA)
- return copy;
-
- for (list = arguments, i = 0; list; list = list->next, i++) {
- if (list->object == copy->data.objref) {
- copy->type = EARGOBJ;
- copy->data.longval = i;
- return copy;
- }
- }
-
- i = CInline_GetLocalID2(copy->data.objref);
- if (i >= 0) {
- copy->type = ELOCOBJ;
- copy->data.longval = i;
- return copy;
- }
-
- if (node->data.objref->datatype == DLOCAL)
- CError_FATAL(949);
- }
- break;
-
- case EARGOBJ:
- switch (enode_copymode) {
- case CopyMode4:
- CError_ASSERT(957, local_aobjects[copy->data.longval].object);
- copy->type = EOBJREF;
- copy->data.objref = local_aobjects[copy->data.longval].object;
- return copy;
-
- case CopyMode3: {
- ObjectList *list;
- int i;
- for (list = arguments, i = 0; list; list = list->next, i++) {
- if (i == copy->data.longval) {
- copy->type = EOBJREF;
- copy->data.objref = list->object;
- CError_ASSERT(966, copy->data.objref);
- return copy;
- }
- }
- }
-
- default:
- CError_FATAL(971);
- }
-
- case ELOCOBJ:
- switch (enode_copymode) {
- case CopyMode4:
- copy->type = EOBJREF;
- copy->data.objref = local_dobjects[copy->data.longval];
- return copy;
-
- case CopyMode3: {
- ObjectList *list;
- int i;
- for (list = locals, i = 0; list; list = list->next, i++) {
- if (i == copy->data.longval) {
- copy->type = EOBJREF;
- copy->data.objref = list->object;
- CError_ASSERT(986, copy->data.objref);
- return copy;
- }
- }
- }
-
- default:
- CError_FATAL(991);
- }
- break;
-
- case ENEWEXCEPTION:
- case ENEWEXCEPTIONARRAY:
- copy->data.newexception.initexpr = CInline_CopyNodes(copy->data.newexception.initexpr);
- copy->data.newexception.tryexpr = CInline_CopyNodes(copy->data.newexception.tryexpr);
- break;
-
- case EINITTRYCATCH:
- copy->data.itc.initexpr = CInline_CopyNodes(copy->data.itc.initexpr);
- copy->data.itc.tryexpr = CInline_CopyNodes(copy->data.itc.tryexpr);
- copy->data.itc.catchexpr = CInline_CopyNodes(copy->data.itc.catchexpr);
- copy->data.itc.result = CInline_CopyNodes(copy->data.itc.result);
- break;
-
- case EMEMBER:
- copy->data.emember = CInline_CopyEMemberInfo(copy->data.emember);
- break;
-
- default:
- CError_FATAL(1015);
- }
-
- return copy;
- }
-}
-
-static void CInline_CheckUsage(ENode *expr, Boolean flag) {
- ENodeList *list;
- ENode *inner;
-
- while (1) {
- switch (expr->type) {
- case EARGOBJ:
- loc_args[expr->data.longval].xD = 1;
- loc_args[expr->data.longval].xE = 0;
- return;
-
- case ELOCOBJ:
- loc_vars[expr->data.longval].xD = 1;
- return;
-
- case EINDIRECT:
- if (ENODE_IS((inner = expr->data.monadic), EARGOBJ)) {
- loc_args[inner->data.longval].xD = 1;
- if (flag)
- loc_args[inner->data.longval].xE = 0;
- return;
- }
- expr = expr->data.monadic;
- flag = 0;
- continue;
-
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- flag = 0;
- continue;
-
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- expr = expr->data.monadic;
- flag = 1;
- continue;
-
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- CInline_CheckUsage(expr->data.diadic.left, 1);
- expr = expr->data.diadic.right;
- flag = 0;
- continue;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 ECOMMA:
- case EROTL:
- case EROTR:
- CInline_CheckUsage(expr->data.diadic.left, 0);
- expr = expr->data.diadic.right;
- flag = 0;
- continue;
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ETEMP:
- case ELABEL:
- case EOBJLIST:
- case EVECTOR128CONST:
- return;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- CInline_CheckUsage(expr->data.emember->expr, 0);
- return;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- CInline_CheckUsage(expr->data.funccall.funcref, 0);
- for (list = expr->data.funccall.args; list; list = list->next)
- CInline_CheckUsage(list->node, 0);
- return;
-
- case ENULLCHECK:
- CInline_CheckUsage(expr->data.nullcheck.nullcheckexpr, 0);
- expr = expr->data.nullcheck.condexpr;
- flag = 0;
- continue;
-
- case EMFPOINTER:
- CInline_CheckUsage(expr->data.mfpointer.accessnode, 0);
- expr = expr->data.mfpointer.mfpointer;
- flag = 0;
- continue;
-
- case ECOND:
- CInline_CheckUsage(expr->data.cond.cond, 0);
- CInline_CheckUsage(expr->data.cond.expr1, 0);
- expr = expr->data.cond.expr2;
- flag = 0;
- continue;
-
- case EINSTRUCTION:
- return;
-
- default:
- CError_FATAL(1146);
- }
- }
-}
-
-ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode) {
- enode_copymode = mode;
-
- switch (mode) {
- case CopyMode0:
- case CopyMode4:
- enode_idtrans = NULL;
- enode_globalcopy = 0;
- expr = CInline_CopyNodes(expr);
- break;
- case CopyMode3:
- enode_globalcopy = 0;
- expr = CInline_CopyNodes(expr);
- break;
- case CopyMode1:
- enode_idtrans = NULL;
- enode_globalcopy = 1;
- expr = CInline_CopyNodes(expr);
- break;
- case CopyMode2:
- enode_idtrans = NULL;
- enode_globalcopy = 1;
- expr = CInline_CopyNodes(expr);
- CInline_CheckUsage(expr, 0);
- break;
- }
-
- return expr;
-}
-
-static UInt8 CInline_GetObjectSFlags(Object *object) {
- UInt8 flags;
-
- switch (object->sclass) {
- case 0:
- flags = CI_SFLAGS_NoClass;
- break;
- case TK_REGISTER:
- flags = CI_SFLAGS_Register;
- break;
- case TK_AUTO:
- flags = CI_SFLAGS_Auto;
- break;
- default:
- CError_FATAL(1204);
- }
-
- if (object->flags & OBJECT_FLAGS_2)
- flags |= CI_SFLAGS_HasObjectFlag2;
-
- return flags;
-}
-
-static void CInline_SetObjectSFlags(Object *object, UInt8 sflags) {
- if (sflags & CI_SFLAGS_HasObjectFlag2) {
- object->flags |= OBJECT_FLAGS_2;
- sflags &= ~CI_SFLAGS_HasObjectFlag2;
- }
-
- switch (sflags) {
- case CI_SFLAGS_NoClass:
- object->sclass = 0;
- break;
- case CI_SFLAGS_Register:
- object->sclass = TK_REGISTER;
- break;
- case CI_SFLAGS_Auto:
- object->sclass = TK_AUTO;
- break;
- default:
- CError_FATAL(1229);
- }
-}
-
-static Object *CInline_NewLocalObject(Type *type, short qual, UInt8 sflags, int unk) {
- Object *object = CParser_NewLocalDataObject(NULL, 1);
- object->name = CParser_GetUniqueName();
- object->type = type;
- object->qual = qual;
- CInline_SetObjectSFlags(object, sflags);
- CFunc_SetupLocalVarInfo(object);
- return object;
-}
-
-static ENode *CInline_FuncArgConvert(ENode *expr) {
- ENode *copy;
-
- switch (expr->type) {
- case EOBJREF:
- copy = lalloc(sizeof(ENode));
- *copy = *expr;
- return copy;
- case ETEMP:
- CError_FATAL(1272);
- }
-
- return NULL;
-}
-
-static ENode *CInline_RefArgTransform(ENode *expr, Boolean flag) {
- ENodeList *arg;
-
- while (ENODE_IS(expr, ECOMMA))
- expr = expr->data.diadic.right;
-
- switch (expr->type) {
- case EOBJREF:
- case ETEMP:
- if (flag)
- return CInline_FuncArgConvert(expr);
- break;
-
- case EFUNCCALL:
- if (IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_CLASS(TPTR_TARGET(expr->rtype))) {
- if (
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- CClass_IsConstructor(expr->data.funccall.funcref->data.objref) &&
- expr->data.funccall.args
- )
- return CInline_FuncArgConvert(expr->data.funccall.args->node);
-
- if (
- TPTR_TARGET(expr->rtype) == expr->data.funccall.functype->functype &&
- CMach_GetFunctionResultClass(expr->data.funccall.functype) == 1 &&
- (arg = expr->data.funccall.args)
- )
- {
- switch (CABI_GetStructResultArgumentIndex(expr->data.funccall.functype)) {
- case 0:
- break;
- case 1:
- if ((arg = arg->next))
- break;
- CError_FATAL(1313);
- default:
- CError_FATAL(1314);
- }
-
- return CInline_FuncArgConvert(arg->node);
- }
- }
- break;
- }
-
- return NULL;
-}
-
-static ENode *CInline_SetupArgsExpression(Object *object, CI_FuncData *data, ENodeList *list) {
- ENode *commaNodes;
- CI_Var *var;
- ENodeList *scan;
- ENode *expr;
- SInt32 i;
- Boolean is_oldstyle;
-
- is_oldstyle = 0;
- if (TYPE_FUNC(object->type)->args == &oldstyle)
- is_oldstyle = 1;
-
- local_dobjects = lalloc(sizeof(Object *) * data->numlocals);
- local_aobjects = lalloc(sizeof(AObject) * data->numarguments);
-
- for (i = 0, var = data->locals; i < data->numlocals; i++, var++) {
- if (var->xD) {
- object = CInline_NewLocalObject(var->type, var->qual, var->sflags, 0);
- local_dobjects[i] = object;
- if (!var->xE)
- object->flags |= OBJECT_FLAGS_2;
- } else {
- local_dobjects[i] = NULL;
- }
- }
-
- for (i = 0, var = data->arguments, scan = list; i < data->numarguments; i++, var++) {
- local_aobjects[i].expr2 = NULL;
-
- if (!var->xD) {
- local_aobjects[i].object = NULL;
- local_aobjects[i].expr1 = NULL;
- } else if (
- scan &&
- var->xE &&
- !CInline_IsTrivialExpression(scan->node) &&
- (!is_oldstyle || scan->node->rtype->size == var->type->size)
- )
- {
- local_aobjects[i].object = NULL;
- local_aobjects[i].expr1 = scan->node;
- } else if (
- scan &&
- var->xE &&
- IS_TYPE_REFERENCE(var->type) &&
- (expr = CInline_RefArgTransform(scan->node, 1))
- )
- {
- local_aobjects[i].object = NULL;
- local_aobjects[i].expr1 = expr;
- local_aobjects[i].expr2 = scan->node;
- } else {
- local_aobjects[i].object = CInline_NewLocalObject(var->type, var->qual, var->sflags, 0);
- local_aobjects[i].expr1 = NULL;
- }
-
- if (scan)
- scan = scan->next;
- }
-
- commaNodes = NULL;
-
- for (i = 0, scan = list; scan; scan = scan->next, i++) {
- if (i >= data->numarguments) {
- if (!commaNodes)
- commaNodes = scan->node;
- else
- commaNodes = makecommaexpression(scan->node, commaNodes);
- } else if (!local_aobjects[i].object || local_aobjects[i].expr2) {
- if (local_aobjects[i].expr2) {
- if (!commaNodes)
- commaNodes = local_aobjects[i].expr2;
- else
- commaNodes = makecommaexpression(local_aobjects[i].expr2, commaNodes);
- } else if (!local_aobjects[i].expr1 && CInline_IsTrivialExpression(scan->node)) {
- commaNodes = !commaNodes ? scan->node : makecommaexpression(scan->node, commaNodes);
- CError_ASSERT(1470, !ENODE_IS(scan->node, EPRECOMP));
- }
- } else {
- if (is_oldstyle && scan->node->rtype->size != local_aobjects[i].object->type->size) {
- scan->node = makemonadicnode(scan->node, ETYPCON);
- scan->node->rtype = local_aobjects[i].object->type;
- }
-
- expr = makediadicnode(create_objectnode2(local_aobjects[i].object), scan->node, EASS);
- if (!commaNodes)
- commaNodes = expr;
- else
- commaNodes = makecommaexpression(expr, commaNodes);
- }
- }
-
- return commaNodes;
-}
-
-static void CInline_ReturnCheckCB(ENode *expr) {
- cinline_has_sideeffect = 1;
-}
-
-static ENode *CInline_ReturnCheck(ENode *expr) {
- ENode *copy;
-
- if (ENODE_IS(expr, EFORCELOAD))
- return expr;
-
- cinline_has_sideeffect = 0;
- CExpr_SearchExprTree(expr, CInline_ReturnCheckCB, 3, EINDIRECT, EFUNCCALL, EFUNCCALLP);
-
- if (!cinline_has_sideeffect)
- return expr;
-
- copy = lalloc(sizeof(ENode));
- *copy = *expr;
- copy->type = EFORCELOAD;
-
- copy->data.monadic = expr;
- return copy;
-}
-
-static ENode *CInline_ReturnMemResult(Object *object) {
- int index = CABI_GetStructResultArgumentIndex(TYPE_FUNC(object->type));
- if (local_aobjects[index].object == NULL)
- return CInline_CopyExpressionSave(local_aobjects[index].expr1);
- else
- return create_objectnode(local_aobjects[index].object);
-}
-
-static ENode *CInline_InlineFunctionExpression(ENode *expr) {
- Object *object;
- CI_FuncData *funcdata;
- short i;
- Boolean flag26;
- ENode *argsExpr;
-
- object = expr->data.funccall.funcref->data.objref;
- if (object->datatype == DALIAS)
- object = object->u.alias.object;
-
- funcdata = object->u.func.u.ifuncdata;
- if (!funcdata)
- return expr;
-
- if (funcdata->can_inline < CI_CanInline6) {
- if (funcdata->can_inline == CI_CanInline3) {
- if (cinline_unconditionalpart && cinline_stmtlevelexprs < 16)
- cinline_stmtlevelexpr[cinline_stmtlevelexprs++] = expr;
- cinline_serialize_stmt = 1;
- }
- return expr;
- }
-
- flag26 = CMach_GetFunctionResultClass(TYPE_FUNC(object->type)) == 1;
- argsExpr = CInline_SetupArgsExpression(object, funcdata, expr->data.funccall.args);
-
- for (i = 0; i < funcdata->numstatements; i++) {
- switch (funcdata->statements[i].type) {
- case ST_RETURN:
- if (funcdata->statements[i].u.expr) {
- ENode *copy = CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4);
- if (flag26) {
- if (argsExpr)
- argsExpr = makecommaexpression(argsExpr, copy);
- else
- argsExpr = copy;
-
- argsExpr = makecommaexpression(argsExpr, CInline_ReturnMemResult(object));
- } else {
- if (argsExpr)
- argsExpr = makecommaexpression(argsExpr, CInline_ReturnCheck(copy));
- else
- argsExpr = CInline_ReturnCheck(copy);
- }
- }
- break;
- case ST_EXPRESSION:
- if (argsExpr)
- argsExpr = makecommaexpression(argsExpr, CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4));
- else
- argsExpr = CInline_CopyExpression(funcdata->statements[i].u.expr, CopyMode4);
- break;
-
- default:
- CError_FATAL(1632);
- }
- }
-
- if (!argsExpr)
- argsExpr = nullnode();
- if (!IS_TYPE_VOID(expr->rtype))
- argsExpr->rtype = expr->rtype;
-
- inline_expanded = 1;
- return CInline_FoldConst(argsExpr);
-}
-
-static Boolean CInline_CanExpand(ENode *expr) {
- TypeFunc *tfunc;
- Object *object;
-
- object = expr->data.objref;
- tfunc = TYPE_FUNC(object->type);
-
- if (
- IS_TYPE_FUNC(tfunc) &&
- ((object->qual & Q_INLINE) || (tfunc->flags & FUNC_FLAGS_800)) &&
- (object->datatype == DFUNC || (object->datatype == DVFUNC && (expr->flags & ENODE_FLAG_80)))
- )
- return 1;
-
- return 0;
-}
-
-static SInt32 CInline_EstimateSizeOfExpr(ENode *expr, SInt32 size, SInt32 level) {
- ENodeList *list;
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- size = CInline_EstimateSizeOfExpr(expr->data.monadic, size, level) + 1;
- break;
-
- ENODE_CASE_DIADIC_ALL:
- size = CInline_EstimateSizeOfExpr(expr->data.diadic.left, size, level);
- if (size <= inline_max_size)
- size = CInline_EstimateSizeOfExpr(expr->data.diadic.right, size, level) + 1;
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- if (
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata &&
- CInline_CanExpand(expr->data.funccall.funcref)
- )
- {
- recursive_inline |= expr->data.funccall.funcref->data.objref == expanding_function;
- if (level == 0) {
- if (!recursive_inline)
- size = inline_max_size + 1;
- } else {
- size = CInline_EstimateSizeOfFunc(expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata, size, level - 1);
- }
- } else {
- size++;
- }
-
- for (list = expr->data.funccall.args; list; list = list->next) {
- if (size > inline_max_size)
- break;
-
- size = CInline_EstimateSizeOfExpr(list->node, size, level);
- }
- break;
-
- case ECOND:
- size = CInline_EstimateSizeOfExpr(expr->data.cond.cond, size, level);
- if (size <= inline_max_size)
- size = CInline_EstimateSizeOfExpr(expr->data.cond.expr1, size, level) + 1;
- if (size <= inline_max_size)
- size = CInline_EstimateSizeOfExpr(expr->data.cond.expr2, size, level) + 1;
- break;
-
- case ENULLCHECK:
- size = CInline_EstimateSizeOfExpr(expr->data.nullcheck.nullcheckexpr, size, level);
- if (size <= inline_max_size)
- size = CInline_EstimateSizeOfExpr(expr->data.nullcheck.condexpr, size, level) + 1;
- break;
-
- case EMFPOINTER:
- size = CInline_EstimateSizeOfExpr(expr->data.mfpointer.accessnode, size, level);
- if (size <= inline_max_size)
- size = CInline_EstimateSizeOfExpr(expr->data.mfpointer.mfpointer, size, level) + 1;
- break;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- size = CInline_EstimateSizeOfExpr(expr->data.emember->expr, size, level) + 1;
- break;
-
- default:
- size++;
- }
-
- return size;
-}
-
-static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 size, SInt32 level) {
- CI_Statement *stmt;
- SInt32 i;
-
- size += funcdata->numstatements;
- if (size > inline_max_size)
- return size;
-
- for (i = 0, stmt = funcdata->statements; i < funcdata->numstatements; i++, stmt++) {
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_ASM:
- break;
- case ST_EXPRESSION:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- size = CInline_EstimateSizeOfExpr(stmt->u.expr, size, level);
- break;
- case ST_SWITCH:
- size = CInline_EstimateSizeOfExpr(stmt->u.switchdata->expr, size, level);
- break;
- case ST_RETURN:
- if (stmt->u.expr)
- size = CInline_EstimateSizeOfExpr(stmt->u.expr, size, level);
- break;
- default:
- CError_FATAL(1840);
- }
-
- if (size > inline_max_size)
- break;
- }
-
- return size;
-}
-
-static SInt32 EstimateExpandedSizeOfExpr(ENode *expr, SInt32 level) {
- ENodeList *list;
- SInt32 size;
-
- size = 0;
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- size = EstimateExpandedSizeOfExpr(expr->data.monadic, level) + 1;
- break;
-
- ENODE_CASE_DIADIC_ALL:
- size = EstimateExpandedSizeOfExpr(expr->data.diadic.left, level) + 1;
- size += EstimateExpandedSizeOfExpr(expr->data.diadic.right, level);
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- if (
- ENODE_IS(expr->data.funccall.funcref, EOBJREF) &&
- expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata &&
- CInline_CanExpand(expr->data.funccall.funcref)
- )
- {
- if (level) {
- SInt32 est = CInline_EstimateSizeOfFunc(expr->data.funccall.funcref->data.objref->u.func.u.ifuncdata, size, level - 1);
- if (est > inline_max_size)
- size++;
- else
- size += est;
- } else {
- size++;
- }
- } else {
- size++;
- }
-
- for (list = expr->data.funccall.args; list; list = list->next)
- size += EstimateExpandedSizeOfExpr(list->node, level);
- break;
-
- case ECOND:
- size = EstimateExpandedSizeOfExpr(expr->data.cond.cond, level) + 1;
- size += EstimateExpandedSizeOfExpr(expr->data.cond.expr1, level);
- size += EstimateExpandedSizeOfExpr(expr->data.cond.expr2, level);
- break;
-
- case ENULLCHECK:
- size = EstimateExpandedSizeOfExpr(expr->data.nullcheck.nullcheckexpr, level) + 1;
- size += EstimateExpandedSizeOfExpr(expr->data.nullcheck.condexpr, level);
- break;
-
- case EMFPOINTER:
- size = EstimateExpandedSizeOfExpr(expr->data.mfpointer.accessnode, level) + 1;
- size += EstimateExpandedSizeOfExpr(expr->data.mfpointer.mfpointer, level);
- break;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- size = EstimateExpandedSizeOfExpr(expr->data.emember->expr, level);
- break;
-
- default:
- size++;
- }
-
- return size;
-}
-
-static SInt32 EstimateExpandedSizeOfFunction(Statement *stmt) {
- SInt32 size;
- SInt32 level;
-
- level = copts.inlinelevel;
- if (!level)
- level = 8;
-
- size = 0;
-
- while (stmt) {
- switch (stmt->type) {
- case ST_NOP:
- break;
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- size++;
- size += EstimateExpandedSizeOfExpr(stmt->expr, level);
- break;
- case ST_RETURN:
- size++;
- if (stmt->expr)
- size = EstimateExpandedSizeOfExpr(stmt->expr, level);
- break;
- case ST_LABEL:
- case ST_GOTO:
- case ST_ASM:
- size++;
- break;
- default:
- CError_FATAL(2015);
- }
-
- stmt = stmt->next;
- }
-
- return size;
-}
-
-static Boolean CInline_InlineFunctionCheck(ENode *expr) {
- Object *object;
- SInt32 level;
- CI_FuncData *funcdata;
-
- object = expr->data.objref;
- if (object->datatype == DALIAS)
- object = object->u.alias.object;
-
- if (
- IS_TYPE_FUNC(object->type) &&
- ((object->qual & Q_INLINE) || (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_800)) &&
- (object->datatype == DFUNC || (object->datatype == DVFUNC && (expr->flags & ENODE_FLAG_80)))
- )
- {
- if (copts.alwaysinline)
- return 1;
-
- if (copts.inline_bottom_up) {
- if (!object->u.func.u.ifuncdata)
- return 0;
-
- level = (copts.inlinelevel == 0) ? (7 - cinline_level) : (copts.inlinelevel - cinline_level - 1);
- if ((object->qual & Q_INLINE) && level == 0)
- return 1;
-
- if (CInline_EstimateSizeOfFunc(object->u.func.u.ifuncdata, 0, level) > inline_max_size)
- return 0;
- } else if (cinline_level > 0 && copts.inlinelevel == 0) {
- funcdata = object->u.func.u.ifuncdata;
- if (!funcdata)
- return 0;
-
- if (funcdata->numstatements > 10)
- return 0;
- if (cinline_level > 1 && funcdata->numstatements > 7)
- return 0;
- if (cinline_level > 2 && funcdata->numstatements > 3)
- return 0;
- }
-
- return 1;
- } else {
- return 0;
- }
-
- return 0;
-}
-
-static ENode *CInline_ExpandExpression(ENode *expr) {
- ENodeList *list;
- Boolean save;
-
- switch (expr->type) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case ETYPCON:
- case EBITFIELD:
- expr->data.monadic = CInline_ExpandExpression(expr->data.monadic);
- break;
-
- case EFORCELOAD:
- expr->data.monadic = CInline_ExpandExpression(expr->data.monadic);
- if (ENODE_IS(expr->data.monadic, EFORCELOAD))
- expr->data.monadic = expr->data.monadic->data.monadic;
- break;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EPMODULO:
- case EROTL:
- case EROTR:
- expr->data.diadic.left = CInline_ExpandExpression(expr->data.diadic.left);
- expr->data.diadic.right = CInline_ExpandExpression(expr->data.diadic.right);
- break;
-
- case ELAND:
- case ELOR:
- case ECOMMA:
- expr->data.diadic.left = CInline_ExpandExpression(expr->data.diadic.left);
- save = cinline_unconditionalpart;
- cinline_unconditionalpart = 0;
- expr->data.diadic.right = CInline_ExpandExpression(expr->data.diadic.right);
- cinline_unconditionalpart = save;
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- expr->data.funccall.funcref = CInline_ExpandExpression(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- list->node = CInline_ExpandExpression(list->node);
-
- if (ENODE_IS(expr->data.funccall.funcref, EOBJREF) && CInline_InlineFunctionCheck(expr->data.funccall.funcref))
- expr = CInline_InlineFunctionExpression(expr);
- break;
-
- case ENULLCHECK:
- expr->data.nullcheck.nullcheckexpr = CInline_ExpandExpression(expr->data.nullcheck.nullcheckexpr);
- save = cinline_unconditionalpart;
- cinline_unconditionalpart = 0;
- expr->data.nullcheck.condexpr = CInline_ExpandExpression(expr->data.nullcheck.condexpr);
- cinline_unconditionalpart = save;
- break;
-
- case EMFPOINTER:
- expr->data.mfpointer.accessnode = CInline_ExpandExpression(expr->data.mfpointer.accessnode);
- expr->data.mfpointer.mfpointer = CInline_ExpandExpression(expr->data.mfpointer.mfpointer);
- break;
-
- case ECOND:
- expr->data.cond.cond = CInline_ExpandExpression(expr->data.cond.cond);
- save = cinline_unconditionalpart;
- cinline_unconditionalpart = 0;
- expr->data.cond.expr1 = CInline_ExpandExpression(expr->data.cond.expr1);
- expr->data.cond.expr2 = CInline_ExpandExpression(expr->data.cond.expr2);
- cinline_unconditionalpart = save;
- break;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- expr = CInline_ExpandExpression(expr->data.emember->expr);
- else
- expr = nullnode();
- break;
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EPRECOMP:
- case ELABEL:
- case EOBJLIST:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- break;
-
- default:
- CError_FATAL(2235);
- }
-
- return expr;
-}
-
-static Statement *CInline_NewStatement(StatementType sttype) {
- Statement *stmt = lalloc(sizeof(Statement));
- memclrw(stmt, sizeof(Statement));
-
- stmt->type = sttype;
- if (cinline_serial_stmt)
- cinline_cur_serial_stmt->next = stmt;
- else
- cinline_serial_stmt = stmt;
- cinline_cur_serial_stmt = stmt;
-
- return stmt;
-}
-
-static ENode *CInline_LoadToTemp(ENode *expr, Object **objectptr) {
- Object *object;
-
- object = *objectptr;
- if (!object) {
- switch (expr->rtype->type) {
- case TYPEVOID:
- return expr;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- case TYPECLASS:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- object = create_temp_object(expr->rtype);
- *objectptr = object;
- break;
- default:
- CError_FATAL(2288);
- }
- }
-
- return makediadicnode(create_objectnode(object), expr, EASS);
-}
-
-static ENode *CInline_SerializeEFORCELOAD(ENode *expr) {
- Statement *stmt;
- Object *temp = NULL;
-
- while (ENODE_IS(expr->data.monadic, EFORCELOAD)) {
- expr->data.monadic = expr->data.monadic->data.monadic;
- }
-
- expr->data.monadic = CInline_SerializeExpr(expr->data.monadic);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = CInline_LoadToTemp(expr->data.monadic, &temp);
- return create_objectnode(temp);
-}
-
-static ENode *CInline_SerializeECOMMA(ENode *expr) {
- Statement *stmt;
-
- expr->data.diadic.left = CInline_SerializeExpr(expr->data.diadic.left);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = expr->data.diadic.left;
- return CInline_SerializeExpr(expr->data.diadic.right);
-}
-
-static ENode *CInline_SerializeELOR(ENode *expr) {
- ENode *n;
- Statement *stmt;
- CLabel *label;
- Object *temp = NULL;
-
- label = newlabel();
-
- n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.left), ELOGNOT);
- n->rtype = expr->rtype;
- n = makemonadicnode(n, ELOGNOT);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_IFGOTO);
- stmt->expr = n;
- stmt->label = label;
-
- n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.right), ELOGNOT);
- n->rtype = expr->rtype;
- n = makemonadicnode(n, ELOGNOT);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = n;
-
- stmt = CInline_NewStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- return create_objectnode(temp);
-}
-
-static ENode *CInline_SerializeELAND(ENode *expr) {
- ENode *n;
- Statement *stmt;
- CLabel *label;
- Object *temp = NULL;
-
- label = newlabel();
-
- n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.left), ELOGNOT);
- n->rtype = expr->rtype;
- n = makemonadicnode(n, ELOGNOT);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_IFNGOTO);
- stmt->expr = n;
- stmt->label = label;
-
- n = makemonadicnode(CInline_SerializeExpr(expr->data.diadic.right), ELOGNOT);
- n->rtype = expr->rtype;
- n = makemonadicnode(n, ELOGNOT);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = n;
-
- stmt = CInline_NewStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- return create_objectnode(temp);
-}
-
-static ENode *CInline_SerializeEPRECOMP(ENode *expr) {
- UIDTemp *uidtemp;
-
- uidtemp = cinline_uid_temps;
- while (1) {
- if (!uidtemp)
- CError_FATAL(2449);
- if (uidtemp->uid == expr->data.precompid)
- return create_objectnode(uidtemp->object);
- uidtemp = uidtemp->next;
- }
-}
-
-static ENode *CInline_SerializeENULLCHECK(ENode *expr) {
- Statement *stmt;
- CLabel *label;
- ENode *n;
- Object *temp = NULL;
- UIDTemp uidtemp;
-
- label = newlabel();
-
- n = CInline_SerializeExpr(expr->data.nullcheck.nullcheckexpr);
- stmt = CInline_NewStatement(ST_IFNGOTO);
- stmt->expr = CInline_LoadToTemp(n, &temp);
- stmt->label = label;
-
- uidtemp.next = cinline_uid_temps;
- uidtemp.object = temp;
- uidtemp.uid = expr->data.nullcheck.precompid;
- cinline_uid_temps = &uidtemp;
-
- n = CInline_SerializeExpr(expr->data.nullcheck.condexpr);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = CInline_LoadToTemp(n, &temp);
-
- cinline_uid_temps = uidtemp.next;
-
- stmt = CInline_NewStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- return create_objectnode(temp);
-}
-
-static ENode *CInline_SerializeECOND(ENode *expr) {
- Statement *stmt;
- CLabel *label1;
- CLabel *label2;
- ENode *n;
- Object *temp = NULL;
-
- label1 = newlabel();
- label2 = newlabel();
-
- n = CInline_SerializeExpr(expr->data.cond.cond);
- stmt = CInline_NewStatement(ST_IFNGOTO);
- stmt->expr = n;
- stmt->label = label1;
-
- n = CInline_SerializeExpr(expr->data.cond.expr1);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = n;
-
- stmt = CInline_NewStatement(ST_GOTO);
- stmt->label = label2;
-
- stmt = CInline_NewStatement(ST_LABEL);
- stmt->label = label1;
- label1->stmt = stmt;
-
- n = CInline_SerializeExpr(expr->data.cond.expr2);
- n = CInline_LoadToTemp(n, &temp);
- stmt = CInline_NewStatement(ST_EXPRESSION);
- stmt->expr = n;
-
- stmt = CInline_NewStatement(ST_LABEL);
- stmt->label = label2;
- label2->stmt = stmt;
-
- if (!temp) {
- n = nullnode();
- n->rtype = &stvoid;
- return n;
- }
-
- return create_objectnode(temp);
-}
-
-static ENode *CInline_SerializeExpr(ENode *expr) {
- ENodeList *list;
-
- switch (expr->type) {
- case EFORCELOAD:
- return CInline_SerializeEFORCELOAD(expr);
- case ECOMMA:
- return CInline_SerializeECOMMA(expr);
- case ELAND:
- return CInline_SerializeELAND(expr);
- case ELOR:
- return CInline_SerializeELOR(expr);
- case EPRECOMP:
- return CInline_SerializeEPRECOMP(expr);
- case ENULLCHECK:
- return CInline_SerializeENULLCHECK(expr);
- case ECOND:
- return CInline_SerializeECOND(expr);
-
- case EINITTRYCATCH:
- expr->data.itc.initexpr = CInline_SerializeExpr(expr->data.itc.initexpr);
- expr->data.itc.tryexpr = CInline_SerializeExpr(expr->data.itc.tryexpr);
- expr->data.itc.catchexpr = CInline_SerializeExpr(expr->data.itc.catchexpr);
- expr->data.itc.result = CInline_SerializeExpr(expr->data.itc.result);
- return expr;
-
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case ETYPCON:
- case EBITFIELD:
- expr->data.monadic = CInline_SerializeExpr(expr->data.monadic);
- return expr;
-
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- case EPMODULO:
- case EROTL:
- case EROTR:
- expr->data.diadic.left = CInline_SerializeExpr(expr->data.diadic.left);
- expr->data.diadic.right = CInline_SerializeExpr(expr->data.diadic.right);
- return expr;
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case ELABEL:
- case EOBJLIST:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return expr;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- expr->data.funccall.funcref = CInline_SerializeExpr(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- list->node = CInline_SerializeExpr(list->node);
- return expr;
-
- case EMFPOINTER:
- // bug???
- expr->data.mfpointer.accessnode = CInline_SerializeExpr(expr->data.mfpointer.accessnode);
- expr->data.mfpointer.accessnode = CInline_SerializeExpr(expr->data.mfpointer.mfpointer);
- return expr;
-
- case EMEMBER:
- if (expr->data.emember->expr)
- return CInline_SerializeExpr(expr->data.emember->expr);
- return expr;
-
- default:
- CError_FATAL(2684);
- return expr;
- }
-}
-
-void CInline_SerializeStatement(Statement *stmt) {
- Statement *scan;
- Statement *copy;
-
- cinline_serial_stmt = NULL;
- cinline_uid_temps = NULL;
- stmt->expr = CInline_SerializeExpr(stmt->expr);
-
- if (cinline_serial_stmt) {
- for (scan = cinline_serial_stmt; scan; scan = scan->next) {
- scan->value = stmt->value;
- scan->dobjstack = stmt->dobjstack;
- scan->sourceoffset = stmt->sourceoffset;
- scan->sourcefilepath = stmt->sourcefilepath;
- }
-
- copy = CInline_NewStatement(ST_EXPRESSION);
- *copy = *stmt;
-
- *stmt = *cinline_serial_stmt;
- }
-}
-
-static void CInline_UnpackSwitch(Statement *stmt, CI_Statement *packstmt, CLabel **labels) {
- SwitchInfo *info;
- SwitchCase *swcase;
- short i;
-
- info = lalloc(sizeof(SwitchInfo));
- stmt->label = (CLabel *) info;
- CError_ASSERT(2730, info->defaultlabel = labels[packstmt->u.switchdata->defaultlabelID]);
- info->x8 = packstmt->u.switchdata->unkSwitch8;
-
- for (i = 0; i < packstmt->u.switchdata->numcases; i++) {
- if (i == 0) {
- swcase = lalloc(sizeof(SwitchCase));
- info->cases = swcase;
- } else {
- swcase->next = lalloc(sizeof(SwitchCase));
- swcase = swcase->next;
- }
-
- swcase->next = NULL;
- swcase->min = packstmt->u.switchdata->cases[i].min;
- swcase->max = packstmt->u.switchdata->cases[i].max;
- CError_ASSERT(2740, swcase->label = labels[packstmt->u.switchdata->cases[i].labelID]);
- }
-}
-
-Object *CInline_GetLocalObj(SInt32 id, Boolean flag) {
- ObjectList *list;
-
- if (id) {
- if (id & 0x80000000) {
- id = (id & 0x7FFFFFFF) - 1;
- if (flag) {
- CError_ASSERT(2761, local_aobjects[id].object);
- return local_aobjects[id].object;
- }
-
- for (list = arguments; list; list = list->next, id--) {
- if (id == 0)
- return list->object;
- }
-
- CError_FATAL(2765);
- } else {
- id--;
- if (flag) {
- CError_ASSERT(2772, local_dobjects[id]);
- return local_dobjects[id];
- }
-
- for (list = locals; list; list = list->next, id--) {
- if (id == 0)
- return list->object;
- }
-
- CError_FATAL(2776);
- }
- }
-
- return NULL;
-}
-
-static ExceptionAction *CInline_UnpackActions(CI_Statement *packstmt, Boolean flag) {
- ExceptionAction *packexc;
- ExceptionAction *last;
- ExceptionAction *exc;
-
- packexc = packstmt->dobjstack;
- last = NULL;
-
- while (packexc) {
- exc = galloc(sizeof(ExceptionAction));
- exc->prev = last;
- last = exc;
-
- exc->type = packexc->type;
-
- switch (packexc->type) {
- case EAT_DESTROYLOCAL:
- exc->data.destroy_local.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local.local, flag);
- exc->data.destroy_local.dtor = packexc->data.destroy_local.dtor;
- break;
- case EAT_DESTROYLOCALCOND:
- exc->data.destroy_local_cond.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_cond.local, flag);
- exc->data.destroy_local_cond.dtor = packexc->data.destroy_local_cond.dtor;
- exc->data.destroy_local_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_cond.cond, flag);
- break;
- case EAT_DESTROYLOCALOFFSET:
- exc->data.destroy_local_offset.local = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_offset.local, flag);
- exc->data.destroy_local_offset.dtor = packexc->data.destroy_local_offset.dtor;
- exc->data.destroy_local_offset.offset = packexc->data.destroy_local_offset.offset;
- break;
- case EAT_DESTROYLOCALPOINTER:
- exc->data.destroy_local_pointer.pointer = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_pointer.pointer, flag);
- exc->data.destroy_local_pointer.dtor = packexc->data.destroy_local_pointer.dtor;
- break;
- case EAT_DESTROYLOCALARRAY:
- exc->data.destroy_local_array.localarray = CInline_GetLocalObj((SInt32) packexc->data.destroy_local_array.localarray, flag);
- exc->data.destroy_local_array.dtor = packexc->data.destroy_local_array.dtor;
- exc->data.destroy_local_array.elements = packexc->data.destroy_local_array.elements;
- exc->data.destroy_local_array.element_size = packexc->data.destroy_local_array.element_size;
- break;
- case EAT_DESTROYPARTIALARRAY:
- exc->data.destroy_partial_array.arraypointer = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.arraypointer, flag);
- exc->data.destroy_partial_array.arraycounter = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.arraycounter, flag);
- exc->data.destroy_partial_array.dtor = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.dtor, flag);
- exc->data.destroy_partial_array.element_size = CInline_GetLocalObj((SInt32) packexc->data.destroy_partial_array.element_size, flag);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- exc->data.destroy_member.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member.objectptr, flag);
- exc->data.destroy_member.dtor = packexc->data.destroy_member.dtor;
- exc->data.destroy_member.offset = packexc->data.destroy_member.offset;
- break;
- case EAT_DESTROYMEMBERCOND:
- exc->data.destroy_member_cond.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_cond.objectptr, flag);
- exc->data.destroy_member_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_cond.cond, flag);
- exc->data.destroy_member_cond.dtor = packexc->data.destroy_member_cond.dtor;
- exc->data.destroy_member_cond.offset = packexc->data.destroy_member_cond.offset;
- break;
- case EAT_DESTROYMEMBERARRAY:
- exc->data.destroy_member_array.objectptr = CInline_GetLocalObj((SInt32) packexc->data.destroy_member_array.objectptr, flag);
- exc->data.destroy_member_array.dtor = packexc->data.destroy_member_array.dtor;
- exc->data.destroy_member_array.offset = packexc->data.destroy_member_array.offset;
- exc->data.destroy_member_array.elements = packexc->data.destroy_member_array.elements;
- exc->data.destroy_member_array.element_size = packexc->data.destroy_member_array.element_size;
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- exc->data.delete_pointer.pointerobject = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer.pointerobject, flag);
- exc->data.delete_pointer.deletefunc = packexc->data.delete_pointer.deletefunc;
- break;
- case EAT_DELETEPOINTERCOND:
- exc->data.delete_pointer_cond.pointerobject = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer_cond.pointerobject, flag);
- exc->data.delete_pointer_cond.deletefunc = packexc->data.delete_pointer_cond.deletefunc;
- exc->data.delete_pointer_cond.cond = CInline_GetLocalObj((SInt32) packexc->data.delete_pointer_cond.cond, flag);
- break;
- case EAT_CATCHBLOCK: {
- LabelTrans *trans;
- exc->data.catch_block.catch_object = CInline_GetLocalObj((SInt32) packexc->data.catch_block.catch_object, flag);
- exc->data.catch_block.catch_info_object = CInline_GetLocalObj((SInt32) packexc->data.catch_block.catch_info_object, flag);
-
- trans = lalloc(sizeof(LabelTrans));
- trans->next = cinline_label_trans;
- cinline_label_trans = trans;
-
- trans->id = (SInt32) packexc->data.catch_block.catch_label;
- trans->labelptr = &exc->data.catch_block.catch_label;
-
- exc->data.catch_block.catch_typeid = packexc->data.catch_block.catch_typeid;
- exc->data.catch_block.catch_type = packexc->data.catch_block.catch_type;
- exc->data.catch_block.catch_qual = packexc->data.catch_block.catch_qual;
- break;
- }
- case EAT_ACTIVECATCHBLOCK:
- exc->data.active_catch_block.catch_info_object = CInline_GetLocalObj((SInt32) packexc->data.active_catch_block.catch_info_object, flag);
- break;
- case EAT_SPECIFICATION: {
- LabelTrans *trans;
- exc->data.specification.unexp_ids = packexc->data.specification.unexp_ids;
- exc->data.specification.unexp_id = packexc->data.specification.unexp_id;
-
- trans = lalloc(sizeof(LabelTrans));
- trans->next = cinline_label_trans;
- cinline_label_trans = trans;
-
- trans->id = (SInt32) packexc->data.specification.unexp_label;
- trans->labelptr = &exc->data.specification.unexp_label;
-
- exc->data.specification.unexp_info_object = CInline_GetLocalObj((SInt32) packexc->data.specification.unexp_info_object, flag);
- break;
- }
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(2904);
- }
-
- packexc = packexc->prev;
- }
-
- return last;
-}
-
-static Statement *CInline_ExpandStatements(Object *funcobj, Statement *stmt, CI_FuncData *funcdata, ENode *funccall, CLabel *label, Object *resultobj, Boolean flag) {
- CLabel **labels;
- CI_Statement *packstmt;
- short i;
- CI_StmtLink *stmtLinks;
- CI_StmtLink *link;
- ENode *setupArgs;
- Boolean is_result_class_1;
- Statement origStmt;
-
- origStmt = *stmt;
- is_result_class_1 = CMach_GetFunctionResultClass(TYPE_FUNC(funcobj->type)) == 1;
-
- if ((setupArgs = CInline_SetupArgsExpression(funcobj, funcdata, funccall->data.funccall.args))) {
- stmt->type = ST_EXPRESSION;
- stmt->expr = CInline_FoldConst(setupArgs);
- } else {
- stmt->type = ST_NOP;
- }
-
- stmtLinks = NULL;
- cinline_label_trans = NULL;
-
- labels = lalloc(sizeof(CLabel *) * funcdata->numstatements);
- memclrw(labels, sizeof(CLabel *) * funcdata->numstatements);
-
- for (i = 0, packstmt = funcdata->statements; i < funcdata->numstatements; i++, packstmt++) {
- stmt->next = lalloc(sizeof(Statement));
- stmt = stmt->next;
- *stmt = origStmt;
-
- stmt->type = packstmt->type;
- stmt->flags = packstmt->flags;
- stmt->value += packstmt->value;
-
- if (packstmt->dobjstack) {
- ExceptionAction *unpacked = CInline_UnpackActions(packstmt, 1);
- if (stmt->dobjstack) {
- ExceptionAction *scan = unpacked;
- while (scan->prev)
- scan = scan->prev;
- scan->prev = stmt->dobjstack;
- }
- stmt->dobjstack = unpacked;
- }
-
- switch (stmt->type) {
- case ST_NOP:
- break;
-
- case ST_EXPRESSION:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.expr, CopyMode4));
- break;
-
- case ST_RETURN:
- if (packstmt->u.expr) {
- stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.expr, CopyMode4));
- if (is_result_class_1)
- stmt->expr = makecommaexpression(stmt->expr, CInline_ReturnMemResult(funcobj));
-
- if (resultobj) {
- stmt->type = ST_EXPRESSION;
- stmt->expr = makediadicnode(create_objectnode2(resultobj), stmt->expr, EASS);
- } else {
- stmt->type = origStmt.type;
- if (stmt->type == ST_EXPRESSION && !CInline_ExpressionHasSideEffect(stmt->expr))
- stmt->type = ST_NOP;
- }
-
- if (label) {
- stmt->next = lalloc(sizeof(Statement));
- stmt = stmt->next;
- *stmt = origStmt;
- stmt->type = ST_GOTO;
- stmt->label = label;
- }
- } else {
- if (label) {
- stmt->type = ST_GOTO;
- stmt->label = label;
- } else {
- stmt->type = ST_NOP;
- }
- }
- break;
-
- case ST_LABEL:
- labels[i] = stmt->label = newlabel();
- stmt->label->stmt = stmt;
- break;
-
- case ST_IFGOTO:
- case ST_IFNGOTO:
- stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.ifgoto.expr, CopyMode4));
- case ST_GOTO:
- link = lalloc(sizeof(CI_StmtLink));
- link->next = stmtLinks;
- stmtLinks = link;
-
- link->stmt = stmt;
- link->ciStmt = packstmt;
- break;
-
- case ST_SWITCH:
- stmt->expr = CInline_FoldConst(CInline_CopyExpression(packstmt->u.switchdata->expr, CopyMode4));
- case ST_ASM:
- link = lalloc(sizeof(CI_StmtLink));
- link->next = stmtLinks;
- stmtLinks = link;
-
- link->stmt = stmt;
- link->ciStmt = packstmt;
- break;
-
- default:
- CError_FATAL(3040);
- }
- }
-
- if (label) {
- stmt->next = lalloc(sizeof(Statement));
- stmt = stmt->next;
- *stmt = origStmt;
-
- stmt->type = ST_LABEL;
- stmt->label = label;
- label->stmt = stmt;
-
- if (flag) {
- stmt->next = lalloc(sizeof(Statement));
- stmt = stmt->next;
- *stmt = origStmt;
- }
- }
-
- while (stmtLinks) {
- Statement *linkstmt = stmtLinks->stmt;
- packstmt = stmtLinks->ciStmt;
-
- switch (linkstmt->type) {
- case ST_GOTO:
- CError_ASSERT(3060, linkstmt->label = labels[packstmt->u.statementnum]);
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CError_ASSERT(3065, linkstmt->label = labels[packstmt->u.ifgoto.statementnum]);
- break;
- case ST_SWITCH:
- CInline_UnpackSwitch(linkstmt, packstmt, labels);
- break;
- case ST_ASM:
- InlineAsm_UnpackAsmStatement(linkstmt, labels, 1, packstmt->u.asmdata.data, packstmt->u.asmdata.size);
- break;
- default:
- CError_FATAL(3076);
- }
-
- stmtLinks = stmtLinks->next;
- }
-
- while (cinline_label_trans) {
- CError_ASSERT(3083, *cinline_label_trans->labelptr = labels[cinline_label_trans->id]);
- cinline_label_trans = cinline_label_trans->next;
- }
-
- return stmt;
-}
-
-static Statement *CInline_InlineFunctionStatement(Statement *stmt, Boolean *changed) {
- Object *object;
- CI_FuncData *funcdata;
- CLabel *label;
-
- *changed = 0;
-
- object = stmt->expr->data.funccall.funcref->data.objref;
- if (object->datatype == DALIAS)
- object = object->u.alias.object;
-
- funcdata = object->u.func.u.ifuncdata;
- if (!funcdata || funcdata->can_inline < CI_CanInline3)
- return stmt;
-
- if (stmt->type != ST_EXPRESSION) {
- short i;
- for (i = 0; i < (funcdata->numstatements - 1); i++) {
- if (funcdata->statements[i].type == ST_RETURN)
- return stmt;
- }
-
- if (funcdata->statements[funcdata->numstatements - 1].type != ST_RETURN)
- return stmt;
-
- label = NULL;
- } else {
- label = newlabel();
- }
-
- *changed = 1;
- return CInline_ExpandStatements(object, stmt, funcdata, stmt->expr, label, NULL, 0);
-}
-
-static Statement *CInline_ExtractInlineFunction(Statement *stmt) {
- ENode *expr;
- CI_FuncData *funcdata;
- short i;
- Object *funcObject;
- Object *resultObject;
-
- for (i = 0; i < cinline_stmtlevelexprs; i++) {
- expr = cinline_stmtlevelexpr[i];
-
- funcObject = expr->data.funccall.funcref->data.objref;
- if (funcObject->datatype == DALIAS)
- funcObject = funcObject->u.alias.object;
-
- if ((funcdata = funcObject->u.func.u.ifuncdata)) {
- TypeFunc *tfunc = TYPE_FUNC(funcObject->type);
- CError_ASSERT(3141, IS_TYPE_FUNC(tfunc));
-
- if (!IS_TYPE_VOID(tfunc->functype)) {
- if (CMach_GetFunctionResultClass(TYPE_FUNC(funcObject->type)) == 1)
- resultObject = CInline_NewLocalObject(CDecl_NewPointerType(tfunc->functype), 0, 0, 0);
- else
- resultObject = CInline_NewLocalObject(tfunc->functype, 0, 0, 0);
- } else {
- resultObject = NULL;
- }
-
- stmt = CInline_ExpandStatements(funcObject, stmt, funcdata, expr, newlabel(), resultObject, 1);
-
- if (resultObject)
- *expr = *create_objectnode2(resultObject);
- else
- *expr = *nullnode();
- }
- }
-
- return stmt;
-}
-
-static Statement *CInline_ExpandStatement(Statement *stmt) {
- Boolean changed;
-
- do {
- changed = 0;
-
- if (
- stmt->type == ST_EXPRESSION &&
- ENODE_IS(stmt->expr, EINDIRECT) &&
- !CParser_IsVolatile(stmt->expr->rtype, ENODE_QUALS(stmt->expr))
- )
- {
- stmt->expr = stmt->expr->data.monadic;
- changed = 1;
- if (ENODE_IS2(stmt->expr, EOBJREF, EBITFIELD))
- stmt->expr = nullnode();
- }
-
- if (ENODE_IS(stmt->expr, ECOMMA)) {
- Statement *newStmt = lalloc(sizeof(Statement));
- *newStmt = *stmt;
-
- stmt->next = newStmt;
- stmt->type = ST_EXPRESSION;
- stmt->expr = stmt->expr->data.diadic.left;
- newStmt->expr = newStmt->expr->data.diadic.right;
-
- changed = 1;
- }
- } while (changed);
-
- if (
- ENODE_IS2(stmt->expr, EFUNCCALL, EFUNCCALLP) &&
- ENODE_IS(stmt->expr->data.funccall.funcref, EOBJREF) &&
- CInline_InlineFunctionCheck(stmt->expr->data.funccall.funcref)
- )
- {
- stmt = CInline_InlineFunctionStatement(stmt, &changed);
- if (changed) {
- any_inline_expanded = 1;
- return stmt;
- }
- }
-
- inline_expanded = 0;
- cinline_unconditionalpart = 1;
- cinline_serialize_stmt = 0;
- cinline_stmtlevelexprs = 0;
- stmt->expr = CInline_ExpandExpression(stmt->expr);
-
- if (cinline_serialize_stmt) {
- cinline_unconditionalpart = 1;
- cinline_serialize_stmt = 0;
- cinline_stmtlevelexprs = 0;
- CInline_SerializeStatement(stmt);
- stmt->expr = CInline_ExpandExpression(stmt->expr);
- }
-
- if (inline_expanded) {
- stmt->expr = CInline_FoldConst(stmt->expr);
- any_inline_expanded = 1;
- }
-
- if (cinline_stmtlevelexprs) {
- stmt = CInline_ExtractInlineFunction(stmt);
- any_inline_expanded = 1;
- }
-
- return stmt;
-}
-
-static void CInline_ForceReverseSearch(ENode *) {
- cinline_funccallfound = 1;
-}
-
-static ENode *CInline_ForceReverseEvaluation(ENode *expr) {
- ENode *commanodes;
- ENodeList *list;
- int counter;
- ENode *ass;
- ENode *inner;
- ENode *copy;
-
- list = expr->data.funccall.args;
- counter = 0;
- commanodes = NULL;
-
- while (list) {
- cinline_funccallfound = 0;
- inner = list->node;
- CExpr_SearchExprTree(inner, CInline_ForceReverseSearch, 2, EFUNCCALL, EFUNCCALLP);
-
- if (cinline_funccallfound && ++counter > 0) {
- inner = create_objectrefnode(create_temp_object(inner->rtype));
- copy = lalloc(sizeof(ENode));
- *copy = *inner;
-
- copy = makemonadicnode(copy, EINDIRECT);
- copy->rtype = TPTR_TARGET(copy->rtype);
-
- inner = makemonadicnode(inner, EINDIRECT);
- inner->rtype = TPTR_TARGET(inner->rtype);
-
- ass = makediadicnode(inner, copy, EASS);
- list->node = copy;
-
- if (commanodes)
- commanodes = makediadicnode(ass, commanodes, ECOMMA);
- else
- commanodes = ass;
- }
-
- list = list->next;
- }
-
- if (commanodes) {
- commanodes = makediadicnode(commanodes, expr, ECOMMA);
- commanodes->rtype = expr->rtype;
- return commanodes;
- }
-
- return expr;
-}
-
-static void CInline_ExportCheck(ENode *expr) {
- while (1) {
- switch (expr->type) {
- case EOBJREF:
- CInline_ObjectAddrRef(expr->data.objref);
- if (expr->data.objref->datatype == DALIAS) {
- CExpr_AliasTransform(expr);
- continue;
- }
- return;
-
- ENODE_CASE_MONADIC:
- expr = expr->data.monadic;
- continue;
-
- ENODE_CASE_DIADIC_ALL:
- CInline_ExportCheck(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- continue;
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EPRECOMP:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- return;
-
- case ELABEL:
- if (expr->data.label->stmt)
- expr->data.label->stmt->flags |= StmtFlag_1;
- return;
-
- case EFUNCCALL:
- case EFUNCCALLP: {
- ENodeList *list;
- TypeClass *tclass;
- SInt32 index;
-
- for (list = expr->data.funccall.args; list; list = list->next)
- CInline_ExportCheck(list->node);
-
- expr = expr->data.funccall.funcref;
- if (
- copts.warn_notinlined &&
- !copts.dontinline &&
- ENODE_IS(expr, EOBJREF) &&
- (expr->data.objref->qual & Q_INLINE) &&
- expr->data.objref->datatype != DINLINEFUNC &&
- !CParser_IsVirtualFunction(expr->data.objref, &tclass, &index)
- )
- CError_Warning(CErrorStr342, expr->data.objref);
-
- continue;
- }
-
- case ENULLCHECK:
- CInline_ExportCheck(expr->data.nullcheck.nullcheckexpr);
- expr = expr->data.nullcheck.condexpr;
- continue;
-
- case EMFPOINTER:
- *expr = *nullnode();
- continue;
-
- case ECOND:
- CInline_ExportCheck(expr->data.cond.cond);
- CInline_ExportCheck(expr->data.cond.expr1);
- expr = expr->data.cond.expr2;
- continue;
-
- case EMEMBER:
- if (expr->data.emember->expr) {
- *expr = *expr->data.emember->expr;
- continue;
- }
- case EOBJLIST:
- *expr = *nullnode();
- continue;
-
- default:
- CError_FATAL(3372);
- }
- }
-}
-
-static void CInline_Expand(Statement *stmt) {
- Statement *scan;
-
- if (!copts.dontinline && copts.inlinelevel >= 0) {
- if (copts.inline_bottom_up) {
- inline_max_size = copts.inlinemaxsize;
- while (inline_max_size > 1 && EstimateExpandedSizeOfFunction(stmt) > copts.inlinemaxtotalsize)
- inline_max_size >>= 1;
- }
-
- cinline_level = 0;
- while (1) {
- any_inline_expanded = 0;
- for (scan = stmt; scan; scan = scan->next) {
- switch (scan->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_ASM:
- break;
- case ST_RETURN:
- if (!scan->expr)
- break;
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_GOTOEXPR:
- scan = CInline_ExpandStatement(scan);
- break;
- default:
- CError_FATAL(3438);
- }
- }
-
- if (!copts.inline_bottom_up && !any_inline_expanded)
- break;
-
- if (!copts.alwaysinline || copts.inline_bottom_up) {
- if (copts.inlinelevel == 0) {
- if (copts.inline_bottom_up) {
- if ((cinline_level + 1) >= 8)
- break;
- } else {
- if (cinline_level >= 3)
- break;
- }
- } else {
- if ((cinline_level + 1) >= copts.inlinelevel)
- break;
- }
- }
-
- if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr)
- CError_UserBreak();
-
- cinline_level++;
- }
- }
-
- while (stmt) {
- if (stmt->dobjstack)
- CExcept_CheckStackRefs(stmt->dobjstack);
-
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_ASM:
- break;
- case ST_RETURN:
- if (!stmt->expr)
- break;
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_GOTOEXPR:
- CInline_ExportCheck(stmt->expr);
- break;
- default:
- CError_FATAL(3501);
- }
-
- stmt = stmt->next;
- }
-}
-
-SInt16 CInline_GetStatementNumber(Statement *first, Statement *stmt) {
- SInt16 number = 0;
-
- while (first) {
- if (first == stmt)
- return number;
-
- first = first->next;
- number++;
- }
-
- CError_FATAL(3517);
- return 0;
-}
-
-static CI_Switch *CInline_PackSwitch(Statement *start, Statement *stmt) {
- SwitchInfo *info;
- SwitchCase *swcase;
- short numcases;
- CI_Switch *packed;
-
- info = (SwitchInfo *) stmt->label;
- swcase = info->cases;
- numcases = 0;
- while (swcase) {
- swcase = swcase->next;
- numcases++;
- }
-
- packed = galloc(sizeof(CI_Switch) + numcases * sizeof(CI_SwitchCase));
- packed->expr = CInline_CopyExpression(stmt->expr, CopyMode2);
- packed->defaultlabelID = CInline_GetStatementNumber(start, info->defaultlabel->stmt);
- packed->unkSwitch8 = info->x8;
- packed->numcases = numcases;
-
- for (swcase = info->cases, numcases = 0; swcase; swcase = swcase->next, numcases++) {
- packed->cases[numcases].labelID = CInline_GetStatementNumber(start, swcase->label->stmt);
- packed->cases[numcases].min = swcase->min;
- packed->cases[numcases].max = swcase->max;
- }
-
- return packed;
-}
-
-static UInt8 CInline_CanInline(Object *object, Statement *stmt) {
- UInt8 resultClass;
- FuncArg *arg;
- UInt8 result;
-
- resultClass = CMach_GetFunctionResultClass(TYPE_FUNC(object->type));
- if (
- resultClass &&
- (resultClass != 1 || (IS_TYPE_CLASS(TYPE_FUNC(object->type)->functype) && CClass_Destructor(TYPE_CLASS(TYPE_FUNC(object->type)->functype))))
- )
- return CI_CanInline0;
-
- for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) {
- if (arg == &elipsis)
- return CI_CanInline0;
- if (arg == &oldstyle)
- break;
-
- if (IS_TYPE_CLASS(arg->type) && CClass_Destructor(TYPE_CLASS(arg->type)))
- return CI_CanInline0;
- }
-
- result = CI_CanInline6;
-
- while (stmt) {
- if (stmt->dobjstack)
- return CI_CanInline3;
-
- switch (stmt->type) {
- case ST_EXPRESSION:
- break;
- case ST_RETURN:
- if (stmt->next || (stmt->expr == NULL && TYPE_FUNC(object->type)->functype != &stvoid))
- result = CI_CanInline3;
- break;
- default:
- result = CI_CanInline3;
- }
-
- stmt = stmt->next;
- }
-
- return result;
-}
-
-static ExceptionAction *CInline_PackActions(Statement *start, Statement *stmt) {
- ExceptionAction *exc;
- ExceptionAction *last;
- ExceptionAction *packexc;
-
- exc = stmt->dobjstack;
- last = NULL;
-
- while (exc) {
- packexc = galloc(sizeof(ExceptionAction));
- packexc->prev = last;
- last = packexc;
-
- packexc->type = exc->type;
-
- switch (exc->type) {
- case EAT_DESTROYLOCAL:
- packexc->data.destroy_local.local = (void *) CInline_GetLocalID(exc->data.destroy_local.local);
- packexc->data.destroy_local.dtor = exc->data.destroy_local.dtor;
- break;
- case EAT_DESTROYLOCALCOND:
- packexc->data.destroy_local_cond.local = (void *) CInline_GetLocalID(exc->data.destroy_local_cond.local);
- packexc->data.destroy_local_cond.dtor = exc->data.destroy_local_cond.dtor;
- packexc->data.destroy_local_cond.cond = (void *) CInline_GetLocalID(exc->data.destroy_local_cond.cond);
- break;
- case EAT_DESTROYLOCALOFFSET:
- packexc->data.destroy_local_offset.local = (void *) CInline_GetLocalID(exc->data.destroy_local_offset.local);
- packexc->data.destroy_local_offset.dtor = exc->data.destroy_local_offset.dtor;
- packexc->data.destroy_local_offset.offset = exc->data.destroy_local_offset.offset;
- break;
- case EAT_DESTROYLOCALPOINTER:
- packexc->data.destroy_local_pointer.pointer = (void *) CInline_GetLocalID(exc->data.destroy_local_pointer.pointer);
- packexc->data.destroy_local_pointer.dtor = exc->data.destroy_local_pointer.dtor;
- break;
- case EAT_DESTROYLOCALARRAY:
- packexc->data.destroy_local_array.localarray = (void *) CInline_GetLocalID(exc->data.destroy_local_array.localarray);
- packexc->data.destroy_local_array.dtor = exc->data.destroy_local_array.dtor;
- packexc->data.destroy_local_array.elements = exc->data.destroy_local_array.elements;
- packexc->data.destroy_local_array.element_size = exc->data.destroy_local_array.element_size;
- break;
- case EAT_DESTROYPARTIALARRAY:
- packexc->data.destroy_partial_array.arraypointer = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.arraypointer);
- packexc->data.destroy_partial_array.arraycounter = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.arraycounter);
- packexc->data.destroy_partial_array.dtor = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.dtor);
- packexc->data.destroy_partial_array.element_size = (void *) CInline_GetLocalID(exc->data.destroy_partial_array.element_size);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- packexc->data.destroy_member.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member.objectptr);
- packexc->data.destroy_member.dtor = exc->data.destroy_member.dtor;
- packexc->data.destroy_member.offset = exc->data.destroy_member.offset;
- break;
- case EAT_DESTROYMEMBERCOND:
- packexc->data.destroy_member_cond.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member_cond.objectptr);
- packexc->data.destroy_member_cond.cond = (void *) CInline_GetLocalID(exc->data.destroy_member_cond.cond);
- packexc->data.destroy_member_cond.dtor = exc->data.destroy_member_cond.dtor;
- packexc->data.destroy_member_cond.offset = exc->data.destroy_member_cond.offset;
- break;
- case EAT_DESTROYMEMBERARRAY:
- packexc->data.destroy_member_array.objectptr = (void *) CInline_GetLocalID(exc->data.destroy_member_array.objectptr);
- packexc->data.destroy_member_array.dtor = exc->data.destroy_member_array.dtor;
- packexc->data.destroy_member_array.offset = exc->data.destroy_member_array.offset;
- packexc->data.destroy_member_array.elements = exc->data.destroy_member_array.elements;
- packexc->data.destroy_member_array.element_size = exc->data.destroy_member_array.element_size;
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- packexc->data.delete_pointer.pointerobject = (void *) CInline_GetLocalID(exc->data.delete_pointer.pointerobject);
- packexc->data.delete_pointer.deletefunc = exc->data.delete_pointer.deletefunc;
- break;
- case EAT_DELETEPOINTERCOND:
- packexc->data.delete_pointer_cond.pointerobject = (void *) CInline_GetLocalID(exc->data.delete_pointer_cond.pointerobject);
- packexc->data.delete_pointer_cond.deletefunc = exc->data.delete_pointer_cond.deletefunc;
- packexc->data.delete_pointer_cond.cond = (void *) CInline_GetLocalID(exc->data.delete_pointer_cond.cond);
- break;
- case EAT_CATCHBLOCK:
- packexc->data.catch_block.catch_object = (void *) CInline_GetLocalID(exc->data.catch_block.catch_object);
- packexc->data.catch_block.catch_info_object = (void *) CInline_GetLocalID(exc->data.catch_block.catch_info_object);
- packexc->data.catch_block.catch_label = (void *) CInline_GetStatementNumber(start->next, exc->data.catch_block.catch_label->stmt);
- packexc->data.catch_block.catch_typeid = exc->data.catch_block.catch_typeid;
- packexc->data.catch_block.catch_type = exc->data.catch_block.catch_type;
- packexc->data.catch_block.catch_qual = exc->data.catch_block.catch_qual;
- break;
- case EAT_ACTIVECATCHBLOCK:
- packexc->data.active_catch_block.catch_info_object = (void *) CInline_GetLocalID(exc->data.active_catch_block.catch_info_object);
- packexc->data.active_catch_block.call_dtor = exc->data.active_catch_block.call_dtor;
- break;
- case EAT_SPECIFICATION:
- packexc->data.specification.unexp_ids = exc->data.specification.unexp_ids;
- packexc->data.specification.unexp_id = exc->data.specification.unexp_id;
- packexc->data.specification.unexp_label = (void *) CInline_GetStatementNumber(start->next, exc->data.specification.unexp_label->stmt);
- packexc->data.specification.unexp_info_object = (void *) CInline_GetLocalID(exc->data.specification.unexp_info_object);
- break;
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(3720);
- }
-
- exc = exc->prev;
- }
-
- return last;
-}
-
-void CInline_PackIFunctionData(CI_FuncData *funcdata, Statement *stmt, Object *object) {
- ObjectList *list;
- CI_Var *var;
- Statement *scan;
- CI_Statement *packstmt;
- int i;
-
- cinline_first_stmt = stmt->next;
- memclrw(funcdata, sizeof(CI_FuncData));
-
- funcdata->can_inline = CInline_CanInline(object, stmt->next);
-
- if (copts.filesyminfo) {
- funcdata->fileoffset = cparser_fileoffset;
- funcdata->fileoffset.is_inline = 1;
- funcdata->symdecloffset = symdecloffset;
- funcdata->functionbodyoffset = functionbodyoffset;
- funcdata->functionbodypath = functionbodypath;
- funcdata->symdeclend = symdeclend;
- }
-
- list = arguments;
- i = 0;
- while (list) {
- list = list->next;
- i++;
- }
-
- if ((funcdata->numarguments = i) > 0) {
- loc_args = funcdata->arguments = galloc(sizeof(CI_Var) * i);
- memclrw(funcdata->arguments, sizeof(CI_Var) * i);
-
- for (list = arguments, var = funcdata->arguments; list; list = list->next, var++) {
- var->name = list->object->name;
- var->type = list->object->type;
- var->qual = list->object->qual;
- var->sflags = CInline_GetObjectSFlags(list->object);
- var->xD = 0;
- var->xE = 1;
- }
- }
-
- list = locals;
- i = 0;
- while (list) {
- if (list->object->datatype == DLOCAL)
- i++;
- list = list->next;
- }
-
- if ((funcdata->numlocals = i) > 0) {
- loc_vars = funcdata->locals = galloc(sizeof(CI_Var) * i);
- memclrw(funcdata->locals, sizeof(CI_Var) * i);
-
- for (list = locals, var = funcdata->locals; list; list = list->next) {
- if (list->object->datatype == DLOCAL) {
- var->name = list->object->name;
- var->type = list->object->type;
- var->qual = list->object->qual;
- var->sflags = CInline_GetObjectSFlags(list->object);
- var->xD = 0;
- var->xE = 0;
- var++;
- }
- }
- }
-
- scan = stmt->next;
- i = 0;
- while (scan) {
- scan = scan->next;
- i++;
- }
-
- funcdata->numstatements = i;
- funcdata->statements = galloc(sizeof(CI_Statement) * i);
-
- for (scan = stmt->next, packstmt = funcdata->statements; scan; scan = scan->next, packstmt++) {
- packstmt->type = scan->type;
- packstmt->flags = scan->flags;
- packstmt->value = scan->value;
- packstmt->dobjstack = CInline_PackActions(stmt, scan);
- packstmt->sourceoffset = scan->sourceoffset;
- packstmt->sourcefilepath = scan->sourcefilepath;
-
- switch (scan->type) {
- case ST_NOP:
- case ST_LABEL:
- break;
- case ST_EXPRESSION:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- packstmt->u.expr = CInline_CopyExpression(scan->expr, CopyMode2);
- break;
- case ST_RETURN:
- if (scan->expr)
- packstmt->u.expr = CInline_CopyExpression(scan->expr, CopyMode2);
- else
- packstmt->u.expr = NULL;
- break;
- case ST_GOTO:
- packstmt->u.statementnum = CInline_GetStatementNumber(stmt->next, scan->label->stmt);
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- packstmt->u.ifgoto.expr = CInline_CopyExpression(scan->expr, CopyMode2);
- packstmt->u.ifgoto.statementnum = CInline_GetStatementNumber(stmt->next, scan->label->stmt);
- break;
- case ST_SWITCH:
- packstmt->u.switchdata = CInline_PackSwitch(stmt->next, scan);
- break;
- case ST_ASM:
- InlineAsm_PackAsmStatement(scan, stmt->next, &packstmt->u.asmdata.data, &packstmt->u.asmdata.size);
- break;
- default:
- CError_FATAL(3862);
- }
- }
-}
-
-void CInline_UnpackIFunctionData(Object *object, CI_FuncData *funcdata, Statement *firstStmt) {
- CLabel **labels;
- CI_Var *var;
- ObjectList *last;
- Statement *stmt;
- CI_Statement *packstmt;
- int i;
-
- cparser_fileoffset = funcdata->fileoffset;
- symdecloffset = funcdata->symdecloffset;
- functionbodyoffset = funcdata->functionbodyoffset;
- functionbodypath = funcdata->functionbodypath;
- symdeclend = funcdata->symdeclend;
-
- for (i = 0, var = funcdata->arguments; i < funcdata->numarguments; i++, var++) {
- if (i == 0) {
- last = lalloc(sizeof(ObjectList));
- arguments = last;
- } else {
- last->next = lalloc(sizeof(ObjectList));
- last = last->next;
- }
-
- object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- last->object = object;
- last->next = NULL;
-
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->datatype = DLOCAL;
- object->name = var->name;
- object->type = var->type;
- object->qual = var->qual;
- CInline_SetObjectSFlags(object, var->sflags);
- CFunc_SetupLocalVarInfo(object);
-
- if (funcdata->fileoffset.file) {
- object->u.var.info->deftoken.tokenfile = funcdata->fileoffset.file;
- object->u.var.info->deftoken.tokenoffset = funcdata->functionbodyoffset;
- }
- }
-
- for (i = 0, var = funcdata->locals; i < funcdata->numlocals; i++, var++) {
- if (i == 0) {
- last = lalloc(sizeof(ObjectList));
- locals = last;
- } else {
- last->next = lalloc(sizeof(ObjectList));
- last = last->next;
- }
-
- object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- last->object = object;
- last->next = NULL;
-
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->datatype = DLOCAL;
- object->name = var->name;
- object->type = var->type;
- object->qual = var->qual;
- CInline_SetObjectSFlags(object, var->sflags);
- CFunc_SetupLocalVarInfo(object);
-
- if (funcdata->fileoffset.file) {
- object->u.var.info->deftoken.tokenfile = funcdata->fileoffset.file;
- object->u.var.info->deftoken.tokenoffset = funcdata->functionbodyoffset;
- }
- }
-
- enode_idtrans = NULL;
- cinline_label_trans = NULL;
-
- labels = lalloc(sizeof(CLabel *) * funcdata->numstatements);
- memclrw(labels, sizeof(CLabel *) * funcdata->numstatements);
-
- for (i = 0, stmt = firstStmt, packstmt = funcdata->statements; i < funcdata->numstatements; i++, packstmt++) {
- stmt->next = lalloc(sizeof(Statement));
- stmt = stmt->next;
-
- stmt->type = packstmt->type;
- stmt->flags = packstmt->flags;
- stmt->value = packstmt->value;
- stmt->sourceoffset = packstmt->sourceoffset;
- stmt->sourcefilepath = packstmt->sourcefilepath;
- stmt->dobjstack = CInline_UnpackActions(packstmt, 0);
- stmt->next = NULL;
-
- switch (stmt->type) {
- case ST_NOP:
- case ST_GOTO:
- case ST_ASM:
- break;
- case ST_EXPRESSION:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- stmt->expr = CInline_CopyExpression(packstmt->u.expr, CopyMode3);
- break;
- case ST_RETURN:
- if (packstmt->u.expr)
- stmt->expr = CInline_CopyExpression(packstmt->u.expr, CopyMode3);
- else
- stmt->expr = NULL;
- break;
- case ST_LABEL:
- labels[i] = stmt->label = newlabel();
- stmt->label->stmt = stmt;
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- stmt->expr = CInline_CopyExpression(packstmt->u.ifgoto.expr, CopyMode3);
- break;
- case ST_SWITCH:
- stmt->expr = CInline_CopyExpression(packstmt->u.switchdata->expr, CopyMode3);
- break;
- default:
- CError_FATAL(4017);
- }
- }
-
- for (stmt = firstStmt->next, packstmt = funcdata->statements; stmt; stmt = stmt->next, packstmt++) {
- switch (stmt->type) {
- case ST_GOTO:
- CError_ASSERT(4024, stmt->label = labels[packstmt->u.statementnum]);
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CError_ASSERT(4029, stmt->label = labels[packstmt->u.ifgoto.statementnum]);
- break;
- case ST_SWITCH:
- CInline_UnpackSwitch(stmt, packstmt, labels);
- break;
- case ST_ASM:
- InlineAsm_UnpackAsmStatement(stmt, labels, 0, packstmt->u.asmdata.data, packstmt->u.asmdata.size);
- break;
- }
- }
-
- cinline_first_stmt = firstStmt->next;
-
- while (cinline_label_trans) {
- CError_ASSERT(4045, *cinline_label_trans->labelptr = labels[cinline_label_trans->id]);
- cinline_label_trans = cinline_label_trans->next;
- }
-}
-
-static void CInline_GenIFunctionCode(Object *object, CI_FuncData *func, UInt8 unk) {
- Boolean saveDebugInfo;
- CScopeSave saveScope;
- Statement firstStmt;
-
- if (cparamblkptr->precompile != 1 && func) {
- ObjGen_SetupSym();
- CScope_SetFunctionScope(object, &saveScope);
- CFunc_FuncGenSetup(&firstStmt, object);
- CInline_UnpackIFunctionData(object, func, &firstStmt);
-
- saveDebugInfo = copts.filesyminfo;
- if (copts.nosyminline || (!symdecloffset && !symdeclend))
- copts.filesyminfo = 0;
-
- expanding_function = object;
- recursive_inline = 0;
- CInline_Expand(&firstStmt);
-
- if (!anyerrors) {
- if (copts.filesyminfo)
- CPrep_SetSourceFile(&cparser_fileoffset);
- CodeGen_Generator(&firstStmt, object, unk, 0);
- }
-
- CScope_RestoreScope(&saveScope);
- copts.filesyminfo = saveDebugInfo;
- }
-}
-
-void CInline_AddDefaultFunctionAction(Object *object) {
- CI_Action *action;
-
- for (action = cinline_actionlist; action; action = action->next) {
- if (action->obj == object)
- return;
- }
-
- action = galloc(sizeof(CI_Action));
- memclrw(action, sizeof(CI_Action));
-
- action->actiontype = CI_ActionDefaultFunc;
- action->obj = object;
-
- action->next = cinline_actionlist;
- cinline_actionlist = action;
-}
-
-void CInline_AddInlineFunctionAction(Object *object, TypeClass *tclass, FileOffsetInfo *fileoffset, TokenStream *stream, Boolean flag) {
- CI_Action *action;
-
- for (action = flag ? cinline_tactionlist : cinline_actionlist; action; action = action->next) {
- if (action->obj == object)
- return;
- }
-
- CError_ASSERT(4132, IS_TYPE_FUNC(object->type));
-
- TYPE_FUNC(object->type)->flags |= FUNC_IS_TEMPL_INSTANCE;
-
- action = galloc(sizeof(CI_Action));
- memclrw(action, sizeof(CI_Action));
-
- action->actiontype = CI_ActionInlineFunc;
- action->obj = object;
- action->u.inlinefunc.tclass = tclass;
- action->u.inlinefunc.fileoffset = *fileoffset;
- action->u.inlinefunc.stream = *stream;
-
- if (flag) {
- action->next = cinline_tactionlist;
- cinline_tactionlist = action;
- TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000;
- } else {
- action->next = cinline_actionlist;
- cinline_actionlist = action;
- }
-}
-
-void CInline_AddMemberFunctionAction(Object *object, TemplClass *templ, TemplClassInst *inst, TemplateMember *tmemb) {
- CI_Action *action;
-
- for (action = cinline_tactionlist; action; action = action->next) {
- if (action->obj == object)
- return;
- }
-
- action = galloc(sizeof(CI_Action));
- memclrw(action, sizeof(CI_Action));
-
- action->actiontype = CI_ActionMemberFunc;
- action->obj = object;
- action->u.memberfunc.templ = templ;
- action->u.memberfunc.inst = inst;
- action->u.memberfunc.tmemb = tmemb;
-
- action->next = cinline_tactionlist;
- cinline_tactionlist = action;
-
- TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000;
-}
-
-void CInline_AddTemplateFunctionAction(Object *object, TemplateFunction *func, TemplFuncInstance *inst) {
- CI_Action *action;
-
- for (action = cinline_tactionlist; action; action = action->next) {
- if (action->obj == object)
- return;
- }
-
- action = galloc(sizeof(CI_Action));
- memclrw(action, sizeof(CI_Action));
-
- action->actiontype = CI_ActionTemplateFunc;
- action->obj = object;
- action->u.templatefunc.func = func;
- action->u.templatefunc.inst = inst;
-
- action->next = cinline_tactionlist;
- cinline_tactionlist = action;
-
- TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_200000;
-}
-
-static void CInline_AddFRefList_Object(Object *object) {
- ObjectList *list;
-
- if (
- !(object->datatype == DFUNC || object->datatype == DVFUNC) ||
- (object->flags & OBJECT_DEFINED) ||
- IS_TEMPL_FUNC(object->type)
- )
- return;
-
- for (list = cinline_freflist; list; list = list->next) {
- if (list->object == object)
- return;
- }
-
- list = lalloc(sizeof(ObjectList));
- list->object = object;
- list->next = cinline_freflist;
- cinline_freflist = list;
-
- if ((object->qual & Q_INLINE) && object->u.func.u.ifuncdata)
- CInline_AddFRefList_InlineFunc(object->u.func.u.ifuncdata);
-}
-
-static void CInline_AddFRefList_ExAction(ExceptionAction *exc) {
- while (exc) {
- switch (exc->type) {
- case EAT_DESTROYLOCAL:
- CInline_AddFRefList_Object(exc->data.destroy_local.dtor);
- break;
- case EAT_DESTROYLOCALCOND:
- CInline_AddFRefList_Object(exc->data.destroy_local_cond.dtor);
- break;
- case EAT_DESTROYLOCALOFFSET:
- CInline_AddFRefList_Object(exc->data.destroy_local_offset.dtor);
- break;
- case EAT_DESTROYLOCALPOINTER:
- CInline_AddFRefList_Object(exc->data.destroy_local_pointer.dtor);
- break;
- case EAT_DESTROYLOCALARRAY:
- CInline_AddFRefList_Object(exc->data.destroy_local_array.dtor);
- break;
- case EAT_DESTROYPARTIALARRAY:
- CInline_AddFRefList_Object(exc->data.destroy_partial_array.dtor);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- CInline_AddFRefList_Object(exc->data.destroy_member.dtor);
- break;
- case EAT_DESTROYMEMBERCOND:
- CInline_AddFRefList_Object(exc->data.destroy_member_cond.dtor);
- break;
- case EAT_DESTROYMEMBERARRAY:
- CInline_AddFRefList_Object(exc->data.destroy_member_array.dtor);
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- CInline_AddFRefList_Object(exc->data.delete_pointer.deletefunc);
- break;
- case EAT_DELETEPOINTERCOND:
- CInline_AddFRefList_Object(exc->data.delete_pointer_cond.deletefunc);
- break;
- case EAT_CATCHBLOCK:
- case EAT_ACTIVECATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(4307);
- }
- exc = exc->prev;
- }
-}
-
-static void CInline_AddFRefList_ExprCB(ENode *expr) {
- CInline_AddFRefList_Object(expr->data.objref);
-}
-
-static void CInline_AddFRefList_Expr(ENode *expr) {
- CExpr_SearchExprTree(expr, CInline_AddFRefList_ExprCB, 1, EOBJREF);
-}
-
-static void CInline_AddFRefList_Statement(Statement *stmt) {
- while (stmt) {
- if (stmt->dobjstack)
- CInline_AddFRefList_ExAction(stmt->dobjstack);
-
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_ASM:
- break;
- case ST_RETURN:
- if (!stmt->expr)
- break;
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_GOTOEXPR:
- CInline_AddFRefList_Expr(stmt->expr);
- break;
- default:
- CError_FATAL(4368);
- }
-
- stmt = stmt->next;
- }
-}
-
-static void CInline_AddFRefList_InlineFunc(CI_FuncData *data) {
- short i;
- CI_Statement *stmt;
- ExceptionAction *exc;
-
- for (i = 0; i < data->numstatements; i++) {
- stmt = data->statements + i;
-
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- case ST_ASM:
- break;
- case ST_EXPRESSION:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_GOTOEXPR:
- CInline_AddFRefList_Expr(stmt->u.expr);
- break;
- case ST_RETURN:
- if (stmt->u.expr)
- CInline_AddFRefList_Expr(stmt->u.expr);
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CInline_AddFRefList_Expr(stmt->u.ifgoto.expr);
- break;
- case ST_SWITCH:
- CInline_AddFRefList_Expr(stmt->u.switchdata->expr);
- break;
- default:
- CError_FATAL(4420);
- }
-
- for (exc = data->statements[i].dobjstack; exc; exc = exc->prev) {
- switch (exc->type) {
- case EAT_DESTROYLOCAL:
- CInline_AddFRefList_Object(exc->data.destroy_local.dtor);
- break;
- case EAT_DESTROYLOCALCOND:
- CInline_AddFRefList_Object(exc->data.destroy_local_cond.dtor);
- break;
- case EAT_DESTROYLOCALOFFSET:
- CInline_AddFRefList_Object(exc->data.destroy_local_offset.dtor);
- break;
- case EAT_DESTROYLOCALPOINTER:
- CInline_AddFRefList_Object(exc->data.destroy_local_pointer.dtor);
- break;
- case EAT_DESTROYLOCALARRAY:
- CInline_AddFRefList_Object(exc->data.destroy_local_array.dtor);
- break;
- case EAT_DESTROYPARTIALARRAY:
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- CInline_AddFRefList_Object(exc->data.destroy_member.dtor);
- break;
- case EAT_DESTROYMEMBERCOND:
- CInline_AddFRefList_Object(exc->data.destroy_member_cond.dtor);
- break;
- case EAT_DESTROYMEMBERARRAY:
- CInline_AddFRefList_Object(exc->data.destroy_member_array.dtor);
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- CInline_AddFRefList_Object(exc->data.delete_pointer.deletefunc);
- break;
- case EAT_DELETEPOINTERCOND:
- CInline_AddFRefList_Object(exc->data.delete_pointer_cond.deletefunc);
- break;
- case EAT_CATCHBLOCK:
- case EAT_ACTIVECATCHBLOCK:
- case EAT_SPECIFICATION:
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(4470);
- }
- }
- }
-}
-
-static void CInline_GenerateTemplateInline(Object *object) {
- CI_Action **ptr;
- CI_Action *action;
-
- ptr = &cinline_tactionlist;
- while ((action = *ptr)) {
- if (object == action->obj) {
- *ptr = action->next;
- action->next = cinline_actionlist;
- cinline_actionlist = action;
-
- TYPE_FUNC(object->type)->flags &= ~FUNC_FLAGS_200000;
- return;
- }
-
- ptr = &action->next;
- }
-
- CError_FATAL(4499);
-}
-
-void CInline_ObjectAddrRef(Object *object) {
- CI_FuncData *funcdata;
-
- object->flags |= OBJECT_FLAGS_2;
-
- switch (object->datatype) {
- case DFUNC:
- case DVFUNC:
- if (
- (object->qual & Q_INLINE) &&
- (funcdata = object->u.func.u.ifuncdata) &&
- !(object->flags & OBJECT_DEFINED) &&
- !(TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL)
- )
- {
- CI_Export *export = galloc(sizeof(CI_Export));
-
- export->object = object;
- export->funcdata = funcdata;
- export->xC = 0;
-
- export->next = cinline_exportlist;
- cinline_exportlist = export;
-
- object->flags |= OBJECT_DEFINED;
- return;
- }
- else if (
- (TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED) &&
- !(TYPE_FUNC(object->type)->flags & FUNC_DEFINED)
- )
- {
- CInline_AddDefaultFunctionAction(object);
- return;
- }
- else if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_200000)
- {
- CInline_GenerateTemplateInline(object);
- return;
- }
- return;
-
- case DALIAS:
- CInline_ObjectAddrRef(object->u.alias.object);
- return;
-
- case DDATA:
- if (object->qual & Q_INLINE_DATA)
- CInit_ExportConst(object);
-
- if (object->flags & OBJECT_LAZY) {
- object->flags &= ~OBJECT_LAZY;
- CParser_CallBackAction(object);
- }
- return;
- }
-}
-
-static Boolean CInline_CheckDependencies(ObjectList *list) {
- Object *object;
- Boolean result;
-
- result = 0;
-
- while (list) {
- object = list->object;
-
- if (
- (TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED) &&
- !(TYPE_FUNC(object->type)->flags & FUNC_DEFINED)
- )
- {
- CInline_AddDefaultFunctionAction(object);
- result = 1;
- }
- else if (
- (object->qual & Q_IS_TEMPLATED) &&
- CTempl_InlineFunctionCheck(object)
- )
- {
- result = 1;
- }
- else {
- CI_Action *action;
- for (action = cinline_actionlist; action; action = action->next) {
- if (object == action->obj) {
- result = 1;
- break;
- }
- }
-
- if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_200000) {
- CInline_GenerateTemplateInline(object);
- result = 1;
- }
- }
-
- list = list->next;
- }
-
- return result;
-}
-
-static Boolean CInline_IsSmallFunction(Object *object, Statement *stmt) {
- SInt32 statementCount;
- ObjectList *list;
- SInt32 localSize;
-
- statementCount = 0;
- while (stmt) {
- if (stmt->type != ST_NOP && stmt->type != ST_LABEL)
- statementCount++;
- if (statementCount > 15)
- return 0;
- stmt = stmt->next;
- }
-
- for (list = locals, localSize = 0; list; list = list->next)
- localSize += list->object->type->size;
-
- if (localSize > 1024)
- return 0;
-
- return 1;
-}
-
-static Boolean CInline_NoFPLocals(void) {
- ObjectList *list;
-
- for (list = locals; list; list = list->next) {
- if (IS_TYPE_FLOAT(list->object->type))
- return 0;
- }
-
- return 1;
-}
-
-void CInline_GenFunc(Statement *stmt, Object *object, UInt8 unk) {
- CI_FuncData *funcdata;
- CI_Export *export;
- Boolean flag24;
- Boolean flag30;
-
- TYPE_FUNC(object->type)->flags |= OBJECT_FLAGS_2;
-
- flag24 = 0;
- flag30 = 0;
- if (!(object->qual & Q_INLINE)) {
- if (
- copts.auto_inline &&
- !copts.dontinline &&
- CInline_CanInline(object, stmt->next) &&
- CInline_IsSmallFunction(object, stmt->next)
- )
- {
- flag24 = 1;
- flag30 = 1;
- TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_800;
- }
- } else {
- flag30 = 1;
- }
-
- if (flag30) {
- COpt_SimpleOptimizer(object, stmt);
-
- funcdata = galloc(sizeof(CI_FuncData));
- CInline_PackIFunctionData(funcdata, stmt, object);
-
- object->u.func.u.ifuncdata = funcdata;
-
- if (!flag24 && !(object->flags & OBJECT_FLAGS_2)) {
- if (cinline_gendeps) {
- cinline_freflist = NULL;
- CInline_AddFRefList_Statement(stmt);
- CInline_CheckDependencies(cinline_freflist);
- }
- return;
- }
- }
-
- object->flags |= OBJECT_DEFINED;
-
- cinline_freflist = NULL;
- CInline_AddFRefList_Statement(stmt);
-
- if (CInline_CheckDependencies(cinline_freflist) || copts.defer_codegen) {
- if (!flag30) {
- funcdata = galloc(sizeof(CI_FuncData));
- CInline_PackIFunctionData(funcdata, stmt, object);
- } else {
- funcdata = object->u.func.u.ifuncdata;
- }
-
- export = galloc(sizeof(CI_Export));
- export->object = object;
- export->funcdata = funcdata;
- export->xC = unk;
-
- export->next = cinline_exportlist;
- cinline_exportlist = export;
-
- return;
- }
-
- expanding_function = object;
- recursive_inline = 0;
- CInline_Expand(stmt);
-
- if (copts.filesyminfo)
- CPrep_SetSourceFile(&cparser_fileoffset);
-
- if (!anyerrors)
- CodeGen_Generator(stmt, object, unk, 0);
-}
-
-static void CInline_GenerateDefaultFunc(Object *object) {
- TypeClass *tclass;
-
- CError_ASSERT(4770, TYPE_FUNC(object->type)->flags & FUNC_AUTO_GENERATED);
- CError_ASSERT(4771, TYPE_FUNC(object->type)->flags & FUNC_METHOD);
-
- tclass = TYPE_METHOD(object->type)->theclass;
-
- if (object == CClass_DefaultConstructor(tclass)) {
- if (object->u.func.defargdata)
- CABI_MakeDefaultArgConstructor(tclass, object);
- else
- CABI_MakeDefaultConstructor(tclass, object);
- } else if (object == CClass_CopyConstructor(tclass)) {
- CABI_MakeDefaultCopyConstructor(tclass, object);
- } else if (object == CClass_AssignmentOperator(tclass)) {
- CABI_MakeDefaultAssignmentOperator(tclass, object);
- } else if (object == CClass_Destructor(tclass)) {
- CABI_MakeDefaultDestructor(tclass, object);
- } else {
- CError_FATAL(4805);
- }
-}
-
-static TemplClassInst *CInline_FindNestedTemplInst(TypeClass *tclass) {
- NameSpace *nspace;
-
- while (tclass) {
- if ((tclass->flags & CLASS_IS_TEMPL_INST))
- return TEMPL_CLASS_INST(tclass);
-
- if (!copts.template_patch)
- break;
-
- nspace = tclass->nspace->parent;
- tclass = NULL;
- while (nspace) {
- if (nspace->theclass) {
- tclass = nspace->theclass;
- break;
- }
- nspace = nspace->parent;
- }
- }
-
- return NULL;
-}
-
-static void CInline_GenerateInlineFunc(CI_Action *action) {
- Object *object;
- TemplClassInst *inst;
- DeclInfo di;
- SInt32 streamState;
-
- object = action->obj;
-
- CPrep_StreamInsert(&action->u.inlinefunc.stream, &streamState);
- cparser_fileoffset = action->u.inlinefunc.fileoffset;
- symdecloffset = cparser_fileoffset.tokenline;
-
- switch ((tk = lex())) {
- case ':':
- case '{':
- case TK_TRY:
- break;
- default:
- CError_FATAL(4860);
- }
-
- symdecltoken = *CPrep_CurStreamElement();
-
- TYPE_FUNC(object->type)->flags &= ~FUNC_DEFINED;
- if (IS_TYPE_METHOD(object->type) && (inst = CInline_FindNestedTemplInst(TYPE_METHOD(object->type)->theclass))) {
- CTempl_ParseInstanceScopeFunction(object, inst, NULL);
- } else {
- memclrw(&di, sizeof(di));
- if (action->u.inlinefunc.tclass) {
- if ((inst = CInline_FindNestedTemplInst(action->u.inlinefunc.tclass))) {
- CTempl_ParseInstanceScopeFunction(object, inst, action->u.inlinefunc.tclass);
- } else {
- CFunc_ParseFuncDef(object, &di, action->u.inlinefunc.tclass, 0, 0, NULL);
- }
- } else {
- CFunc_ParseFuncDef(object, &di, NULL, 0, 0, NULL);
- }
- }
-
- CPrep_StreamRemove(&action->u.inlinefunc.stream, &streamState);
-}
-
-Boolean CInline_CanFreeLHeap(void) {
- CI_Action *action;
-
- if (!anyerrors) {
- for (action = cinline_actionlist; action; action = action->next) {
- if (action->actiontype == CI_ActionInlineFunc)
- return 0;
- }
- }
-
- return 1;
-}
-
-Boolean CInline_GenerateDeferredFuncs(void) {
- CI_Action *action;
- CI_Export *export;
-
- if (!anyerrors) {
- if ((action = cinline_actionlist)) {
- cinline_actionlist = action->next;
- cinline_gendeps = 1;
-
- switch (action->actiontype) {
- case CI_ActionDefaultFunc:
- CInline_GenerateDefaultFunc(action->obj);
- break;
- case CI_ActionInlineFunc:
- if (!(action->obj->flags & OBJECT_DEFINED))
- CInline_GenerateInlineFunc(action);
- break;
- case CI_ActionMemberFunc:
- if (!(TYPE_FUNC(action->obj->type)->flags & FUNC_DEFINED))
- CTempl_InstantiateMember(
- action->u.memberfunc.templ, action->u.memberfunc.inst,
- action->u.memberfunc.tmemb, action->obj, 0);
- break;
- case CI_ActionTemplateFunc:
- if (!(TYPE_FUNC(action->obj->type)->flags & FUNC_DEFINED) && !action->u.templatefunc.inst->is_specialized)
- CTempl_GenFuncInstance(action->u.templatefunc.func, action->u.templatefunc.inst, 0);
- break;
- default:
- CError_FATAL(5001);
- }
-
- cinline_gendeps = 0;
- return 1;
- } else {
- if ((export = cinline_exportlist) && !copts.defer_codegen) {
- cinline_exportlist = export->next;
- CInline_GenIFunctionCode(export->object, export->funcdata, export->xC);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static InitExpr *CInline_InitTemplateData(InitExpr *init) {
- Statement *stmt;
- CLabel *label;
- Object *object;
- Object *data;
-
- object = init->object;
-
- data = CParser_NewCompilerDefDataObject();
- data->type = TYPE(&stsignedchar);
- data->name = CParser_NameConcat("__init__", CMangler_GetLinkName(object)->name);
- data->qual = Q_WEAK;
- CInit_DeclareData(data, NULL, NULL, data->type->size);
-
- stmt = CFunc_AppendStatement(ST_IFGOTO);
- stmt->expr = create_objectnode(data);
- label = newlabel();
- stmt->label = label;
-
- do {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = CInline_CopyExpression(init->expr, CopyMode0);
- init = init->next;
- } while (init && init->object == object);
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(create_objectnode(data), intconstnode(TYPE(&stsignedchar), 1), EASS);
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-
- return init;
-}
-
-void CInline_Finish(void) {
- NameSpace *nspace;
- Boolean saveDebugInfo;
- Statement firstStmt;
- Statement *stmt;
- InitExpr *init;
- Boolean doMore;
-
- if (!init_expressions || anyerrors)
- return;
-
- cinline_freflist = NULL;
-
- for (init = init_expressions; init; init = init->next)
- CInline_AddFRefList_Expr(init->expr);
-
- CInline_CheckDependencies(cinline_freflist);
-
- do {
- doMore = CInline_GenerateDeferredFuncs();
- } while (doMore);
-
- nspace = CFunc_FuncGenSetup(&firstStmt, NULL);
- saveDebugInfo = copts.filesyminfo;
- copts.filesyminfo = 0;
-
- init = init_expressions;
- while (init) {
- if (init->object->nspace->theclass && (init->object->nspace->theclass->flags & CLASS_IS_TEMPL_INST)) {
- init = CInline_InitTemplateData(init);
- } else {
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = CInline_CopyExpression(init->expr, CopyMode0);
- init = init->next;
- }
- }
-
- CFunc_CodeCleanup(&firstStmt);
-
- expanding_function = NULL;
- recursive_inline = 0;
- CInline_Expand(&firstStmt);
-
- if (!anyerrors) {
- if (copts.filesyminfo)
- CPrep_SetSourceFile(&cparser_fileoffset);
- CodeGen_Generator(&firstStmt, NULL, 0, 1);
- }
-
- cscope_current = nspace->parent;
- copts.filesyminfo = saveDebugInfo;
-}
diff --git a/compiler_and_linker/unsorted/CMachine.c b/compiler_and_linker/unsorted/CMachine.c
deleted file mode 100644
index bfa7023..0000000
--- a/compiler_and_linker/unsorted/CMachine.c
+++ /dev/null
@@ -1,1488 +0,0 @@
-#include "compiler/CMachine.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/ScanFloat.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-TypeIntegral stbool = {TYPEINT, 1, IT_BOOL};
-TypeIntegral stchar = {TYPEINT, 1, IT_CHAR};
-TypeIntegral stsignedchar = {TYPEINT, 1, IT_SCHAR};
-TypeIntegral stunsignedchar = {TYPEINT, 1, IT_UCHAR};
-TypeIntegral stwchar = {TYPEINT, 4, IT_WCHAR_T};
-TypeIntegral stsignedshort = {TYPEINT, 2, IT_SHORT};
-TypeIntegral stunsignedshort = {TYPEINT, 2, IT_USHORT};
-TypeIntegral stsignedint = {TYPEINT, 4, IT_INT};
-TypeIntegral stunsignedint = {TYPEINT, 4, IT_UINT};
-TypeIntegral stsignedlong = {TYPEINT, 4, IT_LONG};
-TypeIntegral stunsignedlong = {TYPEINT, 4, IT_ULONG};
-TypeIntegral stsignedlonglong = {TYPEINT, 8, IT_LONGLONG};
-TypeIntegral stunsignedlonglong = {TYPEINT, 8, IT_ULONGLONG};
-TypeIntegral stfloat = {TYPEFLOAT, 4, IT_FLOAT};
-TypeIntegral stshortdouble = {TYPEFLOAT, 8, IT_SHORTDOUBLE};
-TypeIntegral stdouble = {TYPEFLOAT, 8, IT_DOUBLE};
-TypeIntegral stlongdouble = {TYPEFLOAT, 8, IT_LONGDOUBLE};
-
-static StructMember stVUC_unsignedchar15 = {NULL, (Type *) &stunsignedchar, NULL, 15, 0};
-static StructMember stVUC_unsignedchar14 = {&stVUC_unsignedchar15, (Type *) &stunsignedchar, NULL, 14, 0};
-static StructMember stVUC_unsignedchar13 = {&stVUC_unsignedchar14, (Type *) &stunsignedchar, NULL, 13, 0};
-static StructMember stVUC_unsignedchar12 = {&stVUC_unsignedchar13, (Type *) &stunsignedchar, NULL, 12, 0};
-static StructMember stVUC_unsignedchar11 = {&stVUC_unsignedchar12, (Type *) &stunsignedchar, NULL, 11, 0};
-static StructMember stVUC_unsignedchar10 = {&stVUC_unsignedchar11, (Type *) &stunsignedchar, NULL, 10, 0};
-static StructMember stVUC_unsignedchar9 = {&stVUC_unsignedchar10, (Type *) &stunsignedchar, NULL, 9, 0};
-static StructMember stVUC_unsignedchar8 = {&stVUC_unsignedchar9, (Type *) &stunsignedchar, NULL, 8, 0};
-static StructMember stVUC_unsignedchar7 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 7, 0};
-static StructMember stVUC_unsignedchar6 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 6, 0};
-static StructMember stVUC_unsignedchar5 = {&stVUC_unsignedchar6, (Type *) &stunsignedchar, NULL, 5, 0};
-static StructMember stVUC_unsignedchar4 = {&stVUC_unsignedchar5, (Type *) &stunsignedchar, NULL, 4, 0};
-static StructMember stVUC_unsignedchar3 = {&stVUC_unsignedchar4, (Type *) &stunsignedchar, NULL, 3, 0};
-static StructMember stVUC_unsignedchar2 = {&stVUC_unsignedchar3, (Type *) &stunsignedchar, NULL, 2, 0};
-static StructMember stVUC_unsignedchar1 = {&stVUC_unsignedchar2, (Type *) &stunsignedchar, NULL, 1, 0};
-static StructMember stVUC_unsignedchar0 = {&stVUC_unsignedchar1, (Type *) &stunsignedchar, NULL, 0, 0};
-
-static StructMember stVSC_signedchar15 = {NULL, (Type *) &stsignedchar, NULL, 15, 0};
-static StructMember stVSC_signedchar14 = {&stVSC_signedchar15, (Type *) &stsignedchar, NULL, 14, 0};
-static StructMember stVSC_signedchar13 = {&stVSC_signedchar14, (Type *) &stsignedchar, NULL, 13, 0};
-static StructMember stVSC_signedchar12 = {&stVSC_signedchar13, (Type *) &stsignedchar, NULL, 12, 0};
-static StructMember stVSC_signedchar11 = {&stVSC_signedchar12, (Type *) &stsignedchar, NULL, 11, 0};
-static StructMember stVSC_signedchar10 = {&stVSC_signedchar11, (Type *) &stsignedchar, NULL, 10, 0};
-static StructMember stVSC_signedchar9 = {&stVSC_signedchar10, (Type *) &stsignedchar, NULL, 9, 0};
-static StructMember stVSC_signedchar8 = {&stVSC_signedchar9, (Type *) &stsignedchar, NULL, 8, 0};
-static StructMember stVSC_signedchar7 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 7, 0};
-static StructMember stVSC_signedchar6 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 6, 0};
-static StructMember stVSC_signedchar5 = {&stVSC_signedchar6, (Type *) &stsignedchar, NULL, 5, 0};
-static StructMember stVSC_signedchar4 = {&stVSC_signedchar5, (Type *) &stsignedchar, NULL, 4, 0};
-static StructMember stVSC_signedchar3 = {&stVSC_signedchar4, (Type *) &stsignedchar, NULL, 3, 0};
-static StructMember stVSC_signedchar2 = {&stVSC_signedchar3, (Type *) &stsignedchar, NULL, 2, 0};
-static StructMember stVSC_signedchar1 = {&stVSC_signedchar2, (Type *) &stsignedchar, NULL, 1, 0};
-static StructMember stVSC_signedchar0 = {&stVSC_signedchar1, (Type *) &stsignedchar, NULL, 0, 0};
-
-static StructMember stVUS_unsignedshort7 = {NULL, (Type *) &stunsignedshort, NULL, 14, 0};
-static StructMember stVUS_unsignedshort6 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 12, 0};
-static StructMember stVUS_unsignedshort5 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 10, 0};
-static StructMember stVUS_unsignedshort4 = {&stVUS_unsignedshort5, (Type *) &stunsignedshort, NULL, 8, 0};
-static StructMember stVUS_unsignedshort3 = {&stVUS_unsignedshort4, (Type *) &stunsignedshort, NULL, 6, 0};
-static StructMember stVUS_unsignedshort2 = {&stVUS_unsignedshort3, (Type *) &stunsignedshort, NULL, 4, 0};
-static StructMember stVUS_unsignedshort1 = {&stVUS_unsignedshort2, (Type *) &stunsignedshort, NULL, 2, 0};
-static StructMember stVUS_unsignedshort0 = {&stVUS_unsignedshort1, (Type *) &stunsignedshort, NULL, 0, 0};
-
-static StructMember stVSS_signedshort7 = {NULL, (Type *) &stsignedshort, NULL, 14, 0};
-static StructMember stVSS_signedshort6 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 12, 0};
-static StructMember stVSS_signedshort5 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 10, 0};
-static StructMember stVSS_signedshort4 = {&stVSS_signedshort5, (Type *) &stsignedshort, NULL, 8, 0};
-static StructMember stVSS_signedshort3 = {&stVSS_signedshort4, (Type *) &stsignedshort, NULL, 6, 0};
-static StructMember stVSS_signedshort2 = {&stVSS_signedshort3, (Type *) &stsignedshort, NULL, 4, 0};
-static StructMember stVSS_signedshort1 = {&stVSS_signedshort2, (Type *) &stsignedshort, NULL, 2, 0};
-static StructMember stVSS_signedshort0 = {&stVSS_signedshort1, (Type *) &stsignedshort, NULL, 0, 0};
-
-static StructMember stVUL_unsignedlong3 = {NULL, (Type *) &stunsignedlong, NULL, 12, 0};
-static StructMember stVUL_unsignedlong2 = {&stVUL_unsignedlong3, (Type *) &stunsignedlong, NULL, 8, 0};
-static StructMember stVUL_unsignedlong1 = {&stVUL_unsignedlong2, (Type *) &stunsignedlong, NULL, 4, 0};
-static StructMember stVUL_unsignedlong0 = {&stVUL_unsignedlong1, (Type *) &stunsignedlong, NULL, 0, 0};
-
-static StructMember stVSL_signedlong3 = {NULL, (Type *) &stsignedlong, NULL, 12, 0};
-static StructMember stVSL_signedlong2 = {&stVSL_signedlong3, (Type *) &stsignedlong, NULL, 8, 0};
-static StructMember stVSL_signedlong1 = {&stVSL_signedlong2, (Type *) &stsignedlong, NULL, 4, 0};
-static StructMember stVSL_signedlong0 = {&stVSL_signedlong1, (Type *) &stsignedlong, NULL, 0, 0};
-
-static StructMember stVF_float3 = {NULL, (Type *) &stfloat, NULL, 12, 0};
-static StructMember stVF_float2 = {&stVF_float3, (Type *) &stfloat, NULL, 8, 0};
-static StructMember stVF_float1 = {&stVF_float2, (Type *) &stfloat, NULL, 4, 0};
-static StructMember stVF_float0 = {&stVF_float1, (Type *) &stfloat, NULL, 0, 0};
-
-TypeStruct stvectorunsignedchar = {TYPESTRUCT, 16, NULL, &stVUC_unsignedchar0, STRUCT_VECTOR_UCHAR, 16};
-TypeStruct stvectorsignedchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_VECTOR_SCHAR, 16};
-TypeStruct stvectorboolchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_VECTOR_BCHAR, 16};
-
-TypeStruct stvectorunsignedshort = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_VECTOR_USHORT, 16};
-TypeStruct stvectorsignedshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_VECTOR_SSHORT, 16};
-TypeStruct stvectorboolshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_VECTOR_BSHORT, 16};
-
-TypeStruct stvectorunsignedlong = {TYPESTRUCT, 16, NULL, &stVUL_unsignedlong0, STRUCT_VECTOR_UINT, 16};
-TypeStruct stvectorsignedlong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_VECTOR_SINT, 16};
-TypeStruct stvectorboollong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_VECTOR_BINT, 16};
-
-TypeStruct stvectorfloat = {TYPESTRUCT, 16, NULL, &stVF_float0, STRUCT_VECTOR_FLOAT, 16};
-
-TypeStruct stvectorpixel = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_VECTOR_PIXEL, 16};
-
-TypeStruct stvector = {TYPESTRUCT, 16, NULL, NULL, STRUCT_VECTOR_UINT, 16};
-
-static SInt32 cmach_structoffset;
-static UInt8 cmach_structalign;
-static short cmach_curbfsize;
-static short cmach_curbfbasesize;
-static int cmach_curbfoffset;
-
-static short cmach_packsize[] = {
- 1, 2, 4, 8, 16
-};
-
-// forward declarations
-static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag);
-static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 align, Boolean flag);
-
-void CMach_Configure(void) {
-}
-
-SInt32 CMach_GetQUALalign(UInt32 qual) {
- SInt32 result = 0;
- UInt32 chk;
-
- if ((chk = (qual & Q_ALIGNED_MASK))) {
- if (chk == Q_ALIGNED_1)
- result = 1;
- else if (chk == Q_ALIGNED_2)
- result = 2;
- else if (chk == Q_ALIGNED_4)
- result = 4;
- else if (chk == Q_ALIGNED_8)
- result = 8;
- else if (chk == Q_ALIGNED_16)
- result = 16;
- else if (chk == Q_ALIGNED_32)
- result = 32;
- else if (chk == Q_ALIGNED_64)
- result = 64;
- else if (chk == Q_ALIGNED_128)
- result = 128;
- else if (chk == Q_ALIGNED_256)
- result = 256;
- else if (chk == Q_ALIGNED_512)
- result = 512;
- else if (chk == Q_ALIGNED_1024)
- result = 1024;
- else if (chk == Q_ALIGNED_2048)
- result = 2048;
- else if (chk == Q_ALIGNED_4096)
- result = 4096;
- else if (chk == Q_ALIGNED_8192)
- result = 8192;
- else
- CError_FATAL(226);
- }
-
- return result;
-}
-
-SInt32 CMach_ArgumentAlignment(Type *type) {
- char save_align_mode;
- UInt8 save_oldalignment;
- SInt32 align;
-
- save_align_mode = copts.structalignment;
- save_oldalignment = copts.oldalignment;
- copts.structalignment = AlignMode2_PPC;
- copts.oldalignment = 0;
- align = CMach_GetQualifiedTypeAlign(type, 0);
- copts.structalignment = save_align_mode;
- copts.oldalignment = save_oldalignment;
-
- if (type->type == TYPESTRUCT && !TYPE_STRUCT(type)->members) {
- if (TYPE_STRUCT(type)->align > align)
- return TYPE_STRUCT(type)->align;
- else
- return align;
- } else {
- return align;
- }
-}
-
-// TODO: investigate if this returns SInt16 actually
-SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual) {
- SInt32 align;
- SInt32 qualalign;
- SInt32 argalign;
- SInt32 anotheralign;
-
- qualalign = CMach_GetQUALalign(qual);
- align = CMach_GetQualifiedTypeAlign(type, 1);
- if (qualalign > align)
- align = qualalign;
- argalign = CMach_ArgumentAlignment(type);
- if (argalign > align)
- align = argalign;
-
- switch (type->type) {
- case TYPEVOID:
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- anotheralign = 4;
- break;
- default:
- anotheralign = 1;
- }
- if (anotheralign > align)
- align = anotheralign;
-
- if (copts.optimizationlevel > 0) {
- if (type->type == TYPEARRAY || (type->type == TYPESTRUCT && (TYPE_STRUCT(type)->stype < STRUCT_VECTOR_UCHAR || TYPE_STRUCT(type)->stype > STRUCT_VECTOR_PIXEL)) || type->type == TYPECLASS || (type->type == TYPEMEMBERPOINTER && (UInt32) type->size == 12)) {
- return (copts.min_struct_alignment > align) ? copts.min_struct_alignment : align;
- }
- }
-
- return align;
-}
-
-CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right) {
- if (is_unsigned(type)) {
- switch (type->size) {
- case 1:
- CInt64_ConvertUInt8(&left);
- CInt64_ConvertUInt8(&right);
- break;
- case 2:
- CInt64_ConvertUInt16(&left);
- CInt64_ConvertUInt16(&right);
- break;
- case 4:
- CInt64_ConvertUInt32(&left);
- CInt64_ConvertUInt32(&right);
- break;
- case 8:
- break;
- default:
- CError_FATAL(327);
- }
-
- switch (op) {
- case '*':
- left = CInt64_MulU(left, right);
- break;
- case '/':
- if (CInt64_IsZero(&right))
- CError_Warning(CErrorStr139);
- else
- left = CInt64_DivU(left, right);
- break;
- case '%':
- if (CInt64_IsZero(&right))
- CError_Warning(CErrorStr139);
- else
- left = CInt64_ModU(left, right);
- break;
- case '+':
- left = CInt64_Add(left, right);
- break;
- case '-':
- left = CInt64_Sub(left, right);
- break;
- case TK_SHL:
- left = CInt64_Shl(left, right);
- break;
- case TK_SHR:
- left = CInt64_ShrU(left, right);
- break;
- case '<':
- CInt64_SetLong(&left, CInt64_LessU(left, right));
- break;
- case '>':
- CInt64_SetLong(&left, CInt64_GreaterU(left, right));
- break;
- case TK_LESS_EQUAL:
- CInt64_SetLong(&left, CInt64_LessEqualU(left, right));
- break;
- case TK_GREATER_EQUAL:
- CInt64_SetLong(&left, CInt64_GreaterEqualU(left, right));
- break;
- case TK_LOGICAL_EQ:
- CInt64_SetLong(&left, CInt64_Equal(left, right));
- break;
- case TK_LOGICAL_NE:
- CInt64_SetLong(&left, CInt64_NotEqual(left, right));
- break;
- case '&':
- left = CInt64_And(left, right);
- break;
- case '^':
- left = CInt64_Xor(left, right);
- break;
- case '|':
- left = CInt64_Or(left, right);
- break;
- case TK_LOGICAL_AND:
- CInt64_SetLong(&left, (!CInt64_IsZero(&left) && !CInt64_IsZero(&right)));
- break;
- case TK_LOGICAL_OR:
- CInt64_SetLong(&left, (!CInt64_IsZero(&left) || !CInt64_IsZero(&right)));
- break;
- default:
- CError_Error(CErrorStr120);
- }
-
- switch (type->size) {
- case 1:
- CInt64_ConvertUInt8(&left);
- break;
- case 2:
- CInt64_ConvertUInt16(&left);
- break;
- case 4:
- CInt64_ConvertUInt32(&left);
- break;
- case 8:
- break;
- }
- } else {
- switch (type->size) {
- case 1:
- CInt64_ConvertInt8(&left);
- CInt64_ConvertInt8(&right);
- break;
- case 2:
- CInt64_ConvertInt16(&left);
- CInt64_ConvertInt16(&right);
- break;
- case 4:
- CInt64_ConvertInt32(&left);
- CInt64_ConvertInt32(&right);
- break;
- case 8:
- break;
- default:
- CError_FATAL(389);
- }
-
- switch (op) {
- case '*':
- left = CInt64_Mul(left, right);
- break;
- case '/':
- if (CInt64_IsZero(&right))
- CError_Warning(CErrorStr139);
- else
- left = CInt64_Div(left, right);
- break;
- case '%':
- if (CInt64_IsZero(&right))
- CError_Warning(CErrorStr139);
- else
- left = CInt64_Mod(left, right);
- break;
- case '+':
- left = CInt64_Add(left, right);
- break;
- case '-':
- left = CInt64_Sub(left, right);
- break;
- case TK_SHL:
- left = CInt64_Shl(left, right);
- break;
- case TK_SHR:
- left = CInt64_Shr(left, right);
- break;
- case '<':
- CInt64_SetLong(&left, CInt64_Less(left, right));
- break;
- case '>':
- CInt64_SetLong(&left, CInt64_Greater(left, right));
- break;
- case TK_LESS_EQUAL:
- CInt64_SetLong(&left, CInt64_LessEqual(left, right));
- break;
- case TK_GREATER_EQUAL:
- CInt64_SetLong(&left, CInt64_GreaterEqual(left, right));
- break;
- case TK_LOGICAL_EQ:
- CInt64_SetLong(&left, CInt64_Equal(left, right));
- break;
- case TK_LOGICAL_NE:
- CInt64_SetLong(&left, CInt64_NotEqual(left, right));
- break;
- case '&':
- left = CInt64_And(left, right);
- break;
- case '^':
- left = CInt64_Xor(left, right);
- break;
- case '|':
- left = CInt64_Or(left, right);
- break;
- case TK_LOGICAL_AND:
- CInt64_SetLong(&left, (!CInt64_IsZero(&left) && !CInt64_IsZero(&right)));
- break;
- case TK_LOGICAL_OR:
- CInt64_SetLong(&left, (!CInt64_IsZero(&left) || !CInt64_IsZero(&right)));
- break;
- default:
- CError_Error(CErrorStr120);
- }
-
- switch (type->size) {
- case 1:
- CInt64_ConvertInt8(&left);
- break;
- case 2:
- CInt64_ConvertInt16(&left);
- break;
- case 4:
- CInt64_ConvertInt32(&left);
- break;
- case 8:
- break;
- }
- }
-
- return left;
-}
-
-CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val) {
- if (is_unsigned(type)) {
- switch (type->size) {
- case 1:
- CInt64_ConvertUInt8(&val);
- break;
- case 2:
- CInt64_ConvertUInt16(&val);
- break;
- case 4:
- CInt64_ConvertUInt32(&val);
- break;
- case 8:
- break;
- default:
- CError_FATAL(448);
- }
-
- switch (op) {
- case '-':
- val = CInt64_Neg(val);
- break;
- case '~':
- val = CInt64_Inv(val);
- break;
- case '!':
- val = CInt64_Not(val);
- break;
- default:
- CError_Error(CErrorStr120);
- }
-
- switch (type->size) {
- case 1:
- CInt64_ConvertUInt8(&val);
- break;
- case 2:
- CInt64_ConvertUInt16(&val);
- break;
- case 4:
- CInt64_ConvertUInt32(&val);
- break;
- case 8:
- break;
- }
- } else {
- switch (type->size) {
- case 1:
- CInt64_ConvertInt8(&val);
- break;
- case 2:
- CInt64_ConvertInt16(&val);
- break;
- case 4:
- CInt64_ConvertInt32(&val);
- break;
- case 8:
- break;
- default:
- CError_FATAL(478);
- }
-
- switch (op) {
- case '-':
- val = CInt64_Neg(val);
- break;
- case '~':
- val = CInt64_Inv(val);
- break;
- case '!':
- val = CInt64_Not(val);
- break;
- default:
- CError_Error(CErrorStr120);
- }
-
- switch (type->size) {
- case 1:
- CInt64_ConvertInt8(&val);
- break;
- case 2:
- CInt64_ConvertInt16(&val);
- break;
- case 4:
- CInt64_ConvertInt32(&val);
- break;
- case 8:
- break;
- }
- }
-
- return val;
-}
-
-CInt64 CMach_CalcIntConvertFromFloat(Type *type, Float fval) {
- CInt64 result;
-
- if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) {
- if (is_unsigned(type))
- CInt64_ConvertUFromLongDouble(&result, fval.value);
- else
- CInt64_ConvertFromLongDouble(&result, fval.value);
- } else {
- if (is_unsigned(type))
- CInt64_SetULong(&result, fval.value);
- else
- CInt64_SetLong(&result, fval.value);
- }
-
- return result;
-}
-
-void CMach_InitIntMem(Type *type, CInt64 val, void *mem) {
- SInt32 lg;
- SInt16 sh;
- SInt8 ch;
-
- switch (type->type) {
- case TYPEINT:
- switch (type->size) {
- case 1:
- ch = CInt64_GetULong(&val);
- memcpy(mem, &ch, 1);
- break;
- case 2:
- sh = CTool_EndianConvertWord16(CInt64_GetULong(&val));
- memcpy(mem, &sh, 2);
- break;
- case 4:
- lg = CTool_EndianConvertWord32(CInt64_GetULong(&val));
- memcpy(mem, &lg, 4);
- break;
- case 8:
- CTool_EndianConvertWord64(val, mem);
- break;
- default:
- CError_FATAL(566);
- }
- break;
- default:
- CError_FATAL(570);
- }
-}
-
-void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem, Boolean flag) {
- unsigned char uc[16];
- unsigned short us[8];
- unsigned int ul[4];
- float f[4];
- int i;
-
- switch (type->type) {
- case TYPESTRUCT:
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- for (i = 0; i < 16; i++)
- uc[i] = val.uc[i];
- memcpy(mem, uc, 16);
- break;
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- for (i = 0; i < 8; i++)
- us[i] = val.us[i];
- memcpy(mem, us, 16);
- break;
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- for (i = 0; i < 4; i++)
- ul[i] = val.ul[i];
- memcpy(mem, ul, 16);
- break;
- case STRUCT_VECTOR_FLOAT:
- for (i = 0; i < 4; i++)
- f[i] = val.f[i];
- memcpy(mem, f, 16);
- break;
- default:
- CError_FATAL(655);
- }
- break;
- default:
- CError_FATAL(659);
- }
-}
-
-Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right) {
- switch (op) {
- case '+':
- left.value += right.value;
- break;
- case '-':
- left.value -= right.value;
- break;
- case '*':
- left.value *= right.value;
- break;
- case '/':
- left.value /= right.value;
- break;
- default:
- CError_FATAL(679);
- }
-
- return CMach_CalcFloatConvert(type, left);
-}
-
-Float CMach_CalcFloatMonadic(Type *type, short op, Float fval) {
- if (op != '-')
- CError_FATAL(692);
-
- fval.value = -fval.value;
- return CMach_CalcFloatConvert(type, fval);
-}
-
-Boolean CMach_CalcFloatDiadicBool(Type *type, Float left, short op, Float right) {
- switch (op) {
- case TK_LOGICAL_EQ:
- return left.value == right.value;
- case TK_LOGICAL_NE:
- return left.value != right.value;
- case TK_LESS_EQUAL:
- return left.value <= right.value;
- case TK_GREATER_EQUAL:
- return left.value >= right.value;
- case '>':
- return left.value > right.value;
- case '<':
- return left.value < right.value;
- default:
- CError_FATAL(714);
- return 0;
- }
-}
-
-Boolean CMach_CalcVectorDiadicBool(Type *type, MWVector128 *left, short op, MWVector128 *right) {
- switch (op) {
- case TK_LOGICAL_EQ:
- return (left->ul[0] == right->ul[0]) && (left->ul[1] == right->ul[1]) && (left->ul[2] == right->ul[2]) && (left->ul[3] == right->ul[3]);
- case TK_LOGICAL_NE:
- return (left->ul[0] != right->ul[0]) && (left->ul[1] != right->ul[1]) && (left->ul[2] != right->ul[2]) && (left->ul[3] != right->ul[3]);
- default:
- CError_FATAL(740);
- return 0;
- }
-}
-
-char *CMach_FloatScan(char *input, Float *result, Boolean *fail) {
- double resultval;
- char *outpos;
-
- if (!(outpos = ScanFloat(input, &resultval, fail)))
- CError_ErrorTerm(CErrorStr154);
-
- if (*fail)
- result->value = 0.0;
- else
- result->value = resultval;
-
- return outpos;
-}
-
-Float CMach_CalcFloatConvertFromInt(Type *type, CInt64 val) {
- Float result;
-
- if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) {
- if (is_unsigned(type))
- result.value = CInt64_ConvertUToLongDouble(&val);
- else
- result.value = CInt64_ConvertToLongDouble(&val);
- } else {
- if (is_unsigned(type))
- result.value = val.lo;
- else
- result.value = (SInt32) val.lo;
- }
-
- return result;
-}
-
-Float CMach_CalcFloatConvert(Type *type, Float fval) {
- switch (type->size) {
- case 4:
- fval.value = (float) fval.value;
- break;
- case 8:
- fval.value = (double) fval.value;
- break;
- case 10:
- case 12:
- break;
- default:
- CError_FATAL(801);
- }
- return fval;
-}
-
-Boolean CMach_FloatIsZero(Float fval) {
- return fval.value == 0.0;
-}
-
-Boolean CMach_FloatIsOne(Float fval) {
- return fval.value == 1.0;
-}
-
-Boolean CMach_FloatIsNegOne(Float fval) {
- return fval.value == -1.0;
-}
-
-void CMach_InitFloatMem(Type *type, Float val, void *mem) {
- float f;
- double d;
-
- if (type->type == TYPEFLOAT) {
- switch (type->size) {
- case 4:
- f = val.value;
- memcpy(mem, &f, 4);
- CTool_EndianConvertMem(mem, 4);
- return;
- case 8:
- d = val.value;
- memcpy(mem, &d, 8);
- CTool_EndianConvertMem(mem, 8);
- return;
- }
- }
-
- CError_FATAL(866);
-}
-
-void CMach_PrintFloat(char *buf, Float val) {
- double f;
- CMach_InitFloatMem((Type *) &stshortdouble, val, &f);
- sprintf(buf, "%g", f);
-}
-
-void CMach_PragmaParams(void) {
- if (copts.warn_illpragma)
- CError_Warning(CErrorStr186, 0);
-
- while (notendofline())
- lex();
-}
-
-void CMach_AdjustFuntionArgs() {
- // not called so we will never know what the args should have been :(
-}
-
-static SInt32 CMach_GetPPCTypeAlign(Type *type, Boolean flag1, Boolean flag2) {
- ClassList *base;
- ObjMemberVar *ivar;
- StructMember *member;
- SInt32 best;
- SInt32 ivarAlign;
- SInt32 qualAlign;
-
- SInt32 align = CMach_GetQualifiedTypeAlign(type, flag2);
- if (align <= 8) {
- while (type->type == TYPEARRAY)
- type = TYPE_POINTER(type)->target;
-
- if (flag1) {
- if (type->type == TYPEFLOAT && type->size > 4 && align < 8)
- return 8;
- } else if (align == 8) {
- if (type->type == TYPECLASS) {
- best = 4;
- for (base = TYPE_CLASS(type)->bases; base; base = base->next) {
- if (base->base->align > best)
- best = base->base->align;
- }
- for (ivar = TYPE_CLASS(type)->ivars; ivar; ivar = ivar->next) {
- ivarAlign = CMach_GetPPCTypeAlign(ivar->type, 0, flag2);
- if (ivarAlign > best)
- best = ivarAlign;
- if (flag2) {
- qualAlign = CMach_GetQUALalign(ivar->qual);
- if (qualAlign > best)
- best = qualAlign;
- }
- }
- return best;
- }
- if (type->type == TYPESTRUCT) {
- best = 4;
- for (member = TYPE_STRUCT(type)->members; member; member = member->next) {
- ivarAlign = CMach_GetPPCTypeAlign(member->type, 0, flag2);
- if (ivarAlign > best)
- best = ivarAlign;
- if (flag2) {
- qualAlign = CMach_GetQUALalign(member->qual);
- if (qualAlign > best)
- best = qualAlign;
- }
- }
- return best;
- }
- }
- }
-
- return align;
-}
-
-static SInt16 CMach_GetQualifiedStructAlign(const TypeStruct *tstruct, Boolean flag) {
- StructMember *member;
- SInt32 best;
- SInt32 align;
- Boolean isFirst;
-
- if (tstruct->stype >= STRUCT_VECTOR_UCHAR && tstruct->stype <= STRUCT_VECTOR_PIXEL)
- return 16;
-
- switch (copts.structalignment) {
- case AlignMode3_1Byte:
- case AlignMode8_Packed:
- return 1;
- case AlignMode0_Mac68k:
- return 2;
- case AlignMode1_Mac68k4byte:
- return (tstruct->size <= 2) ? 2 : 4;
- }
-
- if (tstruct->size <= 1)
- return 1;
-
- best = 1;
- switch (copts.structalignment) {
- default:
- CError_FATAL(1026);
- case AlignMode4_2Byte:
- case AlignMode5_4Byte:
- case AlignMode6_8Byte:
- case AlignMode7_16Byte:
- for (member = tstruct->members; member; member = member->next) {
- align = CMach_GetQualifiedTypeAlign(member->type, flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(member->qual);
- if (align > best)
- best = align;
- }
- }
- return best;
- case AlignMode2_PPC:
- if (copts.oldalignment) {
- for (member = tstruct->members; member; member = member->next) {
- align = CMach_GetQualifiedTypeAlign(member->type, flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(member->qual);
- if (align > best)
- best = align;
- }
- }
- } else if (TYPE_STRUCT(tstruct)->stype == STRUCT_TYPE_UNION) {
- for (member = tstruct->members; member; member = member->next) {
- align = CMach_GetPPCTypeAlign(member->type, 1, flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(member->qual);
- if (align > best)
- best = align;
- }
- }
- } else {
- isFirst = 1;
- for (member = tstruct->members; member; member = member->next) {
- align = CMach_GetPPCTypeAlign(member->type, isFirst || (best >= 8), flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(member->qual);
- if (align > best)
- best = align;
- }
- isFirst = 0;
- }
- }
- return best;
- }
-}
-
-SInt16 CMach_GetStructAlign(TypeStruct *tstruct) {
- return CMach_GetQualifiedStructAlign(tstruct, 1);
-}
-
-static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) {
- ClassList *base;
- ObjMemberVar *ivar;
- SInt32 best;
- SInt32 align;
- Boolean isFirst;
-
- switch (copts.structalignment) {
- case AlignMode3_1Byte:
- case AlignMode8_Packed:
- return 1;
- case AlignMode0_Mac68k:
- return 2;
- case AlignMode1_Mac68k4byte:
- return (tclass->size <= 2) ? 2 : 4;
- }
- if (tclass->size <= 1)
- return 1;
- best = 1;
- switch (copts.structalignment) {
- default:
- CError_FATAL(1149);
- case AlignMode4_2Byte:
- case AlignMode5_4Byte:
- case AlignMode6_8Byte:
- case AlignMode7_16Byte:
- for (base = tclass->bases; base; base = base->next) {
- if ((align = base->base->align) > best)
- best = align;
- }
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag);
- if (align > best)
- best = align;
- }
- return best;
- case AlignMode2_PPC:
- best = 1;
- if (copts.oldalignment) {
- for (base = tclass->bases; base; base = base->next) {
- if ((align = base->base->align) > best)
- best = align;
- }
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag);
- if (align > best)
- best = align;
- }
- } else {
- isFirst = 1;
- for (base = tclass->bases; base; base = base->next) {
- if ((align = base->base->align) > best)
- best = align;
- isFirst = 0;
- }
- if (tclass->mode == 1) {
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- align = CMach_GetPPCTypeAlign(ivar->type, 1, flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(ivar->qual);
- if (align > best)
- best = align;
- }
- }
- } else {
- for (ivar = tclass->ivars; ivar; ivar = ivar->next) {
- if (ivar->offset && align != 8)
- isFirst = 0;
- align = CMach_GetPPCTypeAlign(ivar->type, isFirst || (best >= 8), flag);
- if (align > best)
- best = align;
- if (flag) {
- align = CMach_GetQUALalign(ivar->qual);
- if (align > best)
- best = align;
- }
- }
- }
- }
- return best;
- }
-}
-
-SInt16 CMach_GetClassAlign(TypeClass *tclass) {
- return CMach_GetQualifiedClassAlign(tclass, 1);
-}
-
-static SInt16 CMach_GetWinTypeAlign(Type *type) {
- int packoffs = copts.structalignment - 3;
- SInt32 align = cmach_packsize[packoffs];
- if (type->size < align)
- align = type->size;
- return align;
-}
-
-static SInt16 CMach_GetWinMinimizeAlign(SInt16 align) {
- int packoffs = copts.structalignment - 3;
- SInt16 minimum = cmach_packsize[packoffs];
- if (minimum < align)
- align = minimum;
- return align;
-}
-
-static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag) {
- Boolean isWin;
- SInt16 align;
-
- if (type->type == TYPESTRUCT && TYPE_STRUCT(type)->stype >= STRUCT_VECTOR_UCHAR && TYPE_STRUCT(type)->stype <= STRUCT_VECTOR_PIXEL)
- return 16;
-
- switch (copts.structalignment) {
- case AlignMode3_1Byte:
- case AlignMode8_Packed:
- return 1;
- case AlignMode4_2Byte:
- case AlignMode5_4Byte:
- case AlignMode6_8Byte:
- case AlignMode7_16Byte:
- isWin = 1;
- break;
- default:
- isWin = 0;
- break;
- }
-
-restart:
- switch (type->type) {
- case TYPEVOID:
- return 0;
- case TYPEFUNC:
- return 0;
- case TYPEENUM:
- type = TYPE_ENUM(type)->enumtype;
- case TYPEINT:
- if (isWin)
- return CMach_GetWinTypeAlign(type);
- if (type->size == 1)
- return 1;
- if (copts.oldalignment && type->size == 8)
- return 8;
- if (copts.structalignment != AlignMode0_Mac68k && type->size >= 4)
- return 4;
- return 2;
- case TYPEFLOAT:
- if (isWin)
- return CMach_GetWinTypeAlign(type);
- switch (copts.structalignment) {
- case AlignMode0_Mac68k:
- return 2;
- case AlignMode1_Mac68k4byte:
- return 4;
- case AlignMode2_PPC:
- if (copts.oldalignment && type->size > 4)
- return 8;
- return 4;
- default:
- CError_FATAL(1346);
- }
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- if (isWin)
- return CMach_GetWinTypeAlign(type);
- if (copts.structalignment == AlignMode0_Mac68k)
- return 2;
- else
- return 4;
- case TYPEARRAY:
- if (copts.alignarraymembers) {
- if (isWin)
- return CMach_GetWinTypeAlign(type);
- if (type->size == 1)
- return 1;
- if (copts.structalignment == AlignMode0_Mac68k || type->size <= 2)
- return 2;
- if (copts.structalignment == AlignMode1_Mac68k4byte || type->size < 8)
- return 4;
- align = CMach_GetQualifiedTypeAlign(TYPE_POINTER(type)->target, flag);
- if (align > 4)
- return align;
- else
- return 4;
- } else {
- type = TYPE_POINTER(type)->target;
- goto restart;
- }
- case TYPESTRUCT:
- if (flag)
- align = TYPE_STRUCT(type)->align;
- else
- align = CMach_GetQualifiedStructAlign(TYPE_STRUCT(type), flag);
- if (isWin)
- return CMach_GetWinMinimizeAlign(align);
- else
- return align;
- case TYPECLASS:
- if (flag)
- align = TYPE_CLASS(type)->align;
- else
- align = CMach_GetQualifiedClassAlign(TYPE_CLASS(type), flag);
- if (isWin)
- return CMach_GetWinMinimizeAlign(align);
- else
- return align;
- case TYPEBITFIELD:
- type = TYPE_BITFIELD(type)->bitfieldtype;
- goto restart;
- case TYPETEMPLATE:
- return 1;
- default:
- CError_FATAL(1392);
- return 0;
- }
-}
-
-SInt16 CMach_GetTypeAlign(Type *type) {
- return CMach_GetQualifiedTypeAlign(type, 1);
-}
-
-static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 var, Boolean flag) {
- SInt32 align;
-
- align = CMach_GetQualifiedTypeAlign(type, flag);
- if (align < 1)
- align = 1;
-
- if (IS_TYPE_VECTOR(type) && align < 16)
- align = 16;
-
- switch (copts.structalignment) {
- case AlignMode8_Packed:
- align = 1;
- break;
- case AlignMode0_Mac68k:
- if (align > 2)
- align = 2;
- break;
- case AlignMode1_Mac68k4byte:
- if (align > 4)
- align = 4;
- break;
- case AlignMode2_PPC:
- if (!copts.oldalignment)
- align = CMach_GetPPCTypeAlign(type, !cmach_structoffset || (cmach_structalign >= 8), flag);
- if (var > align)
- align = var;
- break;
- }
-
- if (align > cmach_structalign)
- cmach_structalign = align;
- return align;
-}
-
-SInt16 CMach_MemberAlignValue(Type *type, SInt32 var) {
- SInt16 align = CMach_GetMemberAlignment(type, 0, 1);
- if (align <= 1)
- return 0;
-
- return (align - 1) & (align - (var & (align - 1)));
-}
-
-static SInt16 MemberAlignValue(Type *type, SInt32 var1, SInt32 var2) {
- SInt16 align = CMach_GetMemberAlignment(type, var2, 1);
- return (align - 1) & (align - (var1 & (align - 1)));
-}
-
-void CMach_StructLayoutInitOffset(SInt32 offset) {
- cmach_structoffset = offset;
- cmach_structalign = 4;
- cmach_curbfsize = 0;
-}
-
-SInt32 CMach_StructLayoutGetCurSize(void) {
- return cmach_structoffset;
-}
-
-SInt32 CMach_StructLayoutGetOffset(Type *type, UInt32 qual) {
- SInt32 align;
- SInt32 offset;
-
- qual = CParser_GetTypeQualifiers(type, qual);
-
- cmach_curbfsize = 0;
- align = MemberAlignValue(type, cmach_structoffset, CMach_GetQUALalign(qual));
- offset = cmach_structoffset + align;
- cmach_structoffset = offset + type->size;
- return offset;
-}
-
-SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) {
- SInt16 align;
- SInt16 padding_at_start;
- SInt16 basesize;
- SInt16 basesize_bits;
- SInt16 required_alignment;
- SInt16 r4;
-
- padding_at_start = 0;
- required_alignment = 0;
- align = CMach_GetQUALalign(qual);
- if (align <= tbitfield->bitfieldtype->size)
- align = 0;
-
- switch (tbitfield->bitfieldtype->size) {
- case 1:
- basesize = 1;
- basesize_bits = 8;
- required_alignment = 0;
- break;
- case 2:
- basesize = 2;
- basesize_bits = 16;
- required_alignment = 2;
- break;
- case 4:
- if (copts.structalignment != AlignMode0_Mac68k && copts.structalignment != AlignMode4_2Byte)
- required_alignment = 4;
- else
- required_alignment = 2;
- basesize = 4;
- basesize_bits = 32;
- break;
- default:
- CError_FATAL(1620);
- }
-
- switch (copts.structalignment) {
- case AlignMode3_1Byte:
- case AlignMode8_Packed:
- required_alignment = 0;
- break;
- }
-
- r4 = required_alignment;
- if (align > required_alignment)
- r4 = align;
- if (r4 && (cmach_structoffset & (r4 - 1)))
- padding_at_start = r4 - (cmach_structoffset & (r4 - 1));
-
- if (!cmach_curbfsize) {
- cmach_structoffset += padding_at_start;
- if (!tbitfield->bitlength)
- return cmach_structoffset;
- cmach_curbfsize = tbitfield->bitlength;
- cmach_curbfbasesize = basesize;
- cmach_curbfoffset = cmach_structoffset;
- cmach_structoffset += basesize;
- tbitfield->offset = 0;
- return cmach_curbfoffset;
- } else {
- if (!tbitfield->bitlength || (cmach_curbfsize + tbitfield->bitlength) > basesize_bits || cmach_curbfbasesize != basesize) {
- cmach_structoffset += padding_at_start;
- cmach_curbfsize = 0;
- cmach_curbfbasesize = basesize;
- if (!tbitfield->bitlength)
- return cmach_structoffset;
- cmach_curbfoffset = cmach_structoffset;
- cmach_structoffset += basesize;
- }
- tbitfield->offset = cmach_curbfsize;
- cmach_curbfsize += tbitfield->bitlength;
- return cmach_curbfoffset;
- }
-}
-
-static Boolean CMach_IsTrivialClass(TypeClass *tclass) {
- return !CClass_Constructor(tclass);
-}
-
-UInt8 CMach_GetFunctionResultClass(TypeFunc *tfunc) {
- switch (tfunc->functype->type) {
- case TYPESTRUCT:
- if (tfunc->functype->type == TYPESTRUCT && TYPE_STRUCT(tfunc->functype)->stype >= STRUCT_VECTOR_UCHAR && TYPE_STRUCT(tfunc->functype)->stype <= STRUCT_VECTOR_PIXEL)
- return 0;
- case TYPECLASS:
- case TYPEMEMBERPOINTER:
- return CMach_PassResultInHiddenArg(tfunc->functype) != 0;
- default:
- return 0;
- }
-}
-
-Boolean CMach_PassResultInHiddenArg(Type *type) {
- switch (type->type) {
- case TYPESTRUCT:
- if (TYPE_STRUCT(type)->stype >= STRUCT_VECTOR_UCHAR && TYPE_STRUCT(type)->stype <= STRUCT_VECTOR_PIXEL)
- return 0;
- else
- return 1;
- case TYPECLASS:
- return 1;
- case TYPEMEMBERPOINTER:
- return (type->size != 4);
- default:
- return 0;
- }
-}
-
-char *CMach_GetCPU(void) {
- switch (copts.processor) {
- case CPU_PPC401: return "__PPC401__";
- case CPU_PPC403: return "__PPC403__";
- case CPU_PPC505: return "__PPC505__";
- case CPU_PPC509: return "__PPC509__";
- case CPU_PPC555: return "__PPC555__";
- case CPU_PPC556: return "__PPC556__";
- case CPU_PPC565: return "__PPC565__";
- case CPU_PPC601: return "__PPC601__";
- case CPU_PPC602: return "__PPC602__";
- case CPU_PPC603: return "__PPC603__";
- case CPU_PPC603e: return "__PPC603e__";
- case CPU_PPC604: return "__PPC604__";
- case CPU_PPC604e: return "__PPC604e__";
- case CPU_PPC740: return "__PPC740__";
- case CPU_PPC750: return "__PPC750__";
- case CPU_PPC801: return "__PPC801__";
- case CPU_PPC821: return "__PPC821__";
- case CPU_PPC823: return "__PPC823__";
- case CPU_PPC850: return "__PPC850__";
- case CPU_PPC860: return "__PPC860__";
- case CPU_PPC7400: return "__PPC7400__";
- case CPU_PPC7450: return "__PPC7450__";
- case CPU_PPC8240: return "__PPC8240__";
- case CPU_PPC8260: return "__PPC8260__";
- case CPU_PPCGEKKO: return "__PPCGEKKO__";
- case CPU_PPCELF: return "__PPCELF__";
- default: return NULL;
- }
-}
-
-Boolean CMach_FloatIsPowerOf2(Float flt) {
- return (flt.value == 2.0) ||
- (flt.value == 4.0) ||
- (flt.value == 8.0) ||
- (flt.value == 16.0) ||
- (flt.value == 32.0) ||
- (flt.value == 64.0) ||
- (flt.value == 128.0) ||
- (flt.value == 256.0) ||
- (flt.value == 512.0) ||
- (flt.value == 1024.0);
-}
-
-Float CMach_FloatReciprocal(Float flt) {
- flt.value = 1.0 / flt.value;
- return flt;
-}
-
-SInt32 CMach_RoundedSizeOf(Object *object) {
- SInt32 size = object->type->size;
- SInt32 align = CMach_GetTypeAlign(object->type) - 1;
- return (size + align) & ~align;
-}
-
-void CMach_ReInitRuntimeObjects(void) {
- HashNameNode *e0 = GetHashNameNodeExport("[0]");
- HashNameNode *e1 = GetHashNameNodeExport("[1]");
- HashNameNode *e2 = GetHashNameNodeExport("[2]");
- HashNameNode *e3 = GetHashNameNodeExport("[3]");
- HashNameNode *e4 = GetHashNameNodeExport("[4]");
- HashNameNode *e5 = GetHashNameNodeExport("[5]");
- HashNameNode *e6 = GetHashNameNodeExport("[6]");
- HashNameNode *e7 = GetHashNameNodeExport("[7]");
- HashNameNode *e8 = GetHashNameNodeExport("[8]");
- HashNameNode *e9 = GetHashNameNodeExport("[9]");
- HashNameNode *e10 = GetHashNameNodeExport("[10]");
- HashNameNode *e11 = GetHashNameNodeExport("[11]");
- HashNameNode *e12 = GetHashNameNodeExport("[12]");
- HashNameNode *e13 = GetHashNameNodeExport("[13]");
- HashNameNode *e14 = GetHashNameNodeExport("[14]");
- HashNameNode *e15 = GetHashNameNodeExport("[15]");
- HashNameNode *vuc = GetHashNameNodeExport("vector unsigned char");
- HashNameNode *vus = GetHashNameNodeExport("vector unsigned short");
- HashNameNode *vui = GetHashNameNodeExport("vector unsigned int");
- HashNameNode *vsc = GetHashNameNodeExport("vector signed char");
- HashNameNode *vss = GetHashNameNodeExport("vector signed short");
- HashNameNode *vsi = GetHashNameNodeExport("vector signed int");
- HashNameNode *vbc = GetHashNameNodeExport("vector bool char");
- HashNameNode *vbs = GetHashNameNodeExport("vector bool short");
- HashNameNode *vbi = GetHashNameNodeExport("vector bool int");
- HashNameNode *vf = GetHashNameNodeExport("vector float");
- HashNameNode *vp = GetHashNameNodeExport("vector pixel");
-
- stvectorunsignedchar.name = vuc;
- stvectorunsignedshort.name = vus;
- stvectorunsignedlong.name = vui;
- stvectorsignedchar.name = vsc;
- stvectorsignedshort.name = vss;
- stvectorsignedlong.name = vsi;
- stvectorboolchar.name = vbc;
- stvectorboolshort.name = vbs;
- stvectorboollong.name = vbi;
- stvectorfloat.name = vf;
- stvectorpixel.name = vp;
-
- stVUC_unsignedchar0.name = e0;
- stVUC_unsignedchar1.name = e1;
- stVUC_unsignedchar2.name = e2;
- stVUC_unsignedchar3.name = e3;
- stVUC_unsignedchar4.name = e4;
- stVUC_unsignedchar5.name = e5;
- stVUC_unsignedchar6.name = e6;
- stVUC_unsignedchar7.name = e7;
- stVUC_unsignedchar8.name = e8;
- stVUC_unsignedchar9.name = e9;
- stVUC_unsignedchar10.name = e10;
- stVUC_unsignedchar11.name = e11;
- stVUC_unsignedchar12.name = e12;
- stVUC_unsignedchar13.name = e13;
- stVUC_unsignedchar14.name = e14;
- stVUC_unsignedchar15.name = e15;
- stVSC_signedchar0.name = e0;
- stVSC_signedchar1.name = e1;
- stVSC_signedchar2.name = e2;
- stVSC_signedchar3.name = e3;
- stVSC_signedchar4.name = e4;
- stVSC_signedchar5.name = e5;
- stVSC_signedchar6.name = e6;
- stVSC_signedchar7.name = e7;
- stVSC_signedchar8.name = e8;
- stVSC_signedchar9.name = e9;
- stVSC_signedchar10.name = e10;
- stVSC_signedchar11.name = e11;
- stVSC_signedchar12.name = e12;
- stVSC_signedchar13.name = e13;
- stVSC_signedchar14.name = e14;
- stVSC_signedchar15.name = e15;
-
- stVUS_unsignedshort0.name = e0;
- stVUS_unsignedshort1.name = e1;
- stVUS_unsignedshort2.name = e2;
- stVUS_unsignedshort3.name = e3;
- stVUS_unsignedshort4.name = e4;
- stVUS_unsignedshort5.name = e5;
- stVUS_unsignedshort6.name = e6;
- stVUS_unsignedshort7.name = e7;
- stVSS_signedshort0.name = e0;
- stVSS_signedshort1.name = e1;
- stVSS_signedshort2.name = e2;
- stVSS_signedshort3.name = e3;
- stVSS_signedshort4.name = e4;
- stVSS_signedshort5.name = e5;
- stVSS_signedshort6.name = e6;
- stVSS_signedshort7.name = e7;
-
- stVUL_unsignedlong0.name = e0;
- stVUL_unsignedlong1.name = e1;
- stVUL_unsignedlong2.name = e2;
- stVUL_unsignedlong3.name = e3;
- stVSL_signedlong0.name = e0;
- stVSL_signedlong1.name = e1;
- stVSL_signedlong2.name = e2;
- stVSL_signedlong3.name = e3;
-
- stVF_float0.name = e0;
- stVF_float1.name = e1;
- stVF_float2.name = e2;
- stVF_float3.name = e3;
-}
diff --git a/compiler_and_linker/unsorted/CMangler.c b/compiler_and_linker/unsorted/CMangler.c
deleted file mode 100644
index 615abf5..0000000
--- a/compiler_and_linker/unsorted/CMangler.c
+++ /dev/null
@@ -1,713 +0,0 @@
-#include "compiler/CMangler.h"
-#include "compiler/CError.h"
-#include "compiler/CInt64.h"
-#include "compiler/CFunc.h"
-#include "compiler/CParser.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/types.h"
-#include "cos.h"
-
-HashNameNode *constructor_name_node;
-HashNameNode *destructor_name_node;
-HashNameNode *asop_name_node;
-
-// forward decls
-static void CMangler_MangleClassName(TypeClass *tclass);
-static void CMangler_MangleTypeAppend(Type *type, UInt32 qual);
-static void CMangler_MangleArgs(FuncArg *args);
-
-void CMangler_Setup(void) {
- constructor_name_node = GetHashNameNodeExport("__ct");
- destructor_name_node = GetHashNameNodeExport("__dt");
- asop_name_node = GetHashNameNodeExport("__as");
-}
-
-HashNameNode *CMangler_BasicDtorName(void) {
- return GetHashNameNodeExport("__dtb");
-}
-
-HashNameNode *CMangler_VBaseDtorName(void) {
- return GetHashNameNodeExport("__dtv");
-}
-
-HashNameNode *CMangler_ArrayDtorName(void) {
- return GetHashNameNodeExport("__dta");
-}
-
-HashNameNode *CMangler_SDeleteDtorName(void) {
- return GetHashNameNodeExport("__dts");
-}
-
-HashNameNode *CMangler_DeleteDtorName(void) {
- return GetHashNameNodeExport("__dt");
-}
-
-char *CMangler_GetOperator(HashNameNode *name) {
- char *str;
-
- if (name == asop_name_node)
- return "operator=";
-
- str = name->name;
- if (!strcmp(str, "__nw")) return "operator new";
- if (!strcmp(str, "__dl")) return "operator delete";
- if (!strcmp(str, "__nwa")) return "operator new[]";
- if (!strcmp(str, "__dla")) return "operator delete[]";
- if (!strcmp(str, "__pl")) return "operator+";
- if (!strcmp(str, "__mi")) return "operator-";
- if (!strcmp(str, "__ml")) return "operator*";
- if (!strcmp(str, "__dv")) return "operator/";
- if (!strcmp(str, "__md")) return "operator%";
- if (!strcmp(str, "__er")) return "operator^";
- if (!strcmp(str, "__ad")) return "operator&";
- if (!strcmp(str, "__or")) return "operator|";
- if (!strcmp(str, "__co")) return "operator~";
- if (!strcmp(str, "__nt")) return "operator!";
- if (!strcmp(str, "__lt")) return "operator<";
- if (!strcmp(str, "__gt")) return "operator>";
- if (!strcmp(str, "__apl")) return "operator+=";
- if (!strcmp(str, "__ami")) return "operator-=";
- if (!strcmp(str, "__amu")) return "operator*=";
- if (!strcmp(str, "__adv")) return "operator/=";
- if (!strcmp(str, "__amd")) return "operator%=";
- if (!strcmp(str, "__aer")) return "operator^=";
- if (!strcmp(str, "__aad")) return "operator&=";
- if (!strcmp(str, "__aor")) return "operator|=";
- if (!strcmp(str, "__ls")) return "operator<<";
- if (!strcmp(str, "__rs")) return "operator>>";
- if (!strcmp(str, "__als")) return "operator<<=";
- if (!strcmp(str, "__ars")) return "operator>>=";
- if (!strcmp(str, "__eq")) return "operator==";
- if (!strcmp(str, "__ne")) return "operator!=";
- if (!strcmp(str, "__le")) return "operator<=";
- if (!strcmp(str, "__ge")) return "operator>=";
- if (!strcmp(str, "__aa")) return "operator&&";
- if (!strcmp(str, "__oo")) return "operator||";
- if (!strcmp(str, "__pp")) return "operator++";
- if (!strcmp(str, "__mm")) return "operator--";
- if (!strcmp(str, "__cm")) return "operator,";
- if (!strcmp(str, "__rm")) return "operator->*";
- if (!strcmp(str, "__rf")) return "operator*";
- if (!strcmp(str, "__cl")) return "operator()";
- if (!strcmp(str, "__vc")) return "operator[]";
- return NULL;
-}
-
-HashNameNode *CMangler_OperatorName(short token) {
- switch (token) {
- case TK_NEW: return GetHashNameNodeExport("__nw");
- case TK_DELETE: return GetHashNameNodeExport("__dl");
- case TK_NEW_ARRAY: return GetHashNameNodeExport("__nwa");
- case TK_DELETE_ARRAY: return GetHashNameNodeExport("__dla");
- case '+': return GetHashNameNodeExport("__pl");
- case '-': return GetHashNameNodeExport("__mi");
- case '*': return GetHashNameNodeExport("__ml");
- case '/': return GetHashNameNodeExport("__dv");
- case '%': return GetHashNameNodeExport("__md");
- case '^': return GetHashNameNodeExport("__er");
- case '&': return GetHashNameNodeExport("__ad");
- case '|': return GetHashNameNodeExport("__or");
- case '~': return GetHashNameNodeExport("__co");
- case '!': return GetHashNameNodeExport("__nt");
- case '=': return asop_name_node;
- case '<': return GetHashNameNodeExport("__lt");
- case '>': return GetHashNameNodeExport("__gt");
- case TK_ADD_ASSIGN: return GetHashNameNodeExport("__apl");
- case TK_SUB_ASSIGN: return GetHashNameNodeExport("__ami");
- case TK_MULT_ASSIGN: return GetHashNameNodeExport("__amu");
- case TK_DIV_ASSIGN: return GetHashNameNodeExport("__adv");
- case TK_MOD_ASSIGN: return GetHashNameNodeExport("__amd");
- case TK_XOR_ASSIGN: return GetHashNameNodeExport("__aer");
- case TK_AND_ASSIGN: return GetHashNameNodeExport("__aad");
- case TK_OR_ASSIGN: return GetHashNameNodeExport("__aor");
- case TK_SHL: return GetHashNameNodeExport("__ls");
- case TK_SHR: return GetHashNameNodeExport("__rs");
- case TK_SHL_ASSIGN: return GetHashNameNodeExport("__als");
- case TK_SHR_ASSIGN: return GetHashNameNodeExport("__ars");
- case TK_LOGICAL_EQ: return GetHashNameNodeExport("__eq");
- case TK_LOGICAL_NE: return GetHashNameNodeExport("__ne");
- case TK_LESS_EQUAL: return GetHashNameNodeExport("__le");
- case TK_GREATER_EQUAL: return GetHashNameNodeExport("__ge");
- case TK_LOGICAL_AND: return GetHashNameNodeExport("__aa");
- case TK_LOGICAL_OR: return GetHashNameNodeExport("__oo");
- case TK_INCREMENT: return GetHashNameNodeExport("__pp");
- case TK_DECREMENT: return GetHashNameNodeExport("__mm");
- case ',': return GetHashNameNodeExport("__cm");
- case TK_ARROW_STAR: return GetHashNameNodeExport("__rm");
- case TK_ARROW: return GetHashNameNodeExport("__rf");
- case '(': return GetHashNameNodeExport("__cl");
- case '[': return GetHashNameNodeExport("__vc");
- default: return NULL;
- }
-}
-
-HashNameNode *CMangler_VTableName(TypeClass *theclass) {
- HashNameNode *name;
-
- name_mangle_list.size = 0;
- AppendGListName(&name_mangle_list, "__vt__");
- CMangler_MangleClassName(theclass);
- AppendGListByte(&name_mangle_list, 0);
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) {
- HashNameNode *name;
-
- name_mangle_list.size = 0;
- AppendGListName(&name_mangle_list, "__RTTI__");
- CMangler_MangleTypeAppend(type, qual);
- AppendGListByte(&name_mangle_list, 0);
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-HashNameNode *CMangler_ThunkName(Object *vfunc, SInt32 this_delta, SInt32 return_delta, SInt32 ctoroffset) {
- HashNameNode *linkname;
- HashNameNode *name;
- char buf[64];
-
- linkname = CMangler_GetLinkName(vfunc);
- name_mangle_list.size = 0;
- if (return_delta == 0) {
- if (ctoroffset < 0)
- sprintf(buf, "_@%" PRId32 "@", -this_delta);
- else
- sprintf(buf, "_@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset);
- } else {
- sprintf(buf, "_@%" PRId32 "@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset, return_delta);
- }
- AppendGListName(&name_mangle_list, buf);
- AppendGListID(&name_mangle_list, linkname->name + 1);
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-static void CMangler_CheckTemplateArguments(TemplArg *arg) {
- ENode *expr;
-
- while (arg) {
- if (arg->pid.type == TPT_NONTYPE) {
- expr = arg->data.paramdecl.expr;
- CError_ASSERT(360, expr);
- if (expr->rtype->type != TYPETEMPLDEPEXPR) {
- switch (expr->type) {
- case EINTCONST:
- break;
- case EOBJREF:
- CMangler_GetLinkName(expr->data.objref);
- break;
- default:
- CError_FATAL(383);
- }
- }
- }
- arg = arg->next;
- }
-}
-
-static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
- ENode *expr;
- char buf[32];
-
- AppendGListByte(&name_mangle_list, '<');
-
- while (arg) {
- if (arg->pid.type == TPT_NONTYPE) {
- expr = arg->data.paramdecl.expr;
- CError_ASSERT(409, expr);
- if (expr->rtype->type != TYPETEMPLDEPEXPR) {
- switch (expr->type) {
- case EINTCONST:
- CInt64_PrintDec(buf, expr->data.intval);
- AppendGListName(&name_mangle_list, buf);
- break;
- case EOBJREF:
- AppendGListByte(&name_mangle_list, '&');
- AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
- break;
- default:
- CError_FATAL(452);
- }
- } else {
- AppendGListByte(&name_mangle_list, 'T');
- }
- } else if (arg->pid.type == TPT_TYPE) {
- CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
- } else {
- CError_ASSERT(467, arg->pid.type == TPT_TEMPLATE);
- CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
- }
-
- if (arg->next)
- AppendGListByte(&name_mangle_list, ',');
- arg = arg->next;
- }
-
- AppendGListByte(&name_mangle_list, '>');
-}
-
-HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args) {
- HashNameNode *name;
-
- CMangler_CheckTemplateArguments(args);
- name_mangle_list.size = 0;
- AppendGListName(&name_mangle_list, basename->name);
- CMangler_AppendTemplateArgumentList(args);
- AppendGListByte(&name_mangle_list, 0);
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-static void CMangler_MangleTypeName(char *str) {
- char buf[16];
-
- sprintf(buf, "%d", strlen(str));
- AppendGListName(&name_mangle_list, buf);
- AppendGListName(&name_mangle_list, str);
-}
-
-static void CMangler_MangleNameSpaceName(NameSpace *nspace, char *str) {
- char *stack[10];
- int stackp;
-
- stack[0] = str;
- stackp = 1;
- while (nspace) {
- if (nspace->name) {
- stack[stackp++] = nspace->name->name;
- if (stackp >= 9)
- break;
- }
- nspace = nspace->parent;
- }
-
- if (stackp > 1) {
- AppendGListByte(&name_mangle_list, 'Q');
- AppendGListByte(&name_mangle_list, '0' + stackp);
- }
-
- while (--stackp >= 0)
- CMangler_MangleTypeName(stack[stackp]);
-}
-
-static void CMangler_MangleClassName(TypeClass *tclass) {
- if (!tclass->classname)
- CMangler_MangleNameSpaceName(tclass->nspace->parent, "class");
- else
- CMangler_MangleNameSpaceName(tclass->nspace->parent, tclass->nspace->name->name);
-}
-
-static void CMangler_MangleQualifier(UInt32 qual) {
- if (qual & Q_CONST)
- AppendGListByte(&name_mangle_list, 'C');
- if (qual & Q_VOLATILE)
- AppendGListByte(&name_mangle_list, 'V');
-}
-
-static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
- char buf[16];
-
- switch (type->type) {
- case TYPEVOID:
- CMangler_MangleQualifier(qual);
- AppendGListByte(&name_mangle_list, 'v');
- break;
- case TYPEINT:
- case TYPEFLOAT:
- CMangler_MangleQualifier(qual);
- switch (TYPE_INTEGRAL(type)->integral) {
- case IT_BOOL:
- AppendGListByte(&name_mangle_list, 'b');
- return;
- case IT_CHAR:
- AppendGListByte(&name_mangle_list, 'c');
- return;
- case IT_WCHAR_T:
- AppendGListByte(&name_mangle_list, 'w');
- return;
- case IT_UCHAR:
- AppendGListName(&name_mangle_list, "Uc");
- return;
- case IT_SCHAR:
- AppendGListName(&name_mangle_list, "Sc");
- return;
- case IT_SHORT:
- AppendGListByte(&name_mangle_list, 's');
- return;
- case IT_USHORT:
- AppendGListName(&name_mangle_list, "Us");
- return;
- case IT_INT:
- AppendGListByte(&name_mangle_list, 'i');
- return;
- case IT_UINT:
- AppendGListName(&name_mangle_list, "Ui");
- return;
- case IT_LONG:
- AppendGListByte(&name_mangle_list, 'l');
- return;
- case IT_ULONG:
- AppendGListName(&name_mangle_list, "Ul");
- return;
- case IT_LONGLONG:
- AppendGListByte(&name_mangle_list, 'x');
- return;
- case IT_ULONGLONG:
- AppendGListName(&name_mangle_list, "Ux");
- return;
- case IT_FLOAT:
- AppendGListByte(&name_mangle_list, 'f');
- return;
- case IT_SHORTDOUBLE:
- AppendGListByte(&name_mangle_list, 'D');
- return;
- case IT_DOUBLE:
- AppendGListByte(&name_mangle_list, 'd');
- return;
- case IT_LONGDOUBLE:
- AppendGListByte(&name_mangle_list, 'r');
- return;
- default:
- CError_FATAL(619);
- }
- case TYPEENUM:
- CMangler_MangleQualifier(qual);
- if (!TYPE_ENUM(type)->enumname)
- CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, "enum");
- else
- CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, TYPE_ENUM(type)->enumname->name);
- break;
- case TYPEPOINTER:
- CMangler_MangleQualifier(TYPE_POINTER(type)->qual);
- if (TYPE_POINTER(type)->qual & Q_REFERENCE)
- AppendGListByte(&name_mangle_list, 'R');
- else
- AppendGListByte(&name_mangle_list, 'P');
- CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
- break;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(type)->ty2->type != TYPECLASS) {
- AppendGListName(&name_mangle_list, "3<T>");
- } else {
- CMangler_MangleQualifier(TYPE_MEMBER_POINTER(type)->qual);
- AppendGListByte(&name_mangle_list, 'M');
- CMangler_MangleClassName(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
- CMangler_MangleTypeAppend(TYPE_MEMBER_POINTER(type)->ty1, qual);
- }
- break;
- case TYPEARRAY:
- AppendGListByte(&name_mangle_list, 'A');
- if (TYPE_POINTER(type)->target->size) {
- sprintf(buf, "%" PRId32 "", type->size / TYPE_POINTER(type)->target->size);
- AppendGListName(&name_mangle_list, buf);
- } else {
- AppendGListByte(&name_mangle_list, '0');
- }
- AppendGListByte(&name_mangle_list, '_');
- CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
- break;
- case TYPEFUNC:
- CMangler_MangleQualifier(qual);
- AppendGListByte(&name_mangle_list, 'F');
- CMangler_MangleArgs(TYPE_FUNC(type)->args);
- AppendGListByte(&name_mangle_list, '_');
- CMangler_MangleTypeAppend(TYPE_FUNC(type)->functype, TYPE_FUNC(type)->qual);
- break;
- case TYPESTRUCT:
- CMangler_MangleQualifier(qual);
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- AppendGListName(&name_mangle_list, "XUc");
- return;
- case STRUCT_VECTOR_SCHAR:
- AppendGListName(&name_mangle_list, "Xc");
- return;
- case STRUCT_VECTOR_BCHAR:
- AppendGListName(&name_mangle_list, "XC");
- return;
- case STRUCT_VECTOR_USHORT:
- AppendGListName(&name_mangle_list, "XUs");
- return;
- case STRUCT_VECTOR_SSHORT:
- AppendGListName(&name_mangle_list, "Xs");
- return;
- case STRUCT_VECTOR_BSHORT:
- AppendGListName(&name_mangle_list, "XS");
- return;
- case STRUCT_VECTOR_UINT:
- AppendGListName(&name_mangle_list, "XUi");
- return;
- case STRUCT_VECTOR_SINT:
- AppendGListName(&name_mangle_list, "Xi");
- return;
- case STRUCT_VECTOR_BINT:
- AppendGListName(&name_mangle_list, "XI");
- return;
- case STRUCT_VECTOR_FLOAT:
- AppendGListName(&name_mangle_list, "Xf");
- return;
- case STRUCT_VECTOR_PIXEL:
- AppendGListName(&name_mangle_list, "Xp");
- return;
- }
-
- if (TYPE_STRUCT(type)->name && !IsTempName(TYPE_STRUCT(type)->name)) {
- CMangler_MangleTypeName(TYPE_STRUCT(type)->name->name);
- return;
- }
-
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_TYPE_STRUCT:
- AppendGListName(&name_mangle_list, "struct");
- break;
- case STRUCT_TYPE_UNION:
- AppendGListName(&name_mangle_list, "union");
- break;
- case STRUCT_TYPE_CLASS:
- AppendGListName(&name_mangle_list, "class");
- break;
- default:
- CError_FATAL(701);
- }
- break;
-
- case TYPECLASS:
- CMangler_MangleQualifier(qual);
- CMangler_MangleClassName(TYPE_CLASS(type));
- break;
-
- case TYPETEMPLATE:
- AppendGListName(&name_mangle_list, "1T");
- break;
-
- default:
- CError_FATAL(716);
- }
-}
-
-void CMangler_MangleType(Type *type, UInt32 qual) {
- name_mangle_list.size = 0;
- CMangler_MangleTypeAppend(type, qual);
-}
-
-static void CMangler_MangleArgs(FuncArg *args) {
- TypePointer ptr;
-
- if (args) {
- if (args->type) {
- while (args) {
- if (args != &elipsis && args != &oldstyle) {
- if (args->type->type == TYPEPOINTER) {
- ptr = *TYPE_POINTER(args->type);
- ptr.qual &= ~(Q_CONST | Q_VOLATILE);
- CMangler_MangleTypeAppend(TYPE(&ptr), args->qual);
- } else {
- CMangler_MangleTypeAppend(args->type, 0);
- }
- } else {
- AppendGListByte(&name_mangle_list, 'e');
- }
- args = args->next;
- }
- } else {
- AppendGListByte(&name_mangle_list, 'e');
- }
- } else {
- AppendGListByte(&name_mangle_list, 'v');
- }
-}
-
-static void CMangler_MangleFunction(Object *obj, NameSpace *nspace) {
- TypeFunc *tfunc = TYPE_FUNC(obj->type);
- FuncArg *arg = tfunc->args;
-
- AppendGListName(&name_mangle_list, obj->name->name);
- if (obj->u.func.inst) {
- if (tfunc->flags & FUNC_CONVERSION)
- CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
- CMangler_AppendTemplateArgumentList(obj->u.func.inst->args);
- }
- AppendGListName(&name_mangle_list, "__");
- while (nspace && nspace->name == NULL)
- nspace = nspace->parent;
-
- if (nspace) {
- CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
- if (nspace->theclass) {
- if (obj->name == destructor_name_node) {
- AppendGListName(&name_mangle_list, "Fv");
- return;
- }
- if (arg) {
- if (obj->name == constructor_name_node) {
- arg = arg->next;
- if (arg && (nspace->theclass->flags & CLASS_HAS_VBASES))
- arg = arg->next;
- } else {
- if ((tfunc->flags & FUNC_METHOD) && !TYPE_METHOD(tfunc)->is_static) {
- CMangler_MangleQualifier(arg->qual);
- arg = arg->next;
- }
- }
- }
- }
- }
-
- AppendGListByte(&name_mangle_list, 'F');
- CMangler_MangleArgs(arg);
- if (obj->u.func.inst && copts.new_mangler) {
- AppendGListByte(&name_mangle_list, '_');
- CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
- }
-}
-
-HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual) {
- HashNameNode *name;
-
- if (CTemplTool_IsTemplateArgumentDependentType(type))
- return GetHashNameNodeExport("__op");
-
- name_mangle_list.size = 0;
- AppendGListName(&name_mangle_list, "__op");
- CMangler_MangleTypeAppend(type, qual);
- AppendGListByte(&name_mangle_list, 0);
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-static HashNameNode *CMangler_MangleNameToUpper(char *str) {
- HashNameNode *name;
-
- name_mangle_list.size = 0;
- while (*str) {
- AppendGListByte(&name_mangle_list, toupper(*(str++)));
- }
- AppendGListByte(&name_mangle_list, 0);
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-static HashNameNode *CMangler_FunctionLinkName(Object *obj) {
- HashNameNode *name;
- NameSpace *nspace;
-
- if (obj->u.func.inst)
- CMangler_CheckTemplateArguments(obj->u.func.inst->args);
-
- for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
- if (nspace->name)
- break;
- }
-
- name_mangle_list.size = 0;
- if (is_pascal_object(obj) && (!nspace || !nspace->theclass)) {
- AppendGListData(&name_mangle_list, "_", 1);
- AppendGListID(&name_mangle_list, obj->name->name);
- } else if ((obj->qual & Q_MANGLE_NAME) && (strcmp("main", obj->name->name) || (obj->nspace != cscope_root))) {
- AppendGListData(&name_mangle_list, "_", 1);
- CMangler_MangleFunction(obj, nspace);
- AppendGListByte(&name_mangle_list, 0);
- } else {
- AppendGListData(&name_mangle_list, "_", 1);
- AppendGListID(&name_mangle_list, obj->name->name);
- }
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-HashNameNode *CMangler_GetCovariantFunctionName(Object *dobj, TypeClass *theclass) {
- HashNameNode *name;
-
- name = CMangler_GetLinkName(dobj);
- name_mangle_list.size = 0;
- AppendGListName(&name_mangle_list, name->name);
- AppendGListName(&name_mangle_list, "@@");
- CMangler_MangleTypeAppend(TYPE(theclass), 0);
- AppendGListByte(&name_mangle_list, 0);
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-static HashNameNode *CMangler_DataLinkName(Object *obj) {
- NameSpace *nspace;
- HashNameNode *name;
-
- nspace = obj->nspace;
- while (nspace && nspace->name == NULL)
- nspace = nspace->parent;
-
- name_mangle_list.size = 0;
- AppendGListData(&name_mangle_list, "_", 1);
- AppendGListName(&name_mangle_list, obj->name->name);
-
- while (nspace && nspace->name == NULL)
- nspace = nspace->parent;
- if (nspace && (obj->qual & Q_MANGLE_NAME)) {
- AppendGListName(&name_mangle_list, "__");
- CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
- }
- AppendGListByte(&name_mangle_list, 0);
-
- COS_LockHandle(name_mangle_list.data);
- name = GetHashNameNodeExport(*name_mangle_list.data);
- COS_UnlockHandle(name_mangle_list.data);
- return name;
-}
-
-HashNameNode *CMangler_GetLinkName(Object *obj) {
- while (obj->datatype == DALIAS)
- obj = obj->u.alias.object;
-
- switch (obj->datatype) {
- case DFUNC:
- case DVFUNC:
- if (!obj->u.func.linkname)
- obj->u.func.linkname = CMangler_FunctionLinkName(obj);
- return obj->u.func.linkname;
- case DDATA:
- if (!obj->u.data.linkname)
- obj->u.data.linkname = CMangler_DataLinkName(obj);
- return obj->u.data.linkname;
- case DINLINEFUNC:
- return CMangler_FunctionLinkName(obj);
- case DLOCAL:
- case DABSOLUTE:
- case DLABEL:
- return obj->name;
- case DNONLAZYPTR:
- if (!obj->u.toc.linkname)
- obj->u.toc.linkname = CMangler_DataLinkName(obj);
- return obj->u.toc.linkname;
- default:
- CError_FATAL(1110);
- return NULL;
- }
-}
diff --git a/compiler_and_linker/unsorted/COptimizer.c b/compiler_and_linker/unsorted/COptimizer.c
deleted file mode 100644
index 9833a2b..0000000
--- a/compiler_and_linker/unsorted/COptimizer.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-#include "compiler/COptimizer.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/CodeGen.h"
-#include "compiler/Switch.h"
-#include "compiler/Exceptions.h"
-#include "compiler/IrOptimizer.h"
-#include "cos.h"
-
-COptBlock *basicblocks;
-Boolean copt_isleaffunction;
-static Boolean stmtchanged;
-static COptBlock *currentblock;
-static ENode *mexpr;
-static short setbytes;
-static COptCSE *csenodes[MAXEXPR];
-static COptCSEList *cselist;
-static short extravars;
-static Boolean cse_found;
-static Boolean cse_invals;
-static Boolean static_for_inlines;
-static short replaces;
-static ENode *objrefnode;
-static int objrefnodes;
-
-static short bitmasks[] = {
- 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
- 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000
-};
-
-// forward decls
-static COptCSE *cse_expression(ENode *expr);
-
-static COptCSE *cse_new(ENode *expr) {
- COptCSE *cse = oalloc(sizeof(COptCSE));
- cse->expr = expr;
- cse->replaced = NULL;
- cse->block = currentblock;
- cse->mexpr = mexpr;
- cse->left = NULL;
- cse->right = NULL;
- cse->x1C = 1;
- return cse;
-}
-
-static COptCSE *cse_append(COptCSE *cse, ENode *expr) {
- COptCSEList *list = oalloc(sizeof(COptCSEList));
- list->next = cselist;
- cselist = list;
- list->cse = cse;
- list->expr = expr;
- return cse;
-}
-
-static void cse_cleanup(void) {
- COptCSEList *scanlist;
- COptCSEList *prevlist;
- COptCSE *scan;
- COptCSE *prev;
- short op;
-
- scanlist = cselist;
- while (scanlist && !scanlist->cse)
- scanlist = scanlist->next;
- cselist = scanlist;
-
- if (scanlist) {
- do {
- prevlist = scanlist;
- do {
- scanlist = scanlist->next;
- } while (scanlist && !scanlist->cse);
- prevlist->next = scanlist;
- } while (scanlist);
- }
-
- for (op = 0; op < MAXEXPR; op++) {
- scan = csenodes[op];
- while (scan && scan->x1C < 0)
- scan = scan->next;
- csenodes[op] = scan;
-
- if (scan) {
- do {
- prev = scan;
- do {
- scan = scan->next;
- } while (scan && scan->x1C < 0);
- prev->next = scan;
- } while (scan);
- }
- }
-}
-
-static void cse_inval(COptCSE *cse) {
- COptCSEList *scanlist;
- COptCSE *scan;
- short op;
-
- if (cse) {
- for (scanlist = cselist; scanlist; scanlist = scanlist->next) {
- if (scanlist->cse == cse) {
- scanlist->cse = NULL;
- scanlist->expr = NULL;
- }
- }
-
- cse->x1C = -1;
- cse->left = NULL;
- cse->right = NULL;
-
- for (op = 0; op < MAXEXPR; op++) {
- for (scan = csenodes[op]; scan; scan = scan->next) {
- if (scan->left == cse || scan->right == cse)
- cse_inval(scan);
- }
- }
- }
-}
-
-static void cse_update_usages(COptCSE *cse, short amount) {
- cse->x1C /= amount;
- if (cse->left)
- cse_update_usages(cse->left, amount);
- if (cse->right)
- cse_update_usages(cse->right, amount);
-}
-
-static void cse_replace(ENode *expr, COptCSE *cse) {
- COptCSEList *list;
-
- for (list = cselist; list; list = list->next) {
- if (list->cse == cse) {
- *list->expr = *expr;
- replaces++;
- list->cse = NULL;
- list->expr = NULL;
- }
- }
-}
-
-static short cse_objectcost(Object *obj) {
- if (obj->datatype == DLOCAL && !obj->u.var.info->noregister)
- return 0;
- return 1;
-}
-
-static void cse_treereplacemexpr(COptCSE *cse, ENode *from, ENode *to) {
- if (cse->mexpr == from)
- cse->mexpr = to;
- if (cse->left)
- cse_treereplacemexpr(cse->left, from, to);
- if (cse->right)
- cse_treereplacemexpr(cse->right, from, to);
-}
-
-static Boolean cse_issubcse(COptCSE *a, COptCSE *b) {
- if (a == b)
- return 1;
- if (b->left && cse_issubcse(a, b->left))
- return 1;
- if (b->right && cse_issubcse(a, b->right))
- return 1;
-
- return 0;
-}
-
-static short cse_cost(COptCSE *cse) {
- short cost;
-
- if (cse) {
- while (ENODE_IS(cse->expr, ETYPCON) && cse->expr->rtype->type == cse->expr->data.monadic->rtype->type && cse->expr->rtype->size == cse->expr->data.monadic->rtype->size)
- cse = cse->left;
-
- if (ENODE_IS_INDIRECT_TO(cse->expr, EOBJREF))
- return cse_objectcost(cse->expr->data.monadic->data.objref);
-
- cost = 1;
- if (!copts.optimizesize) {
- if (ENODE_IS3(cse->expr, EMUL, EDIV, EMODULO))
- cost = 2;
- }
- return cse_cost(cse->left) + cse_cost(cse->right) + cost;
- }
-
- return 0;
-}
-
-static void cse_remove(void) {
- short op; // r27
- COptCSE *cse; // r25
- COptCSE *best_cse; // r28
- int best_cost; // r30
- Object *obj; // r31
- Boolean did_replacement; // r24
- VarInfo *vi; // r27
- ObjectList *objlist;
- ENode *expr1;
- ENode *expr2;
- ENode *expr3;
- ENode *expr4;
- ENode *mexprsave;
- COptCSEList *list;
- short cost;
-
- while (1) {
- op = 0;
- best_cse = NULL;
- best_cost = 0;
- did_replacement = 0;
-
- for (; op < MAXEXPR; op++) {
- switch (op) {
- case EINTCONST:
- case EFLOATCONST:
- case EOBJREF:
- case EVECTOR128CONST:
- break;
- default:
- for (cse = csenodes[op]; cse; cse = cse->next) {
- if (cse->x1C > 1 && (cost = cse_cost(cse)) > 4) {
- if (cse->replaced) {
- replaces = 0;
- cse_replace(cse->replaced, cse);
- CError_ASSERT(348, replaces >= 1);
- cse_found = 1;
- did_replacement = 1;
- cse_update_usages(cse, cse->x1C);
- } else {
- if ((cse->x1C * cost) > best_cost) {
- best_cse = cse;
- best_cost = cse->x1C * cost;
- }
- }
- }
- }
- break;
- }
- }
-
- if (did_replacement)
- continue;
- if (!best_cse || extravars >= 256)
- return;
-
- obj = lalloc(sizeof(Object));
- memclrw(obj, sizeof(Object));
- obj->name = CParser_GetUniqueName();
- obj->type = cse->expr->rtype;
- obj->datatype = DLOCAL;
- vi = CodeGen_GetNewVarInfo();
- obj->u.var.info = vi;
-
- objlist = lalloc(sizeof(ObjectList));
- objlist->object = obj;
- objlist->next = locals;
- locals = objlist;
-
- vi->used = 1;
- vi->usage = cse->x1C + 1;
-
- expr1 = lalloc(sizeof(ENode));
- expr1->type = EOBJREF;
- expr1->cost = 0;
- expr1->flags = 0;
- expr1->data.objref = obj;
- expr1->rtype = CDecl_NewPointerType(obj->type);
-
- expr2 = lalloc(sizeof(ENode));
- expr2->type = EINDIRECT;
- expr2->cost = 1;
- expr2->flags = 0;
- expr2->data.monadic = expr1;
- expr2->rtype = obj->type;
-
- expr3 = lalloc(sizeof(ENode));
- expr3->type = EASS;
- expr3->cost = -1;
- expr3->flags = 0;
- expr3->rtype = obj->type;
- expr3->data.diadic.left = expr2;
- expr3->data.diadic.right = lalloc(sizeof(ENode));
-
- *expr3->data.diadic.right = *cse->expr;
- cse->expr = expr3->data.diadic.right;
-
- replaces = 0;
- cse_replace(expr2, cse);
- cse->replaced = expr2;
-
- if (replaces < 2)
- CError_FATAL(390);
- else
- cse_found = 1;
-
- expr4 = lalloc(sizeof(ENode));
- *expr4 = *cse->mexpr;
-
- cse->mexpr->type = ECOMMA;
- cse->mexpr->data.diadic.left = expr3;
- cse->mexpr->data.diadic.right = expr4;
-
- cse_update_usages(cse, cse->x1C);
- extravars++;
-
- mexprsave = cse->mexpr;
- if (mexpr == mexprsave)
- mexpr = expr4;
-
- for (list = cselist; list; list = list->next) {
- if (list->cse && !cse_issubcse(list->cse, cse)) {
- if (list->cse->mexpr == mexprsave)
- list->cse->mexpr = expr4;
- if (list->cse->expr == mexprsave)
- list->cse->expr = expr4;
- if (list->expr == mexprsave)
- list->expr = expr4;
- }
- }
- }
-}
-
-static COptCSE *cse_intconst(ENode *expr) {
- COptCSE *cse = csenodes[EINTCONST];
-
- for (; cse; cse = cse->next) {
- if (expr->rtype == cse->expr->rtype)
- if (CInt64_Equal(cse->expr->data.intval, expr->data.intval))
- return cse;
- }
-
- cse = cse_new(expr);
- cse->next = csenodes[EINTCONST];
- csenodes[EINTCONST] = cse;
- return cse;
-}
-
-static COptCSE *cse_floatconst(ENode *expr) {
- COptCSE *cse = csenodes[EFLOATCONST];
- Float val = expr->data.floatval;
-
- for (; cse; cse = cse->next) {
- if (CMach_CalcFloatDiadicBool(cse->expr->rtype, cse->expr->data.floatval, TK_LOGICAL_EQ, val))
- if (expr->rtype == cse->expr->rtype)
- return cse;
- }
-
- cse = cse_new(expr);
- cse->next = csenodes[EFLOATCONST];
- csenodes[EFLOATCONST] = cse;
- return cse;
-}
-
-static COptCSE *cse_vectorconst(ENode *expr) {
- COptCSE *cse = csenodes[EVECTOR128CONST];
- MWVector128 val = expr->data.vector128val;
-
- for (; cse; cse = cse->next) {
- if (CMach_CalcVectorDiadicBool(cse->expr->rtype, &cse->expr->data.vector128val, TK_LOGICAL_EQ, &val))
- if (expr->rtype == cse->expr->rtype)
- return cse;
- }
-
- cse = cse_new(expr);
- cse->next = csenodes[EVECTOR128CONST];
- csenodes[EVECTOR128CONST] = cse;
- return cse;
-}
-
-static COptCSE *cse_objref(ENode *expr) {
- COptCSE *cse = csenodes[EOBJREF];
- Object *obj = expr->data.objref;
-
- for (; cse; cse = cse->next) {
- if (cse->expr->data.objref == obj)
- return cse;
- }
-
- cse = cse_new(expr);
- cse->next = csenodes[EOBJREF];
- csenodes[EOBJREF] = cse;
- return cse;
-}
-
-static COptCSE *cse_add_monadic_node(ENode *outer, COptCSE *innercse) {
- COptCSE *cse;
-
- if (!innercse)
- return NULL;
-
- for (cse = csenodes[outer->type]; cse; cse = cse->next) {
- if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
- CError_ASSERT(524, cse->expr != outer);
- cse->x1C++;
- return cse;
- }
- }
-
- cse = cse_new(outer);
- cse->next = csenodes[outer->type];
- csenodes[outer->type] = cse;
- cse->left = innercse;
- return cse;
-}
-
-static COptCSE *cse_add_typecon_node(ENode *outer, COptCSE *innercse) {
- COptCSE *cse;
-
- if (!innercse)
- return NULL;
-
- for (cse = csenodes[outer->type]; cse; cse = cse->next) {
- if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
- CError_ASSERT(552, cse->expr != outer);
- cse->x1C++;
- return cse;
- }
- }
-
- cse = cse_new(outer);
- cse->next = csenodes[outer->type];
- csenodes[outer->type] = cse;
- cse->left = innercse;
- return cse;
-}
-
-static COptCSE *cse_add_diadic_node(ENode *outer, COptCSE *leftcse, COptCSE *rightcse) {
- COptCSE *cse;
-
- if (!leftcse || !rightcse)
- return NULL;
-
- for (cse = csenodes[outer->type]; cse; cse = cse->next) {
- if (cse->left == leftcse && cse->right == rightcse) {
- CError_ASSERT(581, cse->expr != outer);
- cse->x1C++;
- return cse;
- }
- }
-
- cse = cse_new(outer);
- cse->next = csenodes[outer->type];
- csenodes[outer->type] = cse;
- cse->left = leftcse;
- cse->right = rightcse;
- return cse;
-}
-
-static COptCSE *cse_add_commdiadic_node(ENode *outer, COptCSE *leftcse, COptCSE *rightcse) {
- COptCSE *cse;
-
- if (!leftcse || !rightcse)
- return NULL;
-
- for (cse = csenodes[outer->type]; cse; cse = cse->next) {
- if ((cse->left == leftcse && cse->right == rightcse) || (cse->left == rightcse && cse->right == leftcse)) {
- CError_ASSERT(612, cse->expr != outer);
- cse->x1C++;
- return cse;
- }
- }
-
- cse = cse_new(outer);
- cse->next = csenodes[outer->type];
- csenodes[outer->type] = cse;
- cse->left = leftcse;
- cse->right = rightcse;
- return cse;
-}
-
-static void sfind_objref(ENode *expr) {
- while (1) {
- switch (expr->type) {
- case ETYPCON:
- expr = expr->data.monadic;
- break;
- case EOBJREF:
- objrefnode = expr;
- objrefnodes++;
- return;
- case EADD:
- case ESUB:
- sfind_objref(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- break;
- default:
- return;
- }
- }
-}
-
-static ENode *find_objref_node(ENode *expr) {
- objrefnode = NULL;
- objrefnodes = 0;
- sfind_objref(expr);
- if (objrefnodes == 1)
- return objrefnode;
- else
- return NULL;
-}
-
-static void cse_mem_modify(void) {
- COptCSE *cse;
-
- for (cse = csenodes[EINDIRECT]; cse; cse = cse->next) {
- if (ENODE_IS(cse->expr->data.monadic, EOBJREF)) {
- Object *obj = cse->expr->data.monadic->data.objref;
- CError_ASSERT(672, obj->datatype != DALIAS);
- if (obj->datatype == DLOCAL && !obj->u.var.info->noregister)
- continue;
- }
-
- cse_inval(cse);
- }
-}
-
-static void cse_modify_expression(ENode *expr) {
- if (!expr) {
- short op;
-
- cse_remove();
- for (op = 0; op < MAXEXPR; op++)
- csenodes[op] = NULL;
-
- cselist = NULL;
- freeoheap();
- } else {
- ENode *objnode;
- Object *obj;
- COptCSE *cse;
-
- cse_invals = 1;
- if (ENODE_IS(expr, EINDIRECT) && (objnode = find_objref_node(expr->data.monadic))) {
- do {
- obj = objnode->data.objref;
- cse_remove();
- for (cse = csenodes[EINDIRECT]; cse; cse = cse->next) {
- if ((objnode = find_objref_node(cse->expr->data.monadic)) && obj == objnode->data.objref)
- cse_inval(cse);
- }
-
- objnode = find_objref_node(expr->data.monadic);
- if (!objnode) {
- cse_mem_modify();
- break;
- }
- } while (obj != objnode->data.objref);
- } else {
- cse_remove();
- cse_mem_modify();
- }
- }
-}
-
-static void cse_pascalcall(ENode *expr) {
- ENodeList *list;
-
- for (list = expr->data.funccall.args; list; list = list->next)
- cse_expression(list->node);
-
- if (ENODE_IS(expr, EFUNCCALLP))
- cse_expression(expr->data.funccall.funcref);
-
- cse_remove();
- cse_mem_modify();
-}
-
-static Boolean cse_pusharg(ENodeList *exprs, FuncArg *args) {
- Boolean result;
-
- if (!exprs)
- return 1;
-
- if (args && args != &elipsis && args != &oldstyle)
- args = args->next;
- if (exprs->next)
- result = cse_pusharg(exprs->next, args);
-
- cse_expression(exprs->node);
- return result;
-}
-
-static void cse_ccall(ENode *expr) {
- if (cse_pusharg(expr->data.funccall.args, expr->data.funccall.functype->args)) {
- if (ENODE_IS(expr, EFUNCCALL))
- cse_expression(expr->data.funccall.funcref);
-
- cse_remove();
- cse_mem_modify();
- } else {
- cse_modify_expression(NULL);
- }
-}
-
-static COptCSE *cse_expression(ENode *expr) {
- ENode *save;
- COptCSE *tmp;
- ENodeType nt = expr->type;
-
- switch (nt) {
- case EFUNCCALL:
- cse_ccall(expr);
- return NULL;
- case EFUNCCALLP:
- cse_pascalcall(expr);
- return NULL;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- save = mexpr;
- mexpr = expr;
- CError_ASSERT(816, ENODE_IS(expr->data.monadic, EINDIRECT));
-
- cse_expression(expr->data.monadic->data.monadic);
- cse_modify_expression(expr->data.monadic);
- mexpr = save;
- return NULL;
-
- case EINDIRECT:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- return cse_append(cse_add_monadic_node(expr, cse_expression(expr->data.monadic)), expr);
-
- case ETYPCON:
- return cse_append(cse_add_typecon_node(expr, cse_expression(expr->data.monadic)), expr);
-
- case EMUL:
- case EMULV:
- case EADDV:
- case EADD:
- case EEQU:
- case ENOTEQU:
- case EAND:
- case EXOR:
- case EOR:
- tmp = cse_expression(expr->data.diadic.left);
- if (expr->type == nt)
- return cse_append(cse_add_commdiadic_node(expr, tmp, cse_expression(expr->data.diadic.right)), expr);
- else
- return NULL;
-
- case EDIV:
- case EMODULO:
- case ESUBV:
- case ESUB:
- case ESHL:
- case ESHR:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EPMODULO:
- case EROTL:
- case EROTR:
- case EBTST:
- tmp = cse_expression(expr->data.diadic.left);
- if (expr->type == nt)
- return cse_append(cse_add_diadic_node(expr, tmp, cse_expression(expr->data.diadic.right)), expr);
- else
- return NULL;
-
- case EASS:
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- CError_ASSERT(887, ENODE_IS(expr->data.diadic.left, EINDIRECT));
- save = mexpr;
- mexpr = expr;
- cse_expression(expr->data.diadic.right);
- if (expr->type == nt) {
- cse_expression(expr->data.diadic.left->data.monadic);
- cse_modify_expression(expr->data.diadic.left);
- mexpr = save;
- return NULL;
- } else {
- cse_modify_expression(NULL);
- return NULL;
- }
-
- case ECOMMA:
- cse_expression(expr->data.diadic.left);
- save = mexpr;
- mexpr = expr->data.diadic.right;
- tmp = cse_expression(expr->data.diadic.right);
- mexpr = save;
- return tmp;
-
- case EINTCONST:
- return cse_intconst(expr);
- case EFLOATCONST:
- return cse_floatconst(expr);
- case EVECTOR128CONST:
- return cse_vectorconst(expr);
- case EOBJREF:
- return cse_objref(expr);
-
- case EBITFIELD:
- cse_modify_expression(NULL);
- return NULL;
-
- case ECOND:
- cse_expression(expr->data.cond.cond);
- cse_modify_expression(NULL);
- return NULL;
-
- case ENULLCHECK:
- cse_expression(expr->data.nullcheck.nullcheckexpr);
- cse_modify_expression(NULL);
- return NULL;
-
- case ELAND:
- case ELOR:
- cse_expression(expr->data.diadic.left);
- cse_modify_expression(NULL);
- return NULL;
-
- case ESTRINGCONST:
- case ELABEL:
- return NULL;
-
- case EPRECOMP:
- CError_FATAL(948);
-
- default:
- CError_FATAL(951);
- return NULL;
- }
-}
-
-static void cse_block(COptBlock *block) {
- Statement *stmt;
- COptBlock *check;
- COptBlockList *scan;
- COptBlock *best;
- short i;
- SInt32 counter;
- UInt32 starttime;
-
- starttime = COS_GetTicks();
- counter = 0;
-
- while (1) {
- cse_invals = 0;
- currentblock = block;
- block->x1E = 1;
-
- for (stmt = block->stmt, i = block->x1C; i > 0; stmt = stmt->next, i--) {
- switch (stmt->type) {
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- mexpr = stmt->expr;
- cse_expression(mexpr);
- break;
- case ST_RETURN:
- mexpr = stmt->expr;
- if (mexpr)
- cse_expression(mexpr);
- break;
- }
- }
-
- i = 0;
- for (scan = block->blocks2; scan; scan = scan->next) {
- check = scan->block;
- if (!check->x1E && check->blocks && !check->blocks->next && check->blocks->block == block) {
- best = check;
- i++;
- }
- }
-
- if (i != 1)
- break;
-
- block = best;
- if (COS_GetTicks() > (starttime + 60)) {
- if (counter++ & 1) {
- if (CWDisplayLines(cparamblkptr->context, lines))
- CError_UserBreak();
- } else {
- if (CWDisplayLines(cparamblkptr->context, lines + 1))
- CError_UserBreak();
- }
- starttime = COS_GetTicks();
- }
-
- if (cse_invals)
- cse_cleanup();
- }
-
- cse_remove();
-}
-
-static void CSE(void) {
- COptBlock *block;
-
- for (block = basicblocks->next; block; block = block->next)
- block->x1E = 0;
-
- for (block = basicblocks->next; block; block = block->next) {
- if (!block->x1E) {
- short op;
-
- for (op = 0; op < MAXEXPR; op++)
- csenodes[op] = NULL;
-
- cselist = NULL;
- cse_found = 0;
- cse_block(block);
- freeoheap();
- }
- }
-}
-
-static short TestSetBit(short *set, short bit) {
- return set[bit >> 4] & bitmasks[bit & 15];
-}
-
-static void SetSetBit(short *set, short bit) {
- set[bit >> 4] |= bitmasks[bit & 15];
-}
-
-UInt32 RegAllocMask(short var) {
- COptBlock *block;
- UInt32 mask = 0;
-
- for (block = basicblocks; block; block = block->next) {
- if (TestSetBit(block->set1, var) || TestSetBit(block->set2, var))
- mask |= block->allocmask;
- }
-
- return mask;
-}
-
-void MarkRegAllocMask(short var, short bit, Boolean flag) {
- COptBlock *block;
- UInt32 mask = 1 << bit;
-
- if (flag) {
- for (block = basicblocks; block; block = block->next) {
- if (TestSetBit(block->set1, var) || TestSetBit(block->set2, var))
- block->allocmask |= mask;
- }
- } else {
- for (block = basicblocks; block; block = block->next) {
- block->allocmask |= mask;
- }
- }
-}
-
-static COptBlock *newblock(void) {
- COptBlock *block;
- short i;
- short max;
-
- block = lalloc(sizeof(COptBlock) + (setbytes * 2));
- block->x1E = 0;
- block->next = NULL;
- block->blocks = NULL;
- block->blocks2 = NULL;
- block->allocmask = 0;
- block->set1 = (short *) (((long) block) + sizeof(COptBlock));
- block->set2 = (short *) (((long) block) + setbytes + sizeof(COptBlock));
-
- for (i = 0, max = setbytes / 2; i < max; i++) {
- block->set1[i] = 0;
- block->set2[i] = 0;
- }
-
- return block;
-}
-
-static void MarkFollow(COptBlock *block) {
- COptBlockList *list;
-
-restart:
- block->x1E = 1;
- if ((list = block->blocks2)) {
- while (1) {
- if (!list->block->x1E) {
- if (!list->next) {
- block = list->block;
- goto restart;
- }
- MarkFollow(list->block);
- list = list->next;
- } else {
- list = list->next;
- if (!list)
- break;
- }
- }
- }
-}
-
-static Boolean CheckInit(short var) {
- Boolean result;
- COptBlock *block;
-
- result = 1;
- for (block = basicblocks; block; block = block->next) {
- if (!block->x1E && TestSetBit(block->set2, var))
- MarkFollow(block);
- }
-
- for (block = basicblocks; block; block = block->next) {
- if (!block->x1E) {
- if (TestSetBit(block->set1, var))
- result = 0;
- } else {
- block->x1E = 0;
- }
- }
-
- return result;
-}
-
-static void CheckVarInit(void) {
- COptBlock *block;
- VarInfo *vi;
- ObjectList *list;
-
- for (block = basicblocks; block; block = block->next)
- block->x1E = 0;
-
- for (list = locals; list; list = list->next) {
- if (list->object->datatype == DLOCAL && !IsTempName(list->object->name) && !is_volatile_object(list->object)) {
- vi = list->object->u.var.info;
- if (vi->used && !CheckInit(vi->varnumber)) {
- if (!IS_TYPE_CLASS(list->object->type) || !CClass_IsEmpty(TYPE_CLASS(list->object->type))) {
- CError_SetErrorToken(&vi->deftoken);
- CError_Warning(CErrorStr185, list->object->name->name);
- }
- }
- }
- }
-}
-
-static void AddVar(Object *obj, Boolean whichSet) {
- VarInfo *vi;
-
- if (obj->datatype == DLOCAL) {
- vi = obj->u.var.info;
- if (!whichSet) {
- SetSetBit(currentblock->set1, vi->varnumber);
- } else {
- if (!TestSetBit(currentblock->set1, vi->varnumber))
- SetSetBit(currentblock->set2, vi->varnumber);
- }
- }
-}
-
-static void CheckExpr(ENode *expr) {
- ENodeList *list;
-
- while (1) {
- switch (expr->type) {
- case EINDIRECT:
- if (ENODE_IS(expr->data.monadic, EOBJREF)) {
- AddVar(expr->data.monadic->data.objref, 0);
- return;
- }
- expr = expr->data.monadic;
- break;
- case EOBJREF:
- AddVar(expr->data.objref, 1);
- return;
- case EFUNCCALL:
- case EFUNCCALLP:
- CheckExpr(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- CheckExpr(list->node);
- return;
- case ECOND:
- CheckExpr(expr->data.cond.cond);
- CheckExpr(expr->data.cond.expr1);
- CheckExpr(expr->data.cond.expr2);
- return;
- case EASS:
- if (ENODE_IS_INDIRECT_TO(expr->data.diadic.left, EOBJREF)) {
- CheckExpr(expr->data.diadic.right);
- AddVar(expr->data.diadic.left->data.monadic->data.objref, 1);
- return;
- }
- 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 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:
- CheckExpr(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- break;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- break;
- case ENULLCHECK:
- CheckExpr(expr->data.nullcheck.nullcheckexpr);
- expr = expr->data.nullcheck.condexpr;
- break;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EPRECOMP:
- case ELABEL:
- case EVECTOR128CONST:
- return;
- default:
- CError_FATAL(1332);
- }
- }
-}
-
-static short CheckPath(COptBlock *block, short var) {
- COptBlockList *list;
-
- if (block->x1E)
- return TestSetBit(block->set1, var);
-
- block->x1E = 1;
- if (TestSetBit(block->set1, var))
- return -1;
- if (TestSetBit(block->set2, var))
- return 0;
-
- for (list = block->blocks2; list; list = list->next) {
- if (CheckPath(list->block, var)) {
- SetSetBit(block->set1, var);
- return -1;
- }
- }
-
- return 0;
-}
-
-static void MarkPre(COptBlock *block, short var) {
- COptBlockList *list;
-
-restart:
- block->x1E = 1;
- for (list = block->blocks; list; list = list->next) {
- if (!list->block->x1E) {
- if (!TestSetBit(list->block->set2, var)) {
- SetSetBit(list->block->set1, var);
- if (!list->next) {
- block = list->block;
- goto restart;
- }
- MarkPre(list->block, var);
- } else {
- list->block->x1E = 1;
- }
- }
- }
-}
-
-static void CheckVarUsage(void) {
- short local;
- COptBlock *block;
- short counter;
-
- for (currentblock = basicblocks; currentblock; currentblock = currentblock->next) {
- Statement *stmt = currentblock->stmt;
- if (currentblock->x1C > 0 && stmt->type == ST_LABEL && (stmt->flags & StmtFlag_1)) {
- short i;
- for (i = 0; i < localcount; i++)
- SetSetBit(currentblock->set2, i);
- }
-
- for (counter = currentblock->x1C; counter > 0; counter--) {
- if (stmt->type >= ST_EXPRESSION && stmt->type <= ST_GOTOEXPR && stmt->expr)
- CheckExpr(stmt->expr);
- stmt = stmt->next;
- }
- }
-
- for (local = 0; local < localcount; local++) {
- for (block = basicblocks; block; block = block->next) {
- if (!block->x1E && TestSetBit(block->set1, local))
- MarkPre(block, local);
- }
- for (block = basicblocks; block; block = block->next) {
- block->x1E = 0;
- }
- }
-}
-
-static void SplitCommaExpressions(void) {
- COptBlock *block;
- Statement *stmt;
- ENode *expr;
- Statement *stmtcopy;
- short counter;
- Boolean flag;
-
- block = basicblocks->next;
- while (block) {
- stmt = block->stmt;
- counter = block->x1C;
- flag = 1;
- while (counter > 0) {
- if (stmt->type >= ST_EXPRESSION && stmt->type <= ST_GOTOEXPR) {
- if ((expr = stmt->expr) && ENODE_IS(expr, ECOMMA)) {
- stmtcopy = lalloc(sizeof(Statement));
- *stmtcopy = *stmt;
- stmt->next = stmtcopy;
- stmt->type = ST_EXPRESSION;
- stmt->expr = expr->data.diadic.left;
- stmtcopy->expr = expr->data.diadic.right;
- block->x1C++;
- flag = 0;
- break;
- }
- }
-
- stmt = stmt->next;
- counter--;
- }
-
- if (flag)
- block = block->next;
- }
-}
-
-static void BasicBlockAnalyze(Statement *stmt) {
- COptBlock *block;
- ObjectList *objlist;
- COptBlockList *scan;
- COptBlockList *list;
- CLabel *label;
- COptBlock *iblock;
- COptBlock *oblock;
- SwitchCase *swcase;
-
- setbytes = 2 * ((localcount - 1) / 16) + 2;
- if (copts.globaloptimizer) {
- setbytes += 32;
- extravars = 0;
- }
-
- block = newblock();
- basicblocks = block;
- block->stmt = NULL;
- block->x1C = 0;
-
- if (stmt) {
- list = lalloc(sizeof(COptBlockList));
- list->next = NULL;
- block->blocks2 = list;
- list->block = (COptBlock *) stmt;
- }
-
- for (objlist = arguments; objlist; objlist = objlist->next) {
- SetSetBit(block->set2, objlist->object->u.var.info->varnumber);
- }
-
- while (stmt) {
- int counter;
-
- block->next = newblock();
- block = block->next;
- block->stmt = stmt;
- counter = 1;
-
- innerLoop:
- switch (stmt->type) {
- case ST_ASM:
- label = InlineAsm_GetReferencedLabel(stmt);
- if (!label)
- goto jumpahead;
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) label->stmt;
- if (stmt->next) {
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) stmt->next;
- }
- stmt = stmt->next;
- block->x1C = counter;
- continue;
- case ST_NOP:
- case ST_LABEL:
- case ST_ENTRY:
- if (stmt->next && stmt->next->type != ST_LABEL) {
- stmt = stmt->next;
- counter++;
- goto innerLoop;
- }
- break;
- case ST_EXPRESSION:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- jumpahead:
- if (stmt->next && stmt->next->type == ST_GOTO) {
- stmt = stmt->next;
- counter++;
- goto innerLoop;
- }
- break;
- }
-
- switch (stmt->type) {
- case ST_SWITCH:
- label = ((SwitchInfo *) stmt->label)->defaultlabel;
- if (label != cleanreturnlabel) {
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) label->stmt;
- }
- for (swcase = ((SwitchInfo *) stmt->label)->cases; swcase; swcase = swcase->next) {
- label = swcase->label;
- if (label != cleanreturnlabel) {
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) label->stmt;
- }
- }
- break;
- case ST_RETURN:
- case ST_EXIT:
- case ST_GOTOEXPR:
- break;
- case ST_GOTO:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_OVF:
- label = stmt->label;
- if (label != cleanreturnlabel) {
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) label->stmt;
- }
- if (stmt->type == ST_GOTO)
- break;
- default:
- if (stmt->next) {
- list = lalloc(sizeof(COptBlockList));
- list->next = block->blocks2;
- block->blocks2 = list;
- list->block = (COptBlock *) stmt->next;
- }
- break;
- }
-
- stmt = stmt->next;
- block->x1C = counter;
- }
-
- for (oblock = basicblocks; oblock; oblock = oblock->next) {
- for (scan = oblock->blocks2; scan; scan = scan->next) {
- stmt = (Statement *) scan->block;
- for (iblock = basicblocks->next; iblock; iblock = iblock->next) {
- if (iblock->stmt == stmt) {
- scan->block = iblock;
- list = lalloc(sizeof(COptBlockList));
- list->next = iblock->blocks;
- iblock->blocks = list;
- list->block = oblock;
- break;
- }
- }
-
- CError_ASSERT(1602, iblock);
- }
- }
-
- SplitCommaExpressions();
- CheckVarUsage();
-}
-
-static CLabel *finallabel(CLabel *label, Statement *stmt) {
- Statement *scan;
-
- for (scan = label->stmt; scan; scan = scan->next) {
- if (scan->type > ST_LABEL) {
- if (scan == stmt)
- return label;
- if (scan->type == ST_GOTO) {
- if (scan->label != label)
- stmtchanged = 1;
- return scan->label;
- }
- return label;
- }
- }
-
- return label;
-}
-
-static void optimizegoto(Statement *stmt) {
- Statement *scan;
-
- for (scan = stmt->next; scan; scan = scan->next) {
- if (stmt->label->stmt == scan) {
- stmt->type = ST_NOP;
- stmtchanged = 1;
- return;
- }
- if (scan->type > ST_LABEL)
- break;
- }
-
- stmt->label = finallabel(stmt->label, stmt);
-}
-
-static void removeif(Statement *stmt, Boolean flag) {
- if (((stmt->type == ST_IFGOTO) && flag) || ((stmt->type == ST_IFNGOTO) && !flag)) {
- Statement *copy = lalloc(sizeof(Statement));
- *copy = *stmt;
- copy->type = ST_GOTO;
- stmt->next = copy;
- }
- stmt->type = ST_EXPRESSION;
- stmtchanged = 1;
-}
-
-static void optimizeif(Statement *stmt) {
- Statement *scan;
- Statement *scan2;
- Boolean flag;
-
- if (iszero(stmt->expr)) {
- removeif(stmt, 0);
- return;
- }
- if (isnotzero(stmt->expr)) {
- removeif(stmt, 1);
- return;
- }
-
- for (scan = stmt->next, flag = 0; scan; scan = scan->next) {
- if (scan->type > ST_LABEL) {
- if (scan->type == ST_GOTO) {
- if (scan->label == stmt->label) {
- stmt->type = ST_EXPRESSION;
- stmtchanged = 1;
- return;
- }
-
- if (!flag) {
- for (scan2 = scan->next; scan2; scan2 = scan2->next) {
- if (scan2->type > ST_LABEL)
- break;
- if (stmt->label->stmt == scan2) {
- stmt->label = scan->label;
- scan->type = ST_NOP;
- if (stmt->type == ST_IFGOTO)
- stmt->type = ST_IFNGOTO;
- else
- stmt->type = ST_IFGOTO;
- stmtchanged = 1;
- stmt->label = finallabel(stmt->label, stmt);
- return;
- }
- }
- }
- } else if (scan->type == ST_RETURN && !scan->expr && !static_for_inlines && !flag) {
- for (scan2 = scan->next; scan2; scan2 = scan2->next) {
- if (scan2->type > ST_LABEL)
- break;
- if (stmt->label->stmt == scan2) {
- stmt->label = cleanreturnlabel;
- needs_cleanup = 1;
- scan->type = ST_NOP;
- if (stmt->type == ST_IFGOTO)
- stmt->type = ST_IFNGOTO;
- else
- stmt->type = ST_IFGOTO;
- stmtchanged = 1;
- return;
- }
- }
- }
- break;
- }
-
- if (scan->type == ST_LABEL)
- flag = 1;
-
- if (stmt->label->stmt == scan) {
- stmt->type = ST_EXPRESSION;
- stmtchanged = 1;
- return;
- }
- }
-
- stmt->label = finallabel(stmt->label, stmt);
-}
-
-static void optimizeswitch(Statement *stmt) {
- SwitchInfo *info;
- SwitchCase *swcase;
-
- info = (SwitchInfo *) stmt->label;
- CError_ASSERT(1746, info && info->cases && info->defaultlabel);
-
- info->defaultlabel = finallabel(info->defaultlabel, stmt);
- for (swcase = info->cases; swcase; swcase = swcase->next)
- swcase->label = finallabel(swcase->label, stmt);
-
- if (ENODE_IS(stmt->expr, EINTCONST)) {
- for (swcase = info->cases; swcase; swcase = swcase->next) {
- if (CInt64_GreaterEqual(swcase->min, stmt->expr->data.intval) && CInt64_LessEqual(swcase->max, stmt->expr->data.intval))
- break;
- }
-
- stmt->type = ST_GOTO;
- stmt->label = swcase ? swcase->label : info->defaultlabel;
- }
-}
-
-static void removeunusedlabels(Statement *stmt) {
- Statement *scan;
- CLabel *label;
- SwitchCase *swcase;
- ExceptionAction *action;
-
- for (scan = stmt; scan; scan = scan->next)
- scan->marked = 0;
-
- for (scan = stmt; scan; scan = scan->next) {
- switch (scan->type) {
- case ST_GOTO:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_OVF:
- if (scan->label->stmt)
- scan->label->stmt->marked = 1;
- break;
- case ST_SWITCH:
- ((SwitchInfo *) scan->label)->defaultlabel->stmt->marked = 1;
- for (swcase = ((SwitchInfo *) scan->label)->cases; swcase; swcase = swcase->next)
- swcase->label->stmt->marked = 1;
- break;
- case ST_ASM:
- if ((label = InlineAsm_GetReferencedLabel(scan)))
- label->stmt->marked = 1;
- if ((label = InlineAsm_GetReferencedLabel2(scan)))
- label->stmt->marked = 1;
- break;
- case ST_BEGINLOOP:
- ((LoopInfo *) scan->expr)->stmt->marked = 1;
- break;
- case ST_ENDLOOP:
- if (scan->next->type == ST_GOTO && scan->next->next->type == ST_LABEL)
- scan->next->next->marked = 1;
- break;
- default:
- for (action = scan->dobjstack; action; action = action->prev) {
- if (action->type == EAT_CATCHBLOCK) {
- action->data.catch_block.catch_label->stmt->marked = 1;
- action->data.catch_block.catch_label->stmt->flags = action->data.catch_block.catch_label->stmt->flags | StmtFlag_1;
- } else if (action->type == EAT_SPECIFICATION) {
- action->data.specification.unexp_label->stmt->marked = 1;
- action->data.specification.unexp_label->stmt->flags = action->data.specification.unexp_label->stmt->flags | StmtFlag_1;
- }
- }
- }
- }
-
- for (scan = stmt; scan; scan = scan->next) {
- if (scan->type == ST_LABEL && !scan->marked && !(scan->flags & StmtFlag_1)) {
- scan->type = ST_NOP;
- stmtchanged = 1;
- }
- }
-}
-
-static void optimizebranches(Statement *stmt) {
- removeunusedlabels(stmt);
- while (stmt) {
- switch (stmt->type) {
- case ST_GOTO:
- optimizegoto(stmt);
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- optimizeif(stmt);
- break;
- case ST_SWITCH:
- optimizeswitch(stmt);
- break;
- }
- stmt = stmt->next;
- }
-}
-
-void SetVarUsage(Object *obj, Boolean noregister) {
- VarInfo *vi;
- CError_ASSERT(1875, obj->datatype != DALIAS);
-
- if (obj->datatype == DLOCAL || obj->datatype == DNONLAZYPTR) {
- vi = obj->u.var.info;
- vi->used = 1;
- if (!copts.globaloptimizer) {
- if (copts.optimizesize)
- vi->usage++;
- else
- vi->usage += curstmtvalue;
- }
-
- if (noregister)
- vi->noregister = 1;
- }
-}
-
-static void checkexpression(ENode *expr) {
- ENodeList *list;
-
- while (1) {
- switch (expr->type) {
- case EOBJREF:
- SetVarUsage(expr->data.objref, 1);
- return;
- case EINDIRECT:
- if (ENODE_IS(expr->data.monadic, EOBJREF)) {
- SetVarUsage(expr->data.monadic->data.objref, 0);
- return;
- }
- expr = expr->data.monadic;
- break;
- case EFUNCCALL:
- case EFUNCCALLP:
- copt_isleaffunction = 0;
- checkexpression(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- checkexpression(list->node);
- return;
- case ECOND:
- case ECONDASS:
- checkexpression(expr->data.cond.cond);
- checkexpression(expr->data.cond.expr1);
- checkexpression(expr->data.cond.expr2);
- return;
- 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:
- checkexpression(expr->data.diadic.left);
- expr = expr->data.diadic.right;
- break;
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- case EFORCELOAD:
- case ETYPCON:
- case EBITFIELD:
- expr = expr->data.monadic;
- break;
- case ENULLCHECK:
- checkexpression(expr->data.nullcheck.nullcheckexpr);
- expr = expr->data.nullcheck.condexpr;
- break;
- case EINTCONST:
- case EFLOATCONST:
- case EPRECOMP:
- case ELABEL:
- case EVECTOR128CONST:
- return;
- case ESTRINGCONST:
- return;
- default:
- CError_FATAL(1998);
- }
- }
-}
-
-static void checklocalusage(Statement *stmt) {
- Statement *scan;
-
- for (scan = stmt; scan; scan = scan->next) {
- if (scan->type >= ST_EXPRESSION && scan->type <= ST_GOTOEXPR && scan->expr) {
- curstmtvalue = scan->value;
- checkexpression(scan->expr);
- } else if (scan->type == ST_ASM) {
- curstmtvalue = scan->value;
- InlineAsm_CheckLocalUsage(scan);
- }
- }
-}
-
-static void colorcode(Statement *stmt) {
- CLabel *label;
- SwitchCase *swcase;
-
- while (stmt && !stmt->marked) {
- stmt->marked = 1;
- switch (stmt->type) {
- case ST_GOTOEXPR:
- return;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_OVF:
- colorcode(stmt->label->stmt);
- break;
- case ST_GOTO:
- case ST_EXIT:
- stmt = stmt->label->stmt;
- continue;
- case ST_RETURN:
- return;
- case ST_SWITCH:
- for (swcase = ((SwitchInfo *) stmt->label)->cases; swcase; swcase = swcase->next)
- colorcode(swcase->label->stmt);
- stmt = ((SwitchInfo *) stmt->label)->defaultlabel->stmt;
- continue;
- case ST_ASM:
- if ((label = InlineAsm_GetReferencedLabel(stmt)))
- colorcode(label->stmt);
- if ((label = InlineAsm_GetReferencedLabel2(stmt)))
- colorcode(label->stmt);
- break;
- case ST_ENDLOOP:
- if (stmt->next && stmt->next->type == ST_GOTO) {
- stmt = stmt->next;
- stmt->marked = 1;
- }
- break;
- case ST_NOP:
- case ST_LABEL:
- case ST_EXPRESSION:
- case ST_ENTRY:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- case ST_BEGINLOOP:
- break;
- default:
- CError_FATAL(2096);
- }
- stmt = stmt->next;
- }
-}
-
-static void removeunusedcode(Statement *stmt) {
- Statement *scan;
-
- for (scan = stmt; scan; scan = scan->next)
- scan->marked = 0;
-
- colorcode(stmt);
- for (scan = stmt; scan; scan = scan->next) {
- if (!scan->marked && (scan->flags & StmtFlag_1))
- colorcode(scan);
- }
-
- for (scan = stmt; scan; scan = scan->next) {
- if (!scan->marked && scan->type != ST_NOP) {
- scan->type = ST_NOP;
- stmtchanged = 1;
- }
- }
-}
-
-static void COpt_ReturnCheck(Object *obj, Statement *stmt) {
- if ((copts.pedantic || copts.cplusplus) && obj && TYPE_FUNC(obj->type)->functype != &stvoid) {
- while (stmt) {
- if (!stmt->next && stmt->type != ST_GOTO && stmt->type != ST_RETURN) {
- CError_Warning(CErrorStr184);
- break;
- }
-
- if (stmt->type == ST_RETURN && !stmt->expr && !(stmt->flags & StmtFlag_8)) {
- CError_Warning(CErrorStr184);
- break;
- }
-
- stmt = stmt->next;
- }
- }
-}
-
-static void COpt_Optimize(Object *obj, Statement *stmt) {
- Statement **ptr;
-
- do {
- stmtchanged = 0;
- optimizebranches(stmt->next);
- removeunusedcode(stmt->next);
- } while (stmtchanged);
-
- ptr = &stmt->next;
- while (*ptr) {
- if ((*ptr)->type == ST_NOP)
- *ptr = (*ptr)->next;
- else
- ptr = &(*ptr)->next;
- }
-}
-
-static void COpt_ELABELCallBack(ENode *expr) {
- CError_ASSERT(2195, expr->data.label->stmt && expr->data.label->stmt->type == ST_LABEL);
- expr->data.label->stmt->flags = expr->data.label->stmt->flags | StmtFlag_1;
-}
-
-void COpt_SimpleOptimizer(Object *obj, Statement *stmt) {
- Statement *scan;
-
- for (scan = stmt; scan; scan = scan->next) {
- if ((scan->type >= ST_EXPRESSION && scan->type <= ST_GOTOEXPR) && scan->expr)
- CExpr_SearchExprTree(scan->expr, COpt_ELABELCallBack, 1, ELABEL);
- }
-
- static_for_inlines = 1;
- cleanreturnlabel = NULL;
- COpt_Optimize(obj, stmt);
- COpt_ReturnCheck(obj, stmt);
-}
-
-Statement *COpt_Optimizer(Object *obj, Statement *stmt) {
- copt_isleaffunction = 1;
- if (copts.globaloptimizer)
- stmt = IRO_Optimizer(obj, stmt);
-
- static_for_inlines = 0;
- COpt_Optimize(obj, stmt);
-
- if (obj && !(obj->qual & Q_INLINE))
- COpt_ReturnCheck(obj, stmt);
-
- checklocalusage(stmt->next);
- return stmt;
-}
diff --git a/compiler_and_linker/unsorted/CParser.c b/compiler_and_linker/unsorted/CParser.c
deleted file mode 100644
index e53b0bf..0000000
--- a/compiler_and_linker/unsorted/CParser.c
+++ /dev/null
@@ -1,3477 +0,0 @@
-#include "compiler/CParser.h"
-#include "compiler/CABI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CIRTransform.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CObjC.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/IrOptimizer.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "cos.h"
-
-FileOffsetInfo cparser_fileoffset;
-TStreamElement symdecltoken;
-ParserTryBlock *trychain;
-Boolean inassembler;
-Boolean dont_set_references;
-TypeStruct ptmstruct;
-TypeStruct catchinfostruct;
-Boolean in_assembler;
-Boolean illegalimplicitconversion;
-Boolean in_func_arglist;
-NameSpaceName *newp_fobj;
-NameSpaceName *newa_fobj;
-NameSpaceName *delp_fobj;
-NameSpaceName *dela_fobj;
-Object *newh_func;
-Object *delh_func;
-Object *copy_func;
-Object *clear_func;
-Object *Rgtid_func;
-Object *Rdync_func;
-Object *rt_ptmf_cast;
-Object *rt_ptmf_cmpr;
-Object *rt_ptmf_test;
-Object *rt_ptmf_call;
-Object *rt_ptmf_scall;
-Object *rt_ptmf_call4;
-Object *rt_ptmf_scall4;
-Object *rt_ptmf_null;
-Object *rt_som_new;
-Object *rt_som_newcheck;
-Object *rt_som_check;
-Object *rt_som_glue1;
-Object *rt_som_glue2;
-Object *rt_som_glue3;
-Object *carr_func;
-Object *cnar_func;
-Object *darr_func;
-Object *dnar_func;
-Object *dnar3_func;
-Object *Xgreg_func;
-Object *Xthrw_func;
-Object *Xicth_func;
-Object *Xecth_func;
-Object *Xunex_func;
-CompilerLinkerOptions copts;
-GList name_mangle_list;
-HashNameNode *no_name_node;
-HashNameNode *temp_argument_name;
-HashNameNode *this_name_node;
-HashNameNode *self_name_node;
-HashNameNode *vptr_name_node;
-CallbackAction *callbackactions;
-Boolean fatalerrors;
-Boolean anyerrors;
-jmp_buf errorreturn;
-static HashNameNode *uniquenamespacename;
-static SInt32 uniqueid;
-
-struct ClassAction {
- struct ClassAction *next;
- TypeClass *tclass;
-};
-static struct ClassAction *cparser_classactions;
-
-struct ParentCleanup {
- struct ParentCleanup *next;
- TypeClass *tclass;
-};
-static struct ParentCleanup *cparser_parentcleanup;
-
-struct SFuncList {
- struct SFuncList *next;
- Object *func;
- Object *obj;
- ENode *expr;
-};
-static struct SFuncList *cparser_sfunclist;
-
-char string[256];
-SInt32 compilererrornum;
-SInt32 compilererrfile;
-SInt32 compilererrline;
-
-Type sttemplexpr = {TYPETEMPLDEPEXPR, 0};
-Type stillegal = {TYPEILLEGAL, 1};
-Type stvoid = {TYPEVOID, 0};
-TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0};
-TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0};
-
-// forward declarations
-static void CParser_ParseDeclaration(DeclInfo *di);
-
-Object *CParser_NewRTFunc(Type *rettype, HashNameNode *name, Boolean flag, int argcount, ...) {
- Object *obj;
- FuncArg *args;
- FuncArg *arg;
- TypeFunc *tfunc;
- va_list va;
-
- args = NULL;
- if (argcount) {
- va_start(va, argcount);
- while (--argcount >= 0) {
- if (args) {
- arg->next = CParser_NewFuncArg();
- arg = arg->next;
- } else {
- arg = CParser_NewFuncArg();
- args = arg;
- }
- arg->type = va_arg(va, Type *);
- }
- va_end(va);
- }
-
- obj = CParser_NewFunctionObject(NULL);
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = rettype;
- tfunc->args = args;
- CDecl_SetFuncFlags(tfunc, 0);
-
- obj->name = name;
- obj->type = TYPE(tfunc);
- if (flag == 1)
- obj->qual = Q_MANGLE_NAME;
-
- return obj;
-}
-
-Boolean CParser_IsPublicRuntimeObject(Object *obj) {
- if (newp_fobj->first.object == OBJ_BASE(obj) && !newp_fobj->first.next)
- return 1;
- if (newa_fobj->first.object == OBJ_BASE(obj) && !newa_fobj->first.next)
- return 1;
- if (delp_fobj->first.object == OBJ_BASE(obj) && !delp_fobj->first.next)
- return 1;
- if (dela_fobj->first.object == OBJ_BASE(obj) && !dela_fobj->first.next)
- return 1;
- return CodeGen_IsPublicRuntimeObject(obj);
-}
-
-Object *CParser_FindPublicRuntimeObject(HashNameNode *name) {
- NameSpaceObjectList *list = CScope_FindName(cscope_root, name);
- if (list && list->object->otype == OT_OBJECT && (!list->next || list->next->object->otype == OT_TYPETAG))
- return OBJECT(list->object);
- else
- return NULL;
-}
-
-Boolean CParser_ReInitRuntimeObjects(Boolean is_precompiler) {
- if (!(newp_fobj = CScope_FindNameSpaceName(cscope_root, CMangler_OperatorName(TK_NEW))))
- return 0;
- if (!(newa_fobj = CScope_FindNameSpaceName(cscope_root, CMangler_OperatorName(TK_NEW_ARRAY))))
- return 0;
- if (!(delp_fobj = CScope_FindNameSpaceName(cscope_root, CMangler_OperatorName(TK_DELETE))))
- return 0;
- if (!(dela_fobj = CScope_FindNameSpaceName(cscope_root, CMangler_OperatorName(TK_DELETE_ARRAY))))
- return 0;
-
- newh_func->name = GetHashNameNodeExport("__new_hdl");
- delh_func->name = GetHashNameNodeExport("__del_hdl");
- copy_func->name = GetHashNameNodeExport("__copy");
- clear_func->name = GetHashNameNodeExport("__clear");
- Rgtid_func->name = GetHashNameNodeExport("__get_typeid");
- Rdync_func->name = GetHashNameNodeExport("__dynamic_cast");
- rt_ptmf_cast->name = GetHashNameNodeExport("__ptmf_cast");
- rt_ptmf_cmpr->name = GetHashNameNodeExport("__ptmf_cmpr");
- rt_ptmf_test->name = GetHashNameNodeExport("__ptmf_test");
- rt_ptmf_call->name = GetHashNameNodeExport("__ptmf_call");
- rt_ptmf_scall->name = GetHashNameNodeExport("__ptmf_scall");
- rt_ptmf_call4->name = GetHashNameNodeExport("__ptmf_call4");
- rt_ptmf_scall4->name = GetHashNameNodeExport("__ptmf_scall4");
- rt_ptmf_null->name = GetHashNameNodeExport("__ptmf_null");
- rt_som_new->name = GetHashNameNodeExport("__som_new");
- rt_som_newcheck->name = GetHashNameNodeExport("__som_check_new");
- rt_som_check->name = GetHashNameNodeExport("__som_check_ev");
- rt_som_glue1->name = GetHashNameNodeExport("_som_ptrgl4");
- rt_som_glue2->name = GetHashNameNodeExport("_som_ptrgl5");
- rt_som_glue3->name = GetHashNameNodeExport("_som_ptrgl_");
- carr_func->name = GetHashNameNodeExport("__construct_array");
- cnar_func->name = GetHashNameNodeExport("__construct_new_array");
- darr_func->name = GetHashNameNodeExport("__destroy_arr");
- dnar_func->name = GetHashNameNodeExport("__destroy_new_array");
- dnar3_func->name = GetHashNameNodeExport("__destroy_new_array3");
- Xgreg_func->name = GetHashNameNodeExport("__register_global_object");
- Xthrw_func->name = GetHashNameNodeExport("__throw");
- Xicth_func->name = GetHashNameNodeExport("__init__catch");
- Xecth_func->name = GetHashNameNodeExport("__end__catch");
- Xunex_func->name = GetHashNameNodeExport("__unexpected");
-
- CMangler_Setup();
-
- no_name_node = GetHashNameNodeExport("@no_name@");
- temp_argument_name = GetHashNameNodeExport("@temp_ptr@");
- this_name_node = GetHashNameNodeExport("this");
- self_name_node = GetHashNameNodeExport("self");
- vptr_name_node = GetHashNameNodeExport("__vptr$");
-
- CSOM_Setup(is_precompiler);
- return CodeGen_ReInitRuntimeObjects(is_precompiler);
-}
-
-static void CParser_SetupRuntimeObjects(void) {
- ExceptSpecList *exspecs;
- Type *sizet;
- Object *func;
-
- exspecs = galloc(sizeof(ExceptSpecList));
- memclrw(exspecs, sizeof(ExceptSpecList));
-
- sizet = CABI_GetSizeTType();
-
- func = CParser_NewRTFunc(
- TYPE(&void_ptr), CMangler_OperatorName(TK_NEW), 1,
- 1, sizet);
- CScope_AddGlobalObject(func);
-
- func = CParser_NewRTFunc(
- TYPE(&void_ptr), CMangler_OperatorName(TK_NEW_ARRAY), 1,
- 1, sizet);
- CScope_AddGlobalObject(func);
-
- func = CParser_NewRTFunc(
- TYPE(&stvoid), CMangler_OperatorName(TK_DELETE), 1,
- 1, &void_ptr);
- CError_ASSERT(379, IS_TYPE_FUNC(func->type));
- TYPE_FUNC(func->type)->exspecs = exspecs;
- CScope_AddGlobalObject(func);
-
- func = CParser_NewRTFunc(
- TYPE(&stvoid), CMangler_OperatorName(TK_DELETE_ARRAY), 1,
- 1, &void_ptr);
- CError_ASSERT(387, IS_TYPE_FUNC(func->type));
- TYPE_FUNC(func->type)->exspecs = exspecs;
- CScope_AddGlobalObject(func);
-
- newh_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 0,
- 1, sizet);
- delh_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
-
- Rgtid_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 0,
- 2, &void_ptr, &stsignedlong);
- Rdync_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 0,
- 5, &void_ptr, &stsignedlong, &void_ptr, &void_ptr, &stsignedshort);
-
- copy_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 2,
- 3, &void_ptr, &void_ptr, sizet);
- clear_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 2,
- 2, &void_ptr, sizet);
-
- rt_ptmf_cast = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 2,
- 3, &stsignedlong, &void_ptr, &void_ptr);
- rt_ptmf_cmpr = CParser_NewRTFunc(
- TYPE(&stsignedlong), NULL, 2,
- 2, &void_ptr, &void_ptr);
- rt_ptmf_test = CParser_NewRTFunc(
- TYPE(&stsignedlong), NULL, 2,
- 1, &void_ptr);
-
- rt_ptmf_call = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
- rt_ptmf_scall = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
- rt_ptmf_call4 = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
- rt_ptmf_scall4 = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
-
- rt_ptmf_null = CParser_NewGlobalDataObject(NULL);
- rt_ptmf_null->type = &stvoid;
-
- rt_som_new = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 2,
- 3, &void_ptr, &stsignedlong, &stsignedlong);
- rt_som_newcheck = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
- rt_som_check = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
- rt_som_glue1 = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
- rt_som_glue2 = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
- rt_som_glue3 = CParser_NewRTFunc(TYPE(&stvoid), NULL, 2, 0);
-
- carr_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 5, &void_ptr, &void_ptr, &void_ptr, sizet, sizet);
- cnar_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 0,
- 5, &void_ptr, &void_ptr, &void_ptr, sizet, sizet);
- darr_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 4, &void_ptr, &void_ptr, sizet, sizet);
- dnar_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 2, &void_ptr, &void_ptr);
- dnar3_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 4, &void_ptr, &void_ptr, &void_ptr, &stsignedshort);
-
- Xgreg_func = CParser_NewRTFunc(
- TYPE(&void_ptr), NULL, 0,
- 3, &void_ptr, &void_ptr, &void_ptr);
- Xthrw_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 3, &void_ptr, &void_ptr, &void_ptr);
- Xicth_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
- Xecth_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
- Xunex_func = CParser_NewRTFunc(
- TYPE(&stvoid), NULL, 0,
- 1, &void_ptr);
-
- CodeGen_SetupRuntimeObjects();
- CError_ASSERT(534, CParser_ReInitRuntimeObjects(0));
-}
-
-void CParser_Setup(void) {
- CScope_Setup();
-
- name_mangle_list.data = NULL;
- if (InitGList(&name_mangle_list, 256))
- CError_NoMem();
-
- void_ptr.size = 4;
- CError_Init();
- CInit_Init();
- CClass_Init();
- CIRTrans_Setup();
- CObjC_Setup();
- CInline_Init();
-
- in_assembler = 0;
- in_func_arglist = 0;
- CParser_SetUniqueID(1);
- dont_set_references = 0;
-
- copts.sideeffects = 1;
- cparser_classactions = NULL;
- name_obj_check = NULL;
- callbackactions = NULL;
- init_expressions = NULL;
- cparser_sfunclist = NULL;
- trychain = NULL;
- cparser_parentcleanup = NULL;
-
- memclrw(&cparser_fileoffset, sizeof(FileOffsetInfo));
-
- memclrw(&catchinfostruct, sizeof(TypeStruct));
- catchinfostruct.type = TYPESTRUCT;
- catchinfostruct.size = 24;
- catchinfostruct.stype = STRUCT_TYPE_STRUCT;
- catchinfostruct.align = 4;
-
- memclrw(&ptmstruct, sizeof(TypeStruct));
- ptmstruct.type = TYPESTRUCT;
- ptmstruct.size = 12;
- ptmstruct.stype = STRUCT_TYPE_STRUCT;
- ptmstruct.align = 4;
-
- CMach_Configure();
- CTempl_Setup();
-
- uniquenamespacename = NULL;
- disallowgreaterthan = 0;
-
- CParser_SetupRuntimeObjects();
-}
-
-void CParser_Cleanup(void) {
- CTempl_Cleanup();
- CIRTrans_Cleanup();
- CObjC_Cleanup();
- CScope_Cleanup();
- FreeGList(&name_mangle_list);
-}
-
-short GetPrec(short token) {
- switch (token) {
- case '%':
- case '*':
- case '/':
- return 11;
- case '+':
- case '-':
- return 10;
- case TK_SHL:
- case TK_SHR:
- return 9;
- case '<':
- case '>':
- case TK_LESS_EQUAL:
- case TK_GREATER_EQUAL:
- return 8;
- case TK_LOGICAL_EQ:
- case TK_LOGICAL_NE:
- return 7;
- case '&':
- return 6;
- case '^':
- return 5;
- case '|':
- return 4;
- case TK_LOGICAL_AND:
- return 3;
- case TK_LOGICAL_OR:
- return 2;
- default:
- return 0;
- }
-}
-
-Boolean CParser_ParseOperatorName(short *token, Boolean flag1, Boolean flag2) {
- HashNameNode *name;
-
- switch ((tk = lex())) {
- case TK_NEW:
- case TK_DELETE:
- if (lookahead() == '[') {
- lex();
- if (lex() != ']')
- CError_Error(CErrorStr125);
- //if (tk == TK_NEW)
- // tk = TK_NEW_ARRAY;
- //else
- // tk = TK_DELETE_ARRAY;
- tk = (tk == TK_NEW) ? TK_NEW_ARRAY : TK_DELETE_ARRAY;
- }
- break;
- case '(':
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr204);
- return 0;
- }
- tk = '(';
- break;
- case '[':
- if ((tk = lex()) != ']') {
- CError_Error(CErrorStr204);
- return 0;
- }
- tk = '[';
- break;
- }
-
- if ((name = CMangler_OperatorName(tk))) {
- if (token)
- *token = tk;
- tk = lex();
- tkidentifier = name;
- return 1;
- }
-
- if (flag1) {
- if (flag2) {
- DeclInfo declinfo;
- memclrw(&declinfo, sizeof(DeclInfo));
- conversion_type_name(&declinfo);
- tkidentifier = CMangler_ConversionFuncName(declinfo.thetype, declinfo.qual);
- }
- if (token)
- *token = 0;
- return 1;
- } else {
- CError_Error(CErrorStr204);
- return 0;
- }
-}
-
-SInt32 CParser_GetUniqueID(void) {
- return uniqueid++;
-}
-
-void CParser_PrintUniqueID(char *buf) {
- SInt32 id;
- char mybuf[16];
- char *ptr;
-
- ptr = mybuf;
- id = CParser_GetUniqueID();
- while (id) {
- *(ptr++) = '0' + (id - ((id / 10) * 10));
- id = id / 10;
- }
-
- while (ptr > mybuf)
- *(buf++) = *(--ptr);
-
- *buf = 0;
-}
-
-void CParser_SetUniqueID(SInt32 id) {
- uniqueid = id;
-}
-
-HashNameNode *CParser_GetUniqueName(void) {
- char buf[20];
- buf[0] = '@';
- CParser_PrintUniqueID(buf + 1);
- return GetHashNameNodeExport(buf);
-}
-
-HashNameNode *CParser_NameConcat(const char *a, const char *b) {
- char mybuf[256];
- char *buf;
- char *dst;
- int len;
-
- len = strlen(a) + strlen(b);
- if (len > (sizeof(mybuf) - 1)) {
- buf = lalloc(len + 1);
- dst = buf;
- } else {
- buf = mybuf;
- dst = buf;
- }
-
- while (*a)
- *(dst++) = *(a++);
- while (*b)
- *(dst++) = *(b++);
- *dst = 0;
-
- return GetHashNameNodeExport(buf);
-}
-
-HashNameNode *CParser_AppendUniqueName(char *prefix) {
- char buf[256];
- char *dst;
- int i;
-
- dst = buf;
- for (i = 0; *prefix && i < 240; i++) {
- *(dst++) = *(prefix++);
- }
- *(dst++) = '$';
-
- CParser_PrintUniqueID(dst);
- return GetHashNameNodeExport(buf);
-}
-
-HashNameNode *CParser_AppendUniqueNameFile(char *prefix) {
- Str255 filename;
- char buf[256];
- char *src;
- char *dst;
- char c;
- int i;
- int j;
- int len;
-
- dst = buf;
- for (i = 0; *prefix && i < 200; i++) {
- *(dst++) = *(prefix++);
- }
- *(dst++) = '$';
-
- CParser_PrintUniqueID(dst);
-
- while (*dst) {
- dst++;
- i++;
- }
-
- COS_FileGetFSSpecInfo(&cparamblkptr->sourcefile, NULL, NULL, filename);
- src = (char *) &filename[1];
- len = filename[0];
- for (j = 0; j < len && i < 255; j++, i++) {
- c = *(src++);
- if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9'))
- c = '_';
- *(dst++) = c;
- }
-
- dst[0] = 0;
- return GetHashNameNodeExport(buf);
-}
-
-static HashNameNode *CParser_GetUnnamedNameSpaceName(void) {
- Str255 filename;
- char buf[256];
- char *src;
- char *dst;
- char c;
- int i;
- int len;
-
- if (!uniquenamespacename) {
- strcpy(buf, "@unnamed@");
- dst = buf + strlen(buf);
-
- COS_FileGetFSSpecInfo(&cparamblkptr->sourcefile, NULL, NULL, filename);
- src = (char *) &filename[1];
- len = filename[0];
- for (i = 0; i < len && dst < &buf[254]; i++) {
- c = *(src++);
- if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9'))
- c = '_';
- *(dst++) = c;
- }
-
- dst[0] = '@';
- dst[1] = 0;
- uniquenamespacename = GetHashNameNodeExport(buf);
- }
-
- return uniquenamespacename;
-}
-
-Boolean IsTempName(HashNameNode *name) {
- return !name || (name->name[0] == '@') || (name->name[0] == '$');
-}
-
-static void CParser_SetCFMFlags(Object *object, DeclInfo *declinfo) {
- if (declinfo && declinfo->exportflags)
- object->flags |= declinfo->exportflags;
-
- if (object->datatype == DDATA) {
- if (copts.cfm_export)
- object->flags = object->flags | OBJECT_EXPORT;
- if (copts.cfm_internal)
- object->flags = object->flags | OBJECT_INTERNAL;
- } else if (copts.cfm_internal) {
- object->flags = object->flags | OBJECT_INTERNAL;
- } else {
- if (copts.cfm_import)
- object->flags = object->flags | OBJECT_IMPORT;
- if (copts.cfm_export)
- object->flags = object->flags | OBJECT_EXPORT;
- if (copts.cfm_lib_export)
- object->flags = object->flags | OBJECT_IMPORT | OBJECT_EXPORT;
- }
-}
-
-void CParser_UpdateObject(Object *object, DeclInfo *declinfo) {
- if (declinfo && declinfo->section)
- object->section = declinfo->section;
-
- CParser_SetCFMFlags(object, declinfo);
- CodeGen_UpdateObject(object);
-}
-
-Object *CParser_NewObject(DeclInfo *declinfo) {
- Object *object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- CParser_SetCFMFlags(object, declinfo);
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->section = SECT_DEFAULT;
- return object;
-}
-
-Object *CParser_NewLocalDataObject(DeclInfo *declinfo, Boolean add_to_locals) {
- Object *object = lalloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->datatype = DLOCAL;
-
- if (declinfo) {
- object->type = declinfo->thetype;
- object->name = declinfo->name;
- object->qual = declinfo->qual;
- object->sclass = declinfo->storageclass;
- }
-
- if (add_to_locals) {
- ObjectList *list = lalloc(sizeof(ObjectList));
- list->object = object;
- list->next = locals;
- locals = list;
- }
-
- return object;
-}
-
-Object *CParser_NewGlobalDataObject(DeclInfo *declinfo) {
- Object *object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->section = SECT_DEFAULT;
- object->datatype = DDATA;
- object->nspace = cscope_current;
-
- if (declinfo) {
- object->type = declinfo->thetype;
- object->name = declinfo->name;
- object->qual = declinfo->qual;
- object->sclass = declinfo->storageclass;
- if (copts.cplusplus && !declinfo->is_extern_c)
- object->qual |= Q_MANGLE_NAME;
- }
-
- CParser_UpdateObject(object, declinfo);
- return object;
-}
-
-Object *CParser_NewCompilerDefDataObject(void) {
- Object *object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->section = SECT_DEFAULT;
- object->datatype = DDATA;
- object->nspace = cscope_root;
-
- return object;
-}
-
-Object *CParser_NewFunctionObject(DeclInfo *declinfo) {
- Object *object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->section = SECT_DEFAULT;
- object->datatype = DFUNC;
- object->nspace = cscope_current;
-
- if (declinfo) {
- object->type = declinfo->thetype;
- object->name = declinfo->name;
- object->qual = declinfo->qual;
- object->sclass = declinfo->storageclass;
- if (copts.cplusplus && !declinfo->is_extern_c)
- object->qual |= Q_MANGLE_NAME;
- }
-
- CParser_UpdateObject(object, declinfo);
- return object;
-}
-
-Object *CParser_NewCompilerDefFunctionObject(void) {
- Object *object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->section = SECT_DEFAULT;
- object->datatype = DFUNC;
- object->nspace = cscope_root;
- return object;
-}
-
-Object *CParser_NewAliasObject(Object *object, SInt32 offset) {
- Object *alias = galloc(sizeof(Object));
- *alias = *object;
- alias->datatype = DALIAS;
- alias->u.alias.object = object;
- alias->u.alias.member = NULL;
- alias->u.alias.offset = offset;
- CScope_AddObject(cscope_current, alias->name, OBJ_BASE(alias));
- return alias;
-}
-
-FuncArg *CParser_NewFuncArg(void) {
- FuncArg *arg = galloc(sizeof(FuncArg));
- memclrw(arg, sizeof(FuncArg));
- return arg;
-}
-
-Type *atomtype(void) {
- switch (tksize) {
- default:
- CError_FATAL(1145);
- case ATOM_VOID: return &stvoid;
- case ATOM_CHAR: return TYPE(&stchar);
- case ATOM_WCHAR: return TYPE(&stwchar);
- case ATOM_UCHAR: return TYPE(&stunsignedchar);
- case ATOM_SHORT: return TYPE(&stsignedshort);
- case ATOM_USHORT: return TYPE(&stunsignedshort);
- case ATOM_INT: return TYPE(&stsignedint);
- case ATOM_UINT: return TYPE(&stunsignedint);
- case ATOM_LONG: return TYPE(&stsignedlong);
- case ATOM_ULONG: return TYPE(&stunsignedlong);
- case ATOM_LONGLONG: return TYPE(&stsignedlonglong);
- case ATOM_ULONGLONG: return TYPE(&stunsignedlonglong);
- case ATOM_FLOAT: return TYPE(&stfloat);
- case ATOM_SHORTDOUBLE: return TYPE(&stshortdouble);
- case ATOM_DOUBLE: return TYPE(&stdouble);
- case ATOM_LONGDOUBLE: return TYPE(&stlongdouble);
- }
-}
-
-Object *CParser_FindDeallocationObject(Type *type, FuncArg *args, Boolean flag1, Boolean flag2, Boolean *outflag) {
- NameSpaceObjectList *list;
- NameSpaceObjectList *scan;
- NameSpaceObjectList mylist;
- NameResult pr;
- Boolean first_time;
- Boolean retry_flag;
- Object *obj;
- Type *sizet;
-
- list = NULL;
- *outflag = 0;
- if (IS_TYPE_CLASS(type) && !flag2) {
- HashNameNode *name;
- name = (flag1 && copts.array_new_delete) ? dela_fobj->name : delp_fobj->name;
- if (CScope_FindClassMemberObject(TYPE_CLASS(type), &pr, name)) {
- if (pr.obj_10) {
- mylist.next = NULL;
- mylist.object = pr.obj_10;
- list = &mylist;
- } else {
- CError_ASSERT(1202, pr.nsol_14);
- list = pr.nsol_14;
- }
- } else if (TYPE_CLASS(type)->flags & CLASS_HANDLEOBJECT) {
- CError_ASSERT(1210, !args && !flag1);
- return delh_func;
- }
- }
-
- first_time = 1;
- retry_flag = flag1;
- while (1) {
- if (!args) {
- for (scan = list; scan; scan = scan->next) {
- obj = OBJECT(scan->object);
- if (
- obj->otype == OT_OBJECT &&
- IS_TYPE_FUNC(obj->type) &&
- TYPE_FUNC(obj->type)->args &&
- !TYPE_FUNC(obj->type)->args->next &&
- is_typesame(TYPE_FUNC(obj->type)->args->type, TYPE(&void_ptr))
- )
- return obj;
- }
-
- CError_ASSERT(1231, first_time);
-
- sizet = CABI_GetSizeTType();
- for (scan = list; scan; scan = scan->next) {
- obj = OBJECT(scan->object);
- if (
- obj->otype == OT_OBJECT &&
- IS_TYPE_FUNC(obj->type) &&
- TYPE_FUNC(obj->type)->args &&
- TYPE_FUNC(obj->type)->args->next &&
- !TYPE_FUNC(obj->type)->args->next->next &&
- is_typesame(TYPE_FUNC(obj->type)->args->type, TYPE(&void_ptr)) &&
- TYPE_FUNC(obj->type)->args->next->type == sizet
- ) {
- *outflag = 1;
- return obj;
- }
- }
- } else {
- for (scan = list; scan; scan = scan->next) {
- obj = OBJECT(scan->object);
- if (
- obj->otype == OT_OBJECT &&
- IS_TYPE_FUNC(obj->type) &&
- TYPE_FUNC(obj->type)->args &&
- TYPE_FUNC(obj->type)->args->next &&
- is_arglistsame(TYPE_FUNC(obj->type)->args->next, args)
- ) {
- *outflag = 1;
- return obj;
- }
- }
-
- if (!first_time)
- return NULL;
- }
-
- if (list)
- CError_Warning(CErrorStr375, type, 0);
-
- list = (retry_flag && copts.array_new_delete) ? &dela_fobj->first : &delp_fobj->first;
- first_time = 0;
- }
-}
-
-static Boolean oldstylecompatible(FuncArg *arg) {
- if (copts.ignore_oldstyle)
- return 1;
-
- while (arg) {
- if (arg == &elipsis)
- return 0;
- switch (arg->type->type) {
- case TYPEINT:
- if (TYPE_INTEGRAL(arg->type)->integral < IT_INT)
- return 0;
- break;
- case TYPEFLOAT:
- if (TYPE_INTEGRAL(arg->type)->integral < IT_DOUBLE)
- return 0;
- break;
- }
- arg = arg->next;
- }
-
- return 1;
-}
-
-static Boolean is_arglistequal(FuncArg *a, FuncArg *b) {
- if (a == &oldstyle) {
- if (b == &oldstyle)
- return 1;
- else
- return oldstylecompatible(b);
- } else {
- if (b == &oldstyle)
- return oldstylecompatible(a);
- }
-
- while (1) {
- if (a == &elipsis || b == &elipsis)
- return 1;
-
- if (!a)
- return !b;
- if (!b)
- return 0;
-
- if (copts.mpwc_relax && !copts.cplusplus) {
- if (!is_typeequal(a->type, b->type))
- return 0;
- } else {
- if (!is_typesame(a->type, b->type))
- return 0;
- }
-
- if (a->type->type == TYPEPOINTER && a->qual != b->qual)
- return 0;
-
- a = a->next;
- b = b->next;
- }
-}
-
-short is_memberpointerequal(Type *a, Type *b) {
- FuncArg *arg_a;
- FuncArg *arg_b;
-
- if (a->type != b->type)
- return 0;
- if (!IS_TYPE_FUNC(a))
- return is_typeequal(a, b);
-
- if (!is_typesame(TYPE_FUNC(a)->functype, TYPE_FUNC(b)->functype))
- return 0;
-
- if ((TYPE_FUNC(a)->flags & FUNC_CALL_CONV_MASK) != (TYPE_FUNC(b)->flags & FUNC_CALL_CONV_MASK))
- return 0;
-
- CError_ASSERT(1345, arg_a = TYPE_FUNC(a)->args);
- CError_ASSERT(1346, arg_b = TYPE_FUNC(b)->args);
-
- if (TYPE_FUNC(a)->flags & FUNC_FLAGS_80)
- CError_ASSERT(1351, arg_a = arg_a->next);
-
- if (TYPE_FUNC(b)->flags & FUNC_FLAGS_80)
- CError_ASSERT(1355, arg_b = arg_b->next);
-
- if (arg_a->qual != arg_b->qual)
- return 0;
-
- return is_arglistsame(arg_a->next, arg_b->next);
-}
-
-short is_typeequal(Type *a, Type *b) {
-restart:
- if (a->type != b->type)
- return 0;
- switch (a->type) {
- case TYPEVOID:
- return 1;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPECLASS:
- return a == b;
- case TYPESTRUCT:
- return a == b;
- case TYPEPOINTER:
- if (TYPE_POINTER(a)->target == &stvoid || TYPE_POINTER(b)->target == &stvoid)
- return 1;
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- if (copts.mpwc_relax && !copts.cplusplus)
- return 1;
- goto restart;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(a)->ty2 != TYPE_MEMBER_POINTER(b)->ty2)
- return 0;
- return is_memberpointerequal(TYPE_MEMBER_POINTER(a)->ty1, TYPE_MEMBER_POINTER(b)->ty1);
- case TYPEARRAY:
- if (a->size && b->size && a->size != b->size)
- return 0;
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- goto restart;
- case TYPEFUNC:
- if (copts.cplusplus || !copts.cpp_extensions) {
- if (copts.mpwc_relax && !copts.cplusplus) {
- if (!is_typeequal(TYPE_FUNC(a)->functype, TYPE_FUNC(b)->functype))
- return 0;
- } else {
- if (!is_typesame(TYPE_FUNC(a)->functype, TYPE_FUNC(b)->functype))
- return 0;
- }
- if ((TYPE_FUNC(a)->flags & FUNC_CALL_CONV_MASK) != (TYPE_FUNC(b)->flags & FUNC_CALL_CONV_MASK))
- return 0;
- }
- return is_arglistequal(TYPE_FUNC(a)->args, TYPE_FUNC(b)->args);
- case TYPETEMPLATE:
- return CTemplTool_TemplDepTypeCompare(TYPE_TEMPLATE(a), TYPE_TEMPLATE(b));
- default:
- CError_FATAL(1441);
- return 0;
- }
-}
-
-short iscpp_typeequal(Type *a, Type *b) {
- restart:
- if (a->type != b->type)
- return 0;
- switch (a->type) {
- case TYPEVOID:
- return 1;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPECLASS:
- return a == b;
- case TYPESTRUCT:
- return a == b;
- case TYPEPOINTER:
- if (TYPE_POINTER(b)->target == &stvoid) {
- if (TYPE_POINTER(a)->target == &stvoid)
- return 1;
- else
- return -1;
- }
- if (TYPE_POINTER(a)->target == &stvoid) {
- illegalimplicitconversion = 1;
- return 0;
- }
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- goto restart;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(a)->ty2 != TYPE_MEMBER_POINTER(b)->ty2)
- return 0;
- return is_memberpointerequal(TYPE_MEMBER_POINTER(a)->ty1, TYPE_MEMBER_POINTER(b)->ty1);
- case TYPEARRAY:
- if (a->size && b->size && a->size != b->size)
- return 0;
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- goto restart;
- case TYPEFUNC:
- if (!is_typesame(TYPE_FUNC(a)->functype, TYPE_FUNC(b)->functype))
- return 0;
- if ((TYPE_FUNC(a)->flags & FUNC_CALL_CONV_MASK) != (TYPE_FUNC(b)->flags & FUNC_CALL_CONV_MASK))
- return 0;
- return is_arglistequal(TYPE_FUNC(a)->args, TYPE_FUNC(b)->args);
- case TYPETEMPLATE:
- return CTemplTool_TemplDepTypeCompare(TYPE_TEMPLATE(a), TYPE_TEMPLATE(b));
- default:
- CError_FATAL(1500);
- return 0;
- }
-}
-
-short CParser_CompareArgLists(FuncArg *a, FuncArg *b) {
- Boolean r30;
-
- r30 = 0;
- if (a == &oldstyle) {
- if (b == &oldstyle)
- return 1;
- else
- return 2;
- }
- if (b == &oldstyle)
- return 2;
-
- while (1) {
- if (a == &elipsis) {
- if (b != &elipsis)
- return 0;
- break;
- }
- if (b == &elipsis)
- return 0;
-
- if (a == NULL) {
- if (b)
- return 0;
- break;
- }
- if (b == NULL)
- return 0;
-
- if (a->type->type == TYPEPOINTER) {
- if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(a->type))) {
- if (IS_TYPE_REFERENCE(b->type)) {
- if (!is_typesame(TYPE_POINTER(a->type)->target, TYPE_POINTER(b->type)->target))
- return 0;
- if ((a->qual & (Q_CONST | Q_VOLATILE)) != (b->qual & (Q_CONST | Q_VOLATILE)))
- return 0;
- } else {
- if (!copts.old_argmatch)
- return 0;
- if (!is_typesame(TYPE_POINTER(a->type)->target, b->type))
- return 0;
- if (b->type->type == TYPEPOINTER && (a->qual & (Q_CONST | Q_VOLATILE)) != (b->qual & (Q_CONST | Q_VOLATILE)))
- return 0;
- r30 = 1;
- }
- } else {
- if (b->type->type == TYPEPOINTER) {
- if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(b->type))) {
- if (!copts.old_argmatch)
- return 0;
- if (!is_typesame(a->type, TYPE_POINTER(b->type)->target))
- return 0;
- if (a->type->type == TYPEPOINTER && (a->qual & (Q_CONST | Q_VOLATILE)) != (b->qual & (Q_CONST | Q_VOLATILE)))
- return 0;
- r30 = 1;
- } else {
- if (!is_typesame(TYPE_POINTER(a->type)->target, TYPE_POINTER(b->type)->target))
- return 0;
- if ((a->qual & (Q_CONST | Q_VOLATILE)) != (b->qual & (Q_CONST | Q_VOLATILE)))
- return 0;
- }
- } else {
- return 0;
- }
- }
- } else {
- if (b->type->type == TYPEPOINTER) {
- if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(b->type))) {
- if (!copts.old_argmatch)
- return 0;
- if (!is_typesame(a->type, TYPE_POINTER(b->type)->target))
- return 0;
- r30 = 1;
- } else {
- return 0;
- }
- } else {
- if (!is_typesame(a->type, b->type))
- return 0;
- }
- }
-
- a = a->next;
- b = b->next;
- }
-
- if (r30)
- return 2;
- return 1;
-}
-
-Boolean is_arglistsame(FuncArg *a, FuncArg *b) {
- if (a == &oldstyle) {
- if (b == &oldstyle)
- return 1;
- else
- return oldstylecompatible(b);
- } else {
- if (b == &oldstyle)
- return oldstylecompatible(a);
- }
-
- while (1) {
- if (!a || !b || a == &elipsis || b == &elipsis)
- return a == b;
-
- if (a->type->type == TYPEPOINTER) {
- if (b->type->type != TYPEPOINTER ||
- (a->qual & (Q_CONST | Q_VOLATILE)) != (b->qual & (Q_CONST | Q_VOLATILE)) ||
- !is_typesame(TYPE_POINTER(a->type)->target, TYPE_POINTER(b->type)->target) ||
- IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(a->type)) != IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(b->type)))
- return 0;
- } else {
- if (!is_typesame(a->type, b->type))
- return 0;
- }
-
- a = a->next;
- b = b->next;
- }
-}
-
-short is_typesame(Type *a, Type *b) {
-restart:
- if (a->type != b->type) {
- if (IS_TYPE_TEMPLATE(a) && IS_TYPE_CLASS(b) && (TYPE_CLASS(b)->flags & CLASS_IS_TEMPL))
- return CTemplTool_IsSameTemplateType(b, a);
- if (IS_TYPE_TEMPLATE(b) && IS_TYPE_CLASS(a) && (TYPE_CLASS(a)->flags & CLASS_IS_TEMPL))
- return CTemplTool_IsSameTemplateType(a, b);
- return 0;
- }
-
- switch (a->type) {
- case TYPEVOID:
- return 1;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPECLASS:
- return a == b;
- case TYPETEMPLATE:
- return CTemplTool_TemplDepTypeCompare(TYPE_TEMPLATE(a), TYPE_TEMPLATE(b));
- case TYPESTRUCT:
- return a == b;
- case TYPEPOINTER:
- if ((TYPE_POINTER(a)->qual & (Q_RESTRICT | Q_REFERENCE | Q_CONST | Q_VOLATILE)) != (TYPE_POINTER(b)->qual & (Q_RESTRICT | Q_REFERENCE | Q_CONST | Q_VOLATILE)))
- return 0;
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- goto restart;
- case TYPEMEMBERPOINTER:
- if (!is_typesame(TYPE_MEMBER_POINTER(a)->ty2, TYPE_MEMBER_POINTER(b)->ty2))
- return 0;
- if ((TYPE_MEMBER_POINTER(a)->qual & (Q_RESTRICT | Q_REFERENCE | Q_CONST | Q_VOLATILE)) != (TYPE_MEMBER_POINTER(b)->qual & (Q_RESTRICT | Q_REFERENCE | Q_CONST | Q_VOLATILE)))
- return 0;
- return is_memberpointerequal(TYPE_MEMBER_POINTER(a)->ty1, TYPE_MEMBER_POINTER(b)->ty1);
- case TYPEARRAY:
- if (a->size != b->size)
- return 0;
- a = TYPE_POINTER(a)->target;
- b = TYPE_POINTER(b)->target;
- goto restart;
- case TYPEFUNC:
- if (!is_typesame(TYPE_FUNC(a)->functype, TYPE_FUNC(b)->functype))
- return 0;
- if (TYPE_FUNC(a)->qual != TYPE_FUNC(b)->qual)
- return 0;
- if ((TYPE_FUNC(a)->flags & FUNC_CALL_CONV_MASK) != (TYPE_FUNC(b)->flags & FUNC_CALL_CONV_MASK))
- return 0;
- return is_arglistsame(TYPE_FUNC(a)->args, TYPE_FUNC(b)->args);
- default:
- CError_FATAL(1709);
- return 0;
- }
-}
-
-Type *CParser_GetBoolType(void) {
- if (copts.cplusplus && copts.booltruefalse)
- return TYPE(&stbool);
- else
- return TYPE(&stsignedint);
-}
-
-Type *CParser_GetWCharType(void) {
- if (copts.cplusplus && copts.wchar_type)
- return TYPE(&stwchar);
- else
- return TYPE(&stsignedint);
-}
-
-short CParser_GetOperator(ENodeType t) {
- switch (t) {
- default:
- CError_FATAL(1748);
- case EMONMIN: return '-';
- case EBINNOT: return '~';
- case ELOGNOT: return '!';
- case EADD: return '+';
- case ESUB: return '-';
- case EMUL: return '*';
- case EDIV: return '/';
- case EMODULO: return '%';
- case EAND: return '&';
- case EXOR: return '^';
- case EOR: return '|';
- case ESHL: return TK_SHL;
- case ESHR: return TK_SHR;
- case ELESS: return '<';
- case EGREATER: return '>';
- case ELESSEQU: return TK_LESS_EQUAL;
- case EGREATEREQU: return TK_GREATER_EQUAL;
- case EEQU: return TK_LOGICAL_EQ;
- case ENOTEQU: return TK_LOGICAL_NE;
- }
-}
-
-Boolean CParser_IsMoreCVQualified(UInt32 a, UInt32 b) {
- if ((a & Q_CONST) && !(b & Q_CONST)) {
- return ((a & Q_VOLATILE) || !(b & Q_VOLATILE));
- } else if ((a & Q_VOLATILE) && !(b & Q_VOLATILE)) {
- return ((a & Q_CONST) || !(b & Q_CONST));
- }
- return 0;
-}
-
-Boolean CParser_IsSameOrMoreCVQualified(UInt32 a, UInt32 b) {
- if ((a & (Q_CONST | Q_VOLATILE)) == (b & (Q_CONST | Q_VOLATILE)))
- return 1;
-
- if ((a & Q_CONST) && !(b & Q_CONST)) {
- return ((a & Q_VOLATILE) || !(b & Q_VOLATILE));
- } else if ((a & Q_VOLATILE) && !(b & Q_VOLATILE)) {
- return ((a & Q_CONST) || !(b & Q_CONST));
- }
- return 0;
-}
-
-Boolean is_unsigned(Type *type) {
- if (IS_TYPE_ENUM(type))
- type = TYPE_ENUM(type)->enumtype;
-
- if (
- (type == TYPE(&stunsignedchar)) ||
- (type == TYPE(&stunsignedshort)) ||
- (type == TYPE(&stunsignedint)) ||
- (type == TYPE(&stunsignedlong)) ||
- (type == TYPE(&stunsignedlonglong)) ||
- (type == TYPE(&stbool)) ||
- (copts.unsigned_char && (type == TYPE(&stchar))) ||
- (type->type == TYPEPOINTER))
- return 1;
-
- return 0;
-}
-
-StructMember *ismember(TypeStruct *tstruct, HashNameNode *name) {
- StructMember *member;
-
- for (member = tstruct->members; member; member = member->next) {
- if (member->name == name)
- return member;
- }
-
- return NULL;
-}
-
-void appendmember(TypeStruct *tstruct, StructMember *member) {
- StructMember *last;
-
- if (!tstruct->members) {
- tstruct->members = member;
- return;
- }
-
- for (last = tstruct->members; last->next; last = last->next) {}
- last->next = member;
-}
-
-static void CParser_InsertTryBlock(ParserTryBlock *block) {
- block->cscope_current = cscope_current;
- block->cscope_currentclass = cscope_currentclass;
- block->cscope_currentfunc = cscope_currentfunc;
- block->ctempl_curinstance = ctempl_curinstance;
- block->cerror_locktoken = cerror_locktoken;
- block->cscope_is_member_func = cscope_is_member_func;
- block->next = trychain;
- trychain = block;
-}
-
-static void CParser_RemoveTryBlock(ParserTryBlock *block) {
- cscope_current = block->cscope_current;
- cscope_currentclass = block->cscope_currentclass;
- cscope_currentfunc = block->cscope_currentfunc;
- ctempl_curinstance = block->ctempl_curinstance;
- cerror_locktoken = block->cerror_locktoken;
- cscope_is_member_func = block->cscope_is_member_func;
- trychain = block->next;
-}
-
-static Boolean TryIsDeclaration(Boolean flag1, Boolean flag2, Boolean flag3, short token) {
- Boolean result;
- DeclInfo declinfo;
- struct ParserTryBlock tryblock;
-
- switch (tk) {
- case TK_IDENTIFIER:
- case TK_COLON_COLON:
- break;
- case TK_VOID:
- case TK_CHAR:
- case TK_SHORT:
- case TK_INT:
- case TK_LONG:
- case TK_FLOAT:
- case TK_DOUBLE:
- case TK_SIGNED:
- case TK_UNSIGNED:
- case TK_UNK_113:
- case TK_UNK_114:
- case TK_UNK_115:
- case TK_UNK_116:
- case TK_UNK_117:
- case TK_UNK_118:
- case TK_UNK_119:
- case TK_UNK_11A:
- case TK_BOOL:
- case TK_WCHAR_T:
- if (lookahead() != '(')
- return 1;
- break;
- default:
- return 1;
- }
-
- result = 0;
- CParser_InsertTryBlock(&tryblock);
- if (setjmp(tryblock.jmpbuf) == 0) {
- memclrw(&declinfo, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&declinfo, 0);
- if (!(IS_TYPE_TEMPLATE(declinfo.thetype) && TYPE_TEMPLATE(declinfo.thetype)->dtype == TEMPLDEP_QUALNAME && !declinfo.x53 && !declinfo.x49)) {
- if (flag1) {
- declinfo.x46 = flag3;
- scandeclarator(&declinfo);
- if (!(flag2 && declinfo.name)) {
- if (!token) {
- if (tk == ';' || tk == ',' || tk == '=' || tk == '(' || tk == ')' || tk == '>')
- result = 1;
- } else {
- result = (tk == token);
- }
- }
- } else {
- result = 1;
- }
- }
- }
-
- CParser_RemoveTryBlock(&tryblock);
- return result;
-}
-
-Boolean isdeclaration(UInt8 flag1, UInt8 flag2, UInt8 flag3, short token) {
- SInt32 state;
-
- if (!(tk >= TK_AUTO && tk <= TK_BYREF) && tk != TK_COLON_COLON && !(tk == TK_IDENTIFIER && CScope_PossibleTypeName(tkidentifier))) {
- if (!(tk == TK_IDENTIFIER && copts.altivec_model && !strcmp(tkidentifier->name, "vector")))
- return 0;
- } else {
- if (!copts.cplusplus)
- return 1;
- }
-
- CPrep_TokenStreamGetState(&state);
- if (TryIsDeclaration(flag1, flag2, flag3, token)) {
- CPrep_TokenStreamSetCurState(&state);
- return 1;
- } else {
- CPrep_TokenStreamSetCurState(&state);
- return 0;
- }
-}
-
-Boolean islookaheaddeclaration(void) {
- SInt32 state;
-
- CPrep_TokenStreamGetState(&state);
- tk = lex();
- if (!(tk >= TK_AUTO && tk <= TK_BYREF) && tk != TK_COLON_COLON && !(tk == TK_IDENTIFIER && CScope_PossibleTypeName(tkidentifier))) {
- if (!(tk == TK_IDENTIFIER && copts.altivec_model && !strcmp(tkidentifier->name, "vector"))) {
- CPrep_TokenStreamSetCurState(&state);
- return 0;
- }
- } else {
- if (!copts.cplusplus) {
- CPrep_TokenStreamSetCurState(&state);
- return 1;
- }
- }
-
- if (TryIsDeclaration(1, 1, 0, ')')) {
- CPrep_TokenStreamSetCurState(&state);
- return 1;
- } else {
- CPrep_TokenStreamSetCurState(&state);
- return 0;
- }
-}
-
-Type *CParser_ParseTypeID(UInt32 *qual, Boolean *flag) {
- SInt32 state;
- DeclInfo di;
- struct ParserTryBlock tryblock;
-
- memclrw(&di, sizeof(DeclInfo));
- CPrep_TokenStreamGetState(&state);
- CParser_InsertTryBlock(&tryblock);
-
- if (setjmp(tryblock.jmpbuf) == 0) {
- if (copts.cplusplus)
- di.x55 = 1;
-
- if (flag) {
- di.x56 = 1;
- *flag = 0;
- }
-
- CParser_GetDeclSpecs(&di, 0);
- if (di.x57 && IS_TYPE_CLASS(di.thetype) && (TYPE_CLASS(di.thetype)->flags & CLASS_IS_TEMPL)) {
- CParser_RemoveTryBlock(&tryblock);
- *qual = di.qual;
- *flag = 1;
- return di.thetype;
- }
-
- if (flag && IS_TYPE_TEMPLATE(di.thetype) && TYPE_TEMPLATE(di.thetype)->dtype == TEMPLDEP_ARGUMENT &&
- TYPE_TEMPLATE(di.thetype)->u.pid.type == TPT_TEMPLATE) {
- CParser_RemoveTryBlock(&tryblock);
- *qual = di.qual;
- *flag = 1;
- return di.thetype;
- }
-
- scandeclarator(&di);
- if (!di.name) {
- CParser_RemoveTryBlock(&tryblock);
- *qual = di.qual;
- return di.thetype;
- }
- }
-
- CPrep_TokenStreamSetCurState(&state);
- CParser_RemoveTryBlock(&tryblock);
- return 0;
-}
-
-Boolean CParser_TryFuncDecl(void) {
- Boolean result;
- SInt32 state;
- DeclInfo di;
- struct ParserTryBlock tryblock;
-
- result = 0;
- CPrep_TokenStreamGetState(&state);
- CParser_InsertTryBlock(&tryblock);
-
- if (setjmp(tryblock.jmpbuf) == 0) {
- memclrw(&di, sizeof(DeclInfo));
- di.thetype = &stvoid;
- scandeclarator(&di);
-
- if (IS_TYPE_FUNC(di.thetype))
- result = 1;
- }
-
- CParser_RemoveTryBlock(&tryblock);
- CPrep_TokenStreamSetCurState(&state);
- return result;
-}
-
-Boolean CParser_TryParamList(Boolean flag) {
- Boolean result;
- SInt32 state;
- struct ParserTryBlock tryblock;
-
- result = 0;
- CPrep_TokenStreamGetState(&state);
-
- switch ((tk = lex())) {
- case ')':
- case TK_ELLIPSIS:
- result = 1;
- break;
- default:
- CParser_InsertTryBlock(&tryblock);
- if (setjmp(tryblock.jmpbuf) == 0) {
- if (CFunc_ParseFakeArgList(flag) || tk == ')')
- result = 1;
- }
- CParser_RemoveTryBlock(&tryblock);
- break;
- }
-
- CPrep_TokenStreamSetCurState(&state);
- return result;
-}
-
-Type *CParser_RemoveTopMostQualifiers(Type *type, UInt32 *qual) {
- switch (type->type) {
- case TYPEARRAY:
- TYPE_POINTER(type)->target = CParser_RemoveTopMostQualifiers(TYPE_POINTER(type)->target, qual);
- return type;
- case TYPEPOINTER:
- if (TYPE_POINTER(type)->qual & Q_CONST) {
- TypePointer *newtype = galloc(sizeof(TypePointer));
- *newtype = *TYPE_POINTER(type);
- newtype->qual = 0;
- return TYPE(newtype);
- }
- return type;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(type)->qual & Q_CONST) {
- TypeMemberPointer *newtype = galloc(sizeof(TypeMemberPointer));
- *newtype = *TYPE_MEMBER_POINTER(type);
- newtype->qual = 0;
- return TYPE(newtype);
- }
- return type;
- default:
- *qual = 0;
- return type;
- }
-}
-
-UInt32 CParser_GetTypeQualifiers(Type *type, UInt32 qual) {
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
-
- switch (type->type) {
- case TYPEPOINTER:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(type)->qual;
- break;
- }
-
- return qual;
-}
-
-UInt32 CParser_GetCVTypeQualifiers(Type *type, UInt32 qual) {
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
-
- switch (type->type) {
- case TYPEPOINTER:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(type)->qual;
- break;
- }
-
- return qual & (Q_CONST | Q_VOLATILE);
-}
-
-Boolean CParser_IsConst(Type *type, UInt32 qual) {
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
-
- switch (type->type) {
- case TYPEPOINTER:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(type)->qual;
- break;
- }
-
- return (qual & Q_CONST) != 0;
-}
-
-Boolean CParser_IsVolatile(Type *type, UInt32 qual) {
- while (IS_TYPE_ARRAY(type))
- type = TYPE_POINTER(type)->target;
-
- switch (type->type) {
- case TYPEPOINTER:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(type)->qual;
- break;
- }
-
- return (qual & Q_VOLATILE) != 0;
-}
-
-Boolean is_const_object(Object *obj) {
- return CParser_IsConst(obj->type, obj->qual);
-}
-
-Boolean is_volatile_object(Object *obj) {
- return CParser_IsVolatile(obj->type, obj->qual);
-}
-
-Boolean CParserIsConstExpr(ENode *expr) {
- return CParser_IsConst(expr->rtype, expr->flags & ENODE_FLAG_QUALS);
-}
-
-Boolean CParserIsVolatileExpr(ENode *expr) {
- return CParser_IsVolatile(expr->rtype, expr->flags & ENODE_FLAG_QUALS);
-}
-
-Boolean CParser_HasInternalLinkage(const Object *obj) {
- NameSpace *nspace;
-
- for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
- if (nspace->is_unnamed)
- return 1;
- }
-
- if (obj->datatype == DLOCAL)
- return 1;
- if (obj->qual & (Q_20000 | Q_WEAK))
- return 0;
- if (obj->sclass == TK_STATIC)
- return 1;
-
- // this feels *wrong* but it's the only way to match this function that I can see
- if (obj->qual & Q_INLINE)
- ((Object *) obj)->qual |= Q_20000;
- return 0;
-}
-
-Boolean CParser_HasInternalLinkage2(const Object *obj) {
- if (obj->datatype == DLOCAL)
- return 1;
- if (obj->qual & (Q_20000 | Q_WEAK))
- return 0;
- if (obj->sclass == TK_STATIC)
- return 1;
-
- // this feels *wrong* but it's the only way to match this function that I can see
- if (obj->qual & Q_INLINE)
- ((Object *) obj)->qual |= Q_20000;
- return 0;
-}
-
-Boolean CParser_IsVirtualFunction(Object *obj, TypeClass **tclass, SInt32 *index) {
- if (obj->datatype == DVFUNC) {
- *tclass = TYPE_METHOD(obj->type)->theclass;
- *index = TYPE_METHOD(obj->type)->vtbl_index;
- return 1;
- }
-
- return 0;
-}
-
-Boolean is_pascal_object(Object *obj) {
- return IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_PASCAL);
-}
-
-Boolean is_cfm_type(Type *type) {
- return 0;
-}
-
-Boolean CParser_IsVTableObject(Object *obj) {
- return
- obj->datatype == DDATA &&
- obj->nspace &&
- obj->nspace->theclass &&
- obj->nspace->theclass->vtable &&
- obj->nspace->theclass->vtable->object == obj;
-}
-
-static Type *getthetype(short token, short size, short signedness) {
- switch (token) {
- case 0:
- case TK_INT:
- if (signedness == 1) {
- switch (size) {
- case 1: return TYPE(&stunsignedshort);
- case 2: return TYPE(&stunsignedlong);
- case 3: return TYPE(&stunsignedlonglong);
- default: return TYPE(&stunsignedint);
- }
- } else {
- switch (size) {
- case 1: return TYPE(&stsignedshort);
- case 2: return TYPE(&stsignedlong);
- case 3: return TYPE(&stsignedlonglong);
- default: return TYPE(&stsignedint);
- }
- }
- case TK_BOOL:
- return TYPE(&stbool);
- case TK_WCHAR_T:
- return TYPE(&stwchar);
- case TK_CHAR:
- switch (signedness) {
- case 1: return TYPE(&stunsignedchar);
- default: return TYPE(&stchar);
- case -1: return TYPE(&stsignedchar);
- }
- case TK_DOUBLE:
- switch (size) {
- case 1: return TYPE(&stshortdouble);
- case 2: return TYPE(&stlongdouble);
- default: return TYPE(&stdouble);
- }
- case TK_FLOAT:
- return TYPE(&stfloat);
- case TK_VOID:
- return TYPE(&stvoid);
- default:
- CError_Error(CErrorStr121);
- return TYPE(&stvoid);
- }
-}
-
-void TypedefDeclInfo(DeclInfo *declinfo, Type *type, UInt32 qual) {
- if (type->type == TYPEPOINTER) {
- if (IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(type))) {
- declinfo->thetype = type;
- declinfo->qual &= ~(Q_RESTRICT | Q_REFERENCE | Q_VOLATILE | Q_CONST);
- declinfo->qual |= qual;
- return;
- }
-
- declinfo->thetype = galloc(sizeof(TypePointer));
- *TYPE_POINTER(declinfo->thetype) = *TYPE_POINTER(type);
- TYPE_POINTER(declinfo->thetype)->qual |= declinfo->qual & (Q_RESTRICT | Q_REFERENCE | Q_VOLATILE | Q_CONST);
- declinfo->qual &= ~(Q_RESTRICT | Q_REFERENCE | Q_VOLATILE | Q_CONST);
- declinfo->qual |= qual & (Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST);
- } else if (type->type == TYPEMEMBERPOINTER) {
- declinfo->thetype = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(declinfo->thetype) = *TYPE_MEMBER_POINTER(type);
- TYPE_MEMBER_POINTER(declinfo->thetype)->qual |= declinfo->qual & (Q_RESTRICT | Q_REFERENCE | Q_VOLATILE | Q_CONST);
- declinfo->qual &= ~(Q_RESTRICT | Q_REFERENCE | Q_VOLATILE | Q_CONST);
- declinfo->qual |= qual & (Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST);
- } else {
- declinfo->thetype = type;
- declinfo->qual |= qual & (Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST);
- if (IS_TYPE_ARRAY(declinfo->thetype) && !declinfo->thetype->size) {
- declinfo->thetype = galloc(sizeof(TypePointer));
- *TYPE_POINTER(declinfo->thetype) = *TYPE_POINTER(type);
- }
- }
- declinfo->x49 = 1;
-}
-
-static void CParser_ParseAttributeFunctionSummary(DeclInfo *declinfo) {
- Boolean flag;
-
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr114);
- return;
- }
-
- flag = 1;
- tk = lookahead();
- while (tk == TK_IDENTIFIER) {
- if (flag && !strcmp(tkidentifier->name, "entry_points_to")) {
- PointerAnalysis_ParseEntryPointsToSpecifier(declinfo);
- } else if (!strcmp(tkidentifier->name, "exit_points_to")) {
- PointerAnalysis_ParseExitPointsToSpecifier(declinfo);
- flag = 0;
- } else if (!strcmp(tkidentifier->name, "function_modifies")) {
- PointerAnalysis_ParseFunctionModifiesSpecifier(declinfo);
- flag = 0;
- } else {
- lex();
- CError_Error(CErrorStr121);
- return;
- }
-
- tk = lookahead();
- if (tk == ',') {
- lex();
- tk = lookahead();
- }
- }
-
- lex();
- if (tk != ')')
- CError_Error(CErrorStr121);
-}
-
-void CParser_ParseAttribute(Type *type, DeclInfo *declinfo) {
- CInt64 val64;
- SInt32 val;
-
- do {
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr121);
- return;
- }
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr121);
- return;
- }
- if ((tk = lex()) != TK_IDENTIFIER && tk != TK_CONST) {
- CError_Error(CErrorStr121);
- return;
- }
-
- if (!strcmp(tkidentifier->name, "aligned") || !strcmp(tkidentifier->name, "__aligned__")) {
- if ((tk = lex()) != '(') {
- CError_Error(CErrorStr121);
- return;
- }
-
- tk = lex();
- val64 = CExpr_IntegralConstExpr();
- switch ((val = CInt64_GetULong(&val64))) {
- case 1:
- case 2:
- case 4:
- case 8:
- case 0x10:
- case 0x20:
- case 0x40:
- case 0x80:
- case 0x100:
- case 0x200:
- case 0x400:
- case 0x800:
- case 0x1000:
- case 0x2000:
- break;
- default:
- CError_Error(CErrorStr124);
- return;
- }
- if (type) {
- if (IS_TYPE_STRUCT(type)) {
- if (val > TYPE_STRUCT(type)->align) {
- TYPE_STRUCT(type)->align = val;
- type->size += CABI_StructSizeAlignValue(type, type->size);
- }
- } else if (IS_TYPE_CLASS(type)) {
- if (val > TYPE_CLASS(type)->align) {
- TYPE_CLASS(type)->align = val;
- type->size += CABI_StructSizeAlignValue(type, type->size);
- }
- } else {
- CError_Error(CErrorStr149);
- }
- } else if (declinfo) {
- declinfo->qual &= ~Q_ALIGNED_MASK;
- switch (val) {
- case 1:
- declinfo->qual |= Q_ALIGNED_1;
- break;
- case 2:
- declinfo->qual |= Q_ALIGNED_2;
- break;
- case 4:
- declinfo->qual |= Q_ALIGNED_4;
- break;
- case 8:
- declinfo->qual |= Q_ALIGNED_8;
- break;
- case 16:
- declinfo->qual |= Q_ALIGNED_16;
- break;
- case 32:
- declinfo->qual |= Q_ALIGNED_32;
- break;
- case 64:
- declinfo->qual |= Q_ALIGNED_64;
- break;
- case 128:
- declinfo->qual |= Q_ALIGNED_128;
- break;
- case 256:
- declinfo->qual |= Q_ALIGNED_256;
- break;
- case 512:
- declinfo->qual |= Q_ALIGNED_512;
- break;
- case 1024:
- declinfo->qual |= Q_ALIGNED_1024;
- break;
- case 2048:
- declinfo->qual |= Q_ALIGNED_2048;
- break;
- case 4096:
- declinfo->qual |= Q_ALIGNED_4096;
- break;
- case 8192:
- declinfo->qual |= Q_ALIGNED_8192;
- break;
- default:
- CError_FATAL(2779);
- break;
- }
- } else {
- CError_Error(CErrorStr359);
- }
-
- if (tk != ')') {
- CError_Error(CErrorStr121);
- return;
- }
- } else if (!strcmp(tkidentifier->name, "nothrow") || !strcmp(tkidentifier->name, "__nothrow__")) {
- if (declinfo && declinfo->thetype && IS_TYPE_FUNC(declinfo->thetype))
- TYPE_FUNC(declinfo->thetype)->flags |= FUNC_NOTHROW;
- else
- CError_Error(CErrorStr359);
- } else if (!strcmp("function_summary", tkidentifier->name)) {
- CParser_ParseAttributeFunctionSummary(declinfo);
- } else if (!strcmp(tkidentifier->name, "packed") || !strcmp(tkidentifier->name, "__packed__")) {
- CError_Error(CErrorStr359);
- } else if (!strcmp(tkidentifier->name, "unused") || !strcmp(tkidentifier->name, "__unused__")) {
- } else if (!strcmp(tkidentifier->name, "noreturn") || !strcmp(tkidentifier->name, "__noreturn__")) {
- } else if (tk == TK_CONST || !strcmp(tkidentifier->name, "__const__")) {
- } else if (!strcmp(tkidentifier->name, "format") || !strcmp(tkidentifier->name, "__format__")) {
- CError_Warning(CErrorStr359);
- if ((tk = lex()) != '(') {
- CError_Warning(CErrorStr114);
- return;
- }
- tk = lex();
- if ((tk = lex()) != ',') {
- CError_Warning(CErrorStr116);
- return;
- }
- tk = lex();
- if ((tk = lex()) != ',') {
- CError_Warning(CErrorStr116);
- return;
- }
- tk = lex();
- if ((tk = lex()) != ')') {
- CError_Warning(CErrorStr115);
- return;
- }
- } else if (!strcmp(tkidentifier->name, "mode") || !strcmp(tkidentifier->name, "__mode__")) {
- CError_Warning(CErrorStr359);
- if ((tk = lex()) != '(') {
- CError_Warning(CErrorStr114);
- return;
- }
- tk = lex();
- if ((tk = lex()) != ')') {
- CError_Warning(CErrorStr115);
- return;
- }
- } else {
- CError_Error(CErrorStr359);
- }
-
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr121);
- return;
- }
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr121);
- return;
- }
- tk = lex();
- } while (tk == TK_UU_ATTRIBUTE_UU);
-}
-
-static void CParser_ParseTypeOf(DeclInfo *declinfo) {
- DeclInfo subdi;
- ENode *expr;
-
- if ((tk = lex()) == '(' && islookaheaddeclaration()) {
- tk = lex();
-
- memclrw(&subdi, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&subdi, 0);
- scandeclarator(&subdi);
- if (subdi.name)
- CError_Error(CErrorStr121);
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- TypedefDeclInfo(declinfo, subdi.thetype, subdi.qual);
- } else {
- expr = unary_expression();
- if (ENODE_IS(expr, EINDIRECT) && ENODE_IS(expr->data.monadic, EBITFIELD))
- CError_Error(CErrorStr144);
- TypedefDeclInfo(declinfo, expr->rtype, expr->flags & ENODE_FLAG_QUALS);
- }
-}
-
-void CParser_ParseDeclSpec(DeclInfo *declinfo, Boolean flag) {
- if ((tk = lex()) != TK_IDENTIFIER) {
- if (tk != TK_EXPORT)
- CError_Error(CErrorStr107);
- else
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_EXPORT;
- } else if (!strcmp("internal", tkidentifier->name)) {
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_INTERNAL;
- } else if (!strcmp("import", tkidentifier->name) || !strcmp("dllimport", tkidentifier->name)) {
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_IMPORT;
- } else if (!strcmp("export", tkidentifier->name) || !strcmp("dllexport", tkidentifier->name)) {
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_EXPORT;
- } else if (!strcmp("lib_export", tkidentifier->name)) {
- declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_IMPORT | EXPORT_FLAGS_EXPORT;
- } else if (!strcmp("weak", tkidentifier->name)) {
- declinfo->qual |= Q_WEAK;
- } else {
- CodeGen_ParseDeclSpec(tkidentifier, declinfo);
- }
-}
-
-static int CParser_GetVectorDeclSpec(Type **type) {
- tk = lex();
- switch (tk) {
- case TK_CHAR:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboolchar);
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedchar);
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedchar);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboolchar);
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_SIGNED:
- tk = lex();
- switch (tk) {
- case TK_CHAR:
- *type = TYPE(&stvectorsignedchar);
- tk = lex();
- return 1;
- case TK_SHORT:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorsignedlong);
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_UNSIGNED:
- tk = lex();
- switch (tk) {
- case TK_CHAR:
- *type = TYPE(&stvectorunsignedchar);
- tk = lex();
- return 1;
- case TK_SHORT:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorunsignedlong);
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_BOOL:
- tk = lex();
- switch (tk) {
- case TK_CHAR:
- *type = TYPE(&stvectorboolchar);
- tk = lex();
- return 1;
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorboollong);
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_SHORT:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_LONG:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboollong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorboollong);
- return 1;
- }
- case TK_SIGNED:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorsignedlong);
- return 1;
- }
- case TK_UNSIGNED:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorunsignedlong);
- return 1;
- }
- case TK_SHORT:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedshort);
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedshort);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_LONG:
- tk = lex();
- switch (tk) {
- case TK_BOOL:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- case TK_SIGNED:
- *type = TYPE(&stvectorsignedlong);
- tk = lex();
- return 1;
- case TK_UNSIGNED:
- *type = TYPE(&stvectorunsignedlong);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- }
- }
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("bool")) {
- tk = lex();
- switch (tk) {
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorboolshort);
- return 1;
- }
- }
- default:
- CError_Error(CErrorStr121);
- }
- break;
- case TK_FLOAT:
- *type = TYPE(&stvectorfloat);
- tk = lex();
- return 1;
- case TK_IDENTIFIER:
- if (tkidentifier == GetHashNameNode("pixel") || tkidentifier == GetHashNameNode("__pixel")) {
- *type = TYPE(&stvectorpixel);
- tk = lex();
- return 1;
- }
- if (tkidentifier == GetHashNameNode("bool")) {
- tk = lex();
- switch (tk) {
- case TK_CHAR:
- *type = TYPE(&stvectorboolchar);
- tk = lex();
- return 1;
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- if (tk == TK_INT)
- tk = lex();
- return 1;
- case TK_INT:
- tk = lex();
- switch (tk) {
- case TK_SHORT:
- *type = TYPE(&stvectorboolshort);
- tk = lex();
- return 1;
- case TK_LONG:
- *type = TYPE(&stvectorboollong);
- tk = lex();
- return 1;
- default:
- *type = TYPE(&stvectorboollong);
- return 1;
- }
- }
- }
- default:
- CError_Error(CErrorStr121);
- }
-
- return 0;
-}
-
-Boolean CParser_CheckTemplateClassUsage(TemplClass *tmclass, Boolean flag) {
- NameSpace *nspace;
-
- if (tmclass->templ__params) {
- nspace = cscope_current;
- while (1) {
- if (!nspace) {
- if (flag)
- CError_Error(CErrorStr230);
- return 0;
- }
- if (nspace->theclass == TYPE_CLASS(tmclass))
- break;
- nspace = nspace->parent;
- }
- }
-
- return 1;
-}
-
-static Boolean CParser_IsAltiVecPrefix(void) {
- HashNameNode *save = tkidentifier;
-
- switch (lookahead()) {
- case TK_CHAR:
- case TK_SHORT:
- case TK_INT:
- case TK_LONG:
- case TK_FLOAT:
- case TK_SIGNED:
- case TK_UNSIGNED:
- case TK_BOOL:
- return 1;
- case TK_IDENTIFIER:
- if (!strcmp(tkidentifier->name, "bool") || !strcmp(tkidentifier->name, "pixel") || !strcmp(tkidentifier->name, "__pixel"))
- return 1;
- }
-
- tkidentifier = save;
- return 0;
-}
-
-void CParser_GetDeclSpecs(DeclInfo *di, Boolean flag) {
- short typesize;
- short signedness;
- short typetoken;
- Boolean r24;
- Boolean r23;
- SInt32 state;
- NameResult pr;
-
- di->file = CPrep_BrowserCurrentFile();
- CPrep_BrowserFilePosition(&di->file2, &di->sourceoffset);
-
- r24 = 1;
- r23 = copts.cplusplus;
- typetoken = 0;
- signedness = 0;
- typesize = 0;
-
-restart:
- switch (tk) {
- case TK_AUTO:
- case TK_REGISTER:
- case TK_STATIC:
- case TK_EXTERN:
- case TK_TYPEDEF:
- case TK_MUTABLE:
- if (di->storageclass)
- CError_Error(CErrorStr121);
- di->storageclass = tk;
- break;
- case TK_CONST:
- if (di->thetype) {
- if (di->thetype->type == TYPEPOINTER) {
- if (TYPE_POINTER(di->thetype)->qual & Q_CONST)
- CError_QualifierCheck(Q_CONST);
- TYPE_POINTER(di->thetype)->qual |= Q_CONST;
- break;
- } else if (di->thetype->type == TYPEMEMBERPOINTER) {
- if (TYPE_MEMBER_POINTER(di->thetype)->qual & Q_CONST)
- CError_QualifierCheck(Q_CONST);
- TYPE_MEMBER_POINTER(di->thetype)->qual |= Q_CONST;
- break;
- }
- }
- if (di->qual & Q_CONST)
- CError_QualifierCheck(Q_CONST);
- di->qual |= Q_CONST;
- break;
- case TK_VOLATILE:
- if (di->thetype) {
- if (di->thetype->type == TYPEPOINTER) {
- if (TYPE_POINTER(di->thetype)->qual & Q_VOLATILE)
- CError_QualifierCheck(Q_VOLATILE);
- TYPE_POINTER(di->thetype)->qual |= Q_VOLATILE;
- break;
- } else if (di->thetype->type == TYPEMEMBERPOINTER) {
- if (TYPE_MEMBER_POINTER(di->thetype)->qual & Q_VOLATILE)
- CError_QualifierCheck(Q_VOLATILE);
- TYPE_MEMBER_POINTER(di->thetype)->qual |= Q_VOLATILE;
- break;
- }
- }
- if (di->qual & Q_VOLATILE)
- CError_QualifierCheck(Q_VOLATILE);
- di->qual |= Q_VOLATILE;
- break;
- case TK_PASCAL:
- if (di->qual & Q_PASCAL)
- CError_QualifierCheck(Q_PASCAL);
- di->qual |= Q_PASCAL;
- break;
- case TK_EXPLICIT:
- CError_QualifierCheck(di->qual & Q_EXPLICIT);
- di->qual |= Q_EXPLICIT;
- break;
- case TK_VIRTUAL:
- CError_QualifierCheck(di->qual & Q_VIRTUAL);
- di->qual |= Q_VIRTUAL;
- break;
- case TK_IN:
- CError_QualifierCheck(di->qual & Q_IN);
- di->qual |= Q_IN;
- break;
- case TK_OUT:
- CError_QualifierCheck(di->qual & Q_OUT);
- di->qual |= Q_OUT;
- break;
- case TK_INOUT:
- CError_QualifierCheck(di->qual & Q_INOUT);
- di->qual |= Q_INOUT;
- break;
- case TK_BYCOPY:
- CError_QualifierCheck(di->qual & Q_BYCOPY);
- di->qual |= Q_BYCOPY;
- break;
- case TK_BYREF:
- CError_QualifierCheck(di->qual & Q_BYREF);
- di->qual |= Q_BYREF;
- break;
- case TK_ONEWAY:
- CError_QualifierCheck(di->qual & Q_ONEWAY);
- di->qual |= Q_ONEWAY;
- break;
- case TK_UU_DECLSPEC:
- if ((tk = lex()) != '(')
- CError_Error(CErrorStr114);
- CParser_ParseDeclSpec(di, 0);
- if ((tk = lex()) != ')')
- CError_Error(CErrorStr115);
- break;
- case TK_ASM:
- if (di->qual & Q_ASM)
- CError_QualifierCheck(Q_ASM);
- di->qual |= Q_ASM;
- break;
- case TK_INLINE:
- if (di->qual & Q_INLINE)
- CError_QualifierCheck(Q_INLINE);
- di->qual |= Q_INLINE;
- break;
- case TK_SHORT:
- if (typesize || (typetoken && typetoken != TK_INT && typetoken != TK_DOUBLE))
- CError_Error(CErrorStr121);
- typesize = 1;
- break;
- case TK_LONG:
- if (copts.longlong) {
- if (typetoken && typetoken != TK_INT && typetoken != TK_DOUBLE)
- CError_Error(CErrorStr121);
- if (typesize) {
- if (typesize != 2 || typetoken == TK_DOUBLE)
- CError_Error(CErrorStr121);
- typesize = 3;
- } else {
- typesize = 2;
- }
- } else {
- if (typesize || (typetoken && typetoken != TK_INT && typetoken != TK_DOUBLE))
- CError_Error(CErrorStr121);
- typesize = 2;
- }
- break;
- case TK_SIGNED:
- if (signedness || (typetoken && typetoken != TK_INT && typetoken != TK_CHAR))
- CError_Error(CErrorStr121);
- signedness = -1;
- break;
- case TK_UNSIGNED:
- if (signedness || (typetoken && typetoken != TK_INT && typetoken != TK_CHAR))
- CError_Error(CErrorStr121);
- signedness = 1;
- break;
- case TK_VOID:
- if (typetoken || typesize || signedness)
- CError_Error(CErrorStr121);
- typetoken = TK_VOID;
- break;
- case TK_FLOAT:
- if (typetoken || typesize || signedness)
- CError_Error(CErrorStr121);
- typetoken = TK_FLOAT;
- break;
- case TK_BOOL:
- if (typetoken || typesize)
- CError_Error(CErrorStr121);
- typetoken = TK_BOOL;
- break;
- case TK_CHAR:
- if (typetoken || typesize)
- CError_Error(CErrorStr121);
- typetoken = TK_CHAR;
- break;
- case TK_WCHAR_T:
- if (typetoken || typesize || signedness)
- CError_Error(CErrorStr121);
- typetoken = TK_WCHAR_T;
- break;
- case TK_INT:
- if (typetoken)
- CError_Error(CErrorStr121);
- typetoken = TK_INT;
- break;
- case TK_DOUBLE:
- if (typetoken || signedness)
- CError_Error(CErrorStr121);
- typetoken = TK_DOUBLE;
- break;
- case TK_STRUCT:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- tk = lex();
- scanstruct(di, STRUCT_TYPE_STRUCT);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(di->thetype, NULL);
- if (!(tk != TK_CONST && tk != TK_VOLATILE && tk != TK_UU_FAR && tk != TK_UU_DECLSPEC)) {
- typetoken = -1;
- goto restart;
- }
- return;
- case TK_CLASS:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- tk = lex();
- CDecl_ParseClass(di, CLASS_MODE_CLASS, 1, 0);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(di->thetype, NULL);
- if (!(tk != TK_CONST && tk != TK_VOLATILE && tk != TK_UU_FAR && tk != TK_UU_DECLSPEC)) {
- typetoken = -1;
- goto restart;
- }
- return;
- case TK_UNION:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- tk = lex();
- scanstruct(di, STRUCT_TYPE_UNION);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(di->thetype, NULL);
- if (!(tk != TK_CONST && tk != TK_VOLATILE && tk != TK_UU_FAR && tk != TK_UU_DECLSPEC)) {
- typetoken = -1;
- goto restart;
- }
- return;
- case TK_ENUM:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- tk = lex();
- scanenum(di);
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(di->thetype, NULL);
- if (!(tk != TK_CONST && tk != TK_VOLATILE && tk != TK_UU_FAR && tk != TK_UU_DECLSPEC)) {
- typetoken = -1;
- goto restart;
- }
- return;
- case TK_TYPENAME:
- if (typetoken || signedness || typesize || di->x53)
- CError_Error(CErrorStr121);
- di->x53 = 1;
- tk = lex();
- if (tk != TK_COLON_COLON && tk != TK_IDENTIFIER) {
- CError_Error(CErrorStr121);
- break;
- }
- goto some_shared_label;
- case TK_COLON_COLON:
- if (typetoken || signedness || typesize)
- goto switchDefault;
- goto some_shared_label;
- case TK_UU_VECTOR:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- handle_vector:
- if (CParser_GetVectorDeclSpec(&di->thetype)) {
- if (tk == TK_CONST) {
- if (di->qual == 0) {
- di->qual |= Q_CONST;
- tk = lex();
- } else {
- CError_Error(CErrorStr121);
- }
- }
- if (tk == TK_VOLATILE) {
- if (di->qual == 0) {
- di->qual |= Q_VOLATILE;
- tk = lex();
- } else {
- CError_Error(CErrorStr121);
- }
- }
- return;
- }
- break;
- case TK_UU_TYPEOF_UU:
- if (typetoken || signedness || typesize)
- CError_Error(CErrorStr121);
- CParser_ParseTypeOf(di);
- typetoken = -1;
- goto bailOut;
- case TK_IDENTIFIER:
- if (copts.altivec_model && !typetoken && !signedness && !typesize && !strcmp(tkidentifier->name, "vector")) {
- if (CParser_IsAltiVecPrefix())
- goto handle_vector;
- }
- if (!typetoken && !signedness && !typesize) {
- if (copts.objective_c && !strcmp(tkidentifier->name, "id")) {
- di->thetype = CObjC_ParseID();
- typetoken = -1;
- goto bailOut;
- }
- some_shared_label:
- CPrep_TokenStreamGetState(&state);
- if (CScope_ParseDeclName(&pr)) {
- if (pr.type) {
- if (IS_TYPE_TEMPLATE(pr.type)) {
- switch (TYPE_TEMPLATE(pr.type)->dtype) {
- case TEMPLDEP_ARGUMENT:
- switch (TYPE_TEMPLATE(pr.type)->u.pid.type) {
- case TPT_TYPE:
- break;
- case TPT_NONTYPE:
- CError_Error(CErrorStr348);
- pr.type = TYPE(&stsignedint);
- break;
- case TPT_TEMPLATE:
- CError_Error(CErrorStr230);
- pr.type = TYPE(&stsignedint);
- break;
- default:
- CError_FATAL(4109);
- }
- break;
- case TEMPLDEP_QUALNAME:
- if (!di->x53 && !pr.x20 && di->x55)
- CError_Error(CErrorStr355);
- break;
- case TEMPLDEP_TEMPLATE:
- case TEMPLDEP_ARRAY:
- case TEMPLDEP_QUALTEMPL:
- case TEMPLDEP_BITFIELD:
- break;
- default:
- CError_FATAL(4136);
- }
- }
-
- if (IS_TYPE_CLASS(pr.type) && (TYPE_CLASS(pr.type)->flags & CLASS_IS_TEMPL)) {
- if (!CParser_CheckTemplateClassUsage(TEMPL_CLASS(pr.type), 0)) {
- if (di->x56) {
- if (di->qual)
- CError_Error(CErrorStr121);
- di->thetype = pr.type;
- di->x57 = 1;
- tk = lex();
- return;
- } else {
- CError_Error(CErrorStr230);
- pr.type = TYPE(&stsignedint);
- }
- }
- }
-
- TypedefDeclInfo(di, pr.type, pr.qual);
- di->x49 = pr.x20;
- typetoken = -1;
- tk = lex();
- if (tk == '<' && copts.objective_c && IS_TYPE_CLASS(di->thetype) && TYPE_CLASS(di->thetype)->objcinfo)
- di->thetype = CObjC_ParseTypeProtocol(TYPE_CLASS(di->thetype));
- goto bailOut;
- } else if (pr.nsol_14) {
- if (pr.x1D) {
- if (flag && (OBJECT(pr.nsol_14->object)->nspace == pr.nspace_0 || di->in_friend_decl)) {
- di->x14 = pr.nsol_14;
- if (IS_TYPE_FUNC(OBJECT(di->x14->object)->type) && ((TYPE_FUNC(OBJECT(di->x14->object)->type)->flags & FUNC_IS_CTOR) | FUNC_IS_DTOR))
- r23 = 0;
- } else {
- CError_Error(CErrorStr121);
- }
- }
- } else if (pr.obj_10) {
- switch (pr.obj_10->otype) {
- case OT_OBJECT:
- if (pr.x1D) {
- if (flag && (OBJECT(pr.obj_10)->nspace == pr.nspace_0 || di->in_friend_decl)) {
- di->x10 = OBJECT(pr.obj_10);
- if (IS_TYPE_FUNC(di->x10->type) && ((TYPE_FUNC(di->x10->type)->flags & FUNC_IS_CTOR) | FUNC_IS_DTOR))
- r23 = 0;
- } else {
- CError_Error(CErrorStr121);
- }
- }
- break;
- case OT_ENUMCONST:
- case OT_MEMBERVAR:
- CError_Error(CErrorStr121);
- break;
- default:
- CError_FATAL(4217);
- }
- } else if (pr.name_4) {
- if (copts.cplusplus)
- CError_Error(CErrorStr121);
- } else if (pr.x21) {
- CPrep_TokenStreamSetState(&state);
- CPrep_UnLex();
- tk = lex();
- r23 = 0;
- } else {
- CError_FATAL(4234);
- }
- }
- }
- default:
- switchDefault:
- if (!typetoken && !signedness && !typesize) {
- di->x4A = 1;
- if (r23) {
- if (!di->storageclass && !di->qual && !di->exportflags)
- CError_Error(CErrorStr121);
- else
- CError_Warning(CErrorStr349);
- }
- }
- if (typetoken >= 0)
- di->thetype = getthetype(typetoken, typesize, signedness);
- if (r24)
- di->x48 = 1;
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(NULL, di);
- return;
- case ';':
- if (!typetoken && !signedness && !typesize && copts.warn_emptydecl)
- CError_Warning(CErrorStr216);
- if (typetoken >= 0)
- di->thetype = getthetype(typetoken, typesize, signedness);
- return;
- }
-
- tk = lex();
-bailOut:
- r24 = 0;
- goto restart;
-}
-
-void CParser_RegisterNonGlobalClass(TypeClass *tclass) {
- struct ParentCleanup *p = lalloc(sizeof(struct ParentCleanup));
- p->next = cparser_parentcleanup;
- p->tclass = tclass;
- cparser_parentcleanup = p;
-}
-
-void CParser_RegisterSingleExprFunction(Object *func, ENode *expr) {
- struct SFuncList *p = lalloc(sizeof(struct SFuncList));
- p->next = cparser_sfunclist;
- p->func = func;
- p->obj = NULL;
- p->expr = expr;
- cparser_sfunclist = p;
-}
-
-void CParser_RegisterDummyCtorFunction(Object *func, Object *obj) {
- struct SFuncList *p = lalloc(sizeof(struct SFuncList));
- p->next = cparser_sfunclist;
- p->func = func;
- p->obj = obj;
- p->expr = NULL;
- cparser_sfunclist = p;
-}
-
-static void CParser_FreeLocalHeap(void) {
- struct SFuncList *s;
- struct ParentCleanup *p;
-
- while ((s = cparser_sfunclist)) {
- cparser_sfunclist = s->next;
- if (s->expr)
- CFunc_GenerateSingleExprFunc(s->func, s->expr);
- else
- CFunc_GenerateDummyCtorFunc(s->func, s->obj);
- }
-
- if (cparser_parentcleanup) {
- if (!CInline_CanFreeLHeap())
- return;
-
- for (p = cparser_parentcleanup; p; p = p->next) {
- while (!p->tclass->nspace->parent->is_global)
- p->tclass->nspace->parent = p->tclass->nspace->parent->parent;
- }
-
- cparser_parentcleanup = NULL;
- }
-
- freelheap();
-}
-
-static void CParser_GlobalCleanup(Boolean flag) {
- Boolean working;
-
- do {
- CParser_FreeLocalHeap();
- working = 0;
-
- if (flag) {
- if (cparser_classactions) {
- CClass_ClassAction(cparser_classactions->tclass);
- cparser_classactions = cparser_classactions->next;
- working = 1;
- } else if (CTempl_Instantiate()) {
- working = 1;
- }
- }
-
- while (CInline_GenerateDeferredFuncs()) {
- CParser_FreeLocalHeap();
- working = 1;
- }
- } while (working);
-}
-
-Boolean CParser_IsAnonymousUnion(DeclInfo *di, Boolean flag) {
- return IS_TYPE_CLASS(di->thetype) &&
- ((TYPE_CLASS(di->thetype)->mode == CLASS_MODE_UNION || (flag && copts.cpp_extensions))) &&
- IsTempName(TYPE_CLASS(di->thetype)->classname);
-}
-
-void CParser_CheckAnonymousUnion(DeclInfo *di, Boolean flag) {
- ObjMemberVar *ivar;
- Object *obj;
- Object *ivar_obj;
-
- if (!CParser_IsAnonymousUnion(di, 0)) {
- if (copts.warn_emptydecl) {
- switch (di->thetype->type) {
- case TYPEENUM:
- case TYPESTRUCT:
- case TYPECLASS:
- if (!di->storageclass && !di->qual)
- return;
- }
- CError_Warning(CErrorStr216);
- }
- return;
- }
-
- if (!flag && di->storageclass != TK_STATIC)
- CError_Error(CErrorStr177);
-
- if (flag && di->storageclass != TK_STATIC) {
- obj = CParser_NewLocalDataObject(di, 1);
- obj->name = CParser_GetUniqueName();
- CFunc_SetupLocalVarInfo(obj);
- obj->u.var.info->noregister = 1;
- } else {
- obj = CParser_NewGlobalDataObject(di);
- obj->name = CParser_GetUniqueName();
- obj->nspace = cscope_root;
- obj->sclass = TK_STATIC;
- CInit_DeclareData(obj, NULL, NULL, obj->type->size);
- }
-
- for (ivar = TYPE_CLASS(di->thetype)->ivars; ivar; ivar = ivar->next) {
- ivar_obj = galloc(sizeof(Object));
- *ivar_obj = *obj;
- ivar_obj->name = ivar->name;
- ivar_obj->type = ivar->type;
- ivar_obj->qual = ivar->qual;
- ivar_obj->datatype = DALIAS;
- ivar_obj->u.alias.object = obj;
- ivar_obj->u.alias.offset = ivar->offset;
- ivar_obj->u.alias.member = NULL;
- CScope_AddObject(cscope_current, ivar_obj->name, OBJ_BASE(ivar_obj));
- }
-}
-
-void CParser_NewCallBackAction(Object *obj, TypeClass *tclass) {
- CallbackAction *act = galloc(sizeof(CallbackAction));
- act->next = callbackactions;
- act->obj = obj;
- act->tclass = tclass;
- callbackactions = act;
- obj->flags = obj->flags | OBJECT_LAZY;
-}
-
-void CParser_NewClassAction(TypeClass *tclass) {
- struct ClassAction *act = galloc(sizeof(struct ClassAction));
- act->next = cparser_classactions;
- act->tclass = tclass;
- cparser_classactions = act;
-}
-
-void CParser_CallBackAction(Object *obj) {
- CallbackAction *act;
-
- for (act = callbackactions; act; act = act->next) {
- if (act->obj == obj) {
- CParser_NewClassAction(act->tclass);
- return;
- }
- }
-
- CError_FATAL(4551);
-}
-
-static Object *CParser_FindOverloadFunc(NameSpaceObjectList *list, TypeFunc *tfunc) {
- while (list) {
- if (list->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(list->object)->type))
- if (CParser_CompareArgLists(tfunc->args, TYPE_FUNC(OBJECT(list->object)->type)->args) == 1)
- return OBJECT(list->object);
- list = list->next;
- }
-
- return NULL;
-}
-
-Object *CParser_ParseObject(void) {
- DeclInfo di;
- NameResult pr;
- NameSpaceObjectList *list;
- Object *obj;
-
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 1);
- scandeclarator(&di);
-
- if (di.name && (list = CScope_FindObjectList(&pr, di.name))) {
- if (list->object->otype == OT_OBJECT) {
- if (IS_TYPE_FUNC(di.thetype))
- return CParser_FindOverloadFunc(list, TYPE_FUNC(di.thetype));
-
- if (is_typesame(di.thetype, OBJECT(list->object)->type) && OBJECT(list->object)->qual == di.qual)
- return OBJECT(list->object);
-
- obj = OBJECT(list->object);
- CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, di.thetype, di.qual);
- }
- }
-
- return NULL;
-}
-
-void CParser_ParseGlobalDeclaration(void) {
- DeclInfo di;
-
- if (tk) {
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, NULL);
- symdecloffset = cparser_fileoffset.tokenline;
- symdecltoken = *CPrep_CurStreamElement();
-
- memclrw(&di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(&di, 1);
- if (di.storageclass == TK_REGISTER || di.storageclass == TK_AUTO) {
- CError_Error(CErrorStr177);
- di.storageclass = 0;
- }
-
- if (tk != ';')
- scandeclaratorlist(&di);
- else
- CParser_CheckAnonymousUnion(&di, 0);
-
- tk = lex();
- } else {
- CError_Error(CErrorStr102);
- }
-}
-
-static void CParser_ParseLinkageSpecification(DeclInfo *di) {
- UInt32 qual;
- UInt8 r28;
-
- if (!strcmp(tkstring, "C") || !strcmp(tkstring, "Objective C")) {
- qual = 0;
- r28 = 1;
- } else if (!strcmp(tkstring, "C++")) {
- qual = 0;
- r28 = 0;
- } else if (!strcmp(tkstring, "Pascal")) {
- qual = Q_PASCAL;
- r28 = 1;
- } else {
- CError_Error(CErrorStr121);
- qual = 0;
- r28 = 1;
- }
-
- if ((tk = lex()) == '{') {
- while (1) {
- if ((tk = lex()) == 0) {
- CError_Error(CErrorStr130);
- return;
- }
-
- if (tk == '}')
- break;
-
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, NULL);
- symdecloffset = cparser_fileoffset.tokenline;
- symdecltoken = *CPrep_CurStreamElement();
-
- memclrw(di, sizeof(DeclInfo));
- di->is_extern_c = r28;
- di->qual = qual;
- CParser_ParseDeclaration(di);
- }
- } else if (tk == TK_EXTERN && copts.cpp_extensions && lookahead() == TK_STRING) {
- tk = lex();
- CParser_ParseLinkageSpecification(di);
- } else {
- memclrw(di, sizeof(DeclInfo));
- di->is_extern_c = r28;
- di->qual = qual;
- CParser_GetDeclSpecs(di, 1);
-
- if (di->storageclass != TK_TYPEDEF) {
- if (di->storageclass && copts.pedantic)
- CError_Warning(CErrorStr177);
- if (!di->storageclass)
- di->storageclass = TK_EXTERN;
- }
- if (copts.cpp_extensions)
- di->x48 = 0;
- if (tk != ';')
- scandeclaratorlist(di);
- }
-}
-
-static void CParser_ParseNameSpace(DeclInfo *di) {
- NameSpace *nspace;
- ObjNameSpace *objns;
- HashNameNode *name;
- Boolean flag;
- CScopeSave save;
- NameSpaceObjectList *list;
- NameSpaceList *nsl;
-
- if ((tk = lex()) == TK_IDENTIFIER) {
- name = tkidentifier;
- flag = 0;
- if ((tk = lex()) == '=') {
- CScope_ParseNameSpaceAlias(name);
- return;
- }
- } else {
- if (tk != '{') {
- CError_Error(CErrorStr107);
- return;
- }
- name = CParser_GetUnnamedNameSpaceName();
- flag = 1;
- }
-
- nspace = cscope_current;
- if (!(list = CScope_FindName(nspace, name))) {
- objns = galloc(sizeof(ObjNameSpace));
- memclrw(objns, sizeof(ObjNameSpace));
- objns->otype = OT_NAMESPACE;
- objns->access = ACCESSPUBLIC;
- if (flag) {
- nspace = CScope_NewListNameSpace(name, 1);
- nspace->is_unnamed = 1;
- nsl = galloc(sizeof(NameSpaceList));
- nsl->next = cscope_current->usings;
- nsl->nspace = nspace;
- cscope_current->usings = nsl;
- } else {
- nspace = CScope_NewHashNameSpace(name);
- if (cscope_current->is_unnamed)
- nspace->is_unnamed = 1;
- }
-
- nspace->parent = cscope_current;
- objns->nspace = nspace;
- CScope_AddObject(cscope_current, name, OBJ_BASE(objns));
- } else {
- if (list->object->otype != OT_NAMESPACE)
- CError_Error(CErrorStr320);
- else
- nspace = OBJ_NAMESPACE(list->object)->nspace;
- }
-
- if (tk != '{') {
- CError_Error(CErrorStr135);
- return;
- }
-
- CScope_SetNameSpaceScope(nspace, &save);
- while (1) {
- if ((tk = lex()) == 0) {
- CError_Error(CErrorStr130);
- break;
- }
-
- if (tk == '}')
- break;
-
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, NULL);
- symdecloffset = cparser_fileoffset.tokenline;
- symdecltoken = *CPrep_CurStreamElement();
-
- memclrw(di, sizeof(DeclInfo));
- CParser_ParseDeclaration(di);
- }
- CScope_RestoreScope(&save);
-}
-
-static void CParser_ParseDeclaration(DeclInfo *di) {
- switch (tk) {
- case TK_AT_INTERFACE:
- CObjC_ParseInterface();
- break;
- case TK_AT_IMPLEMENTATION:
- CObjC_ParseImplementation();
- break;
- case TK_AT_PROTOCOL:
- CObjC_ParseProtocol();
- break;
- case TK_AT_CLASS:
- CObjC_ParseClassDeclaration();
- break;
- case TK_NAMESPACE:
- CParser_ParseNameSpace(di);
- break;
- case TK_EXPORT:
- CError_Error(CErrorStr190);
- if ((tk = lex()) != TK_TEMPLATE) {
- CError_Error(CErrorStr121);
- return;
- }
- case TK_TEMPLATE:
- CTempl_Parse(NULL, 0);
- break;
- case TK_USING:
- if ((tk = lex()) == TK_NAMESPACE) {
- tk = lex();
- CScope_ParseUsingDirective(cscope_current);
- } else {
- CScope_ParseUsingDeclaration(cscope_current, 0, 0);
- }
- break;
- case TK_EXTERN:
- if (copts.cplusplus) {
- di->storageclass = TK_EXTERN;
- if ((tk = lex()) == TK_STRING) {
- CParser_ParseLinkageSpecification(di);
- break;
- }
- }
- default:
- CParser_GetDeclSpecs(di, 1);
- if ((di->storageclass == TK_REGISTER || di->storageclass == TK_AUTO) != 0) {
- CError_Error(CErrorStr177);
- di->storageclass = 0;
- }
- if (tk != ';')
- scandeclaratorlist(di);
- else
- CParser_CheckAnonymousUnion(di, 0);
- CParser_GlobalCleanup(0);
- }
-}
-
-void cparser(void) {
- DeclInfo di;
-
- if (copts.crippled && copts.optimizationlevel > 1) {
- CError_Warning(CErrorStr385);
- copts.optimizationlevel = 1;
- CodeGen_UpdateOptimizerOptions();
- CodeGen_UpdateBackEndOptions();
- }
-
- if ((tk = lex())) {
- do {
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, NULL);
- symdecloffset = cparser_fileoffset.tokenline;
- symdecltoken = *CPrep_CurStreamElement();
-
- memclrw(&di, sizeof(DeclInfo));
- CParser_ParseDeclaration(&di);
- } while (tk && (tk = lex()));
- } else {
- if (!copts.cplusplus && copts.ANSIstrict)
- CError_Error(CErrorStr102);
- }
-
- CInit_DefineTentativeData();
- copts.defer_codegen = 0;
- CParser_GlobalCleanup(1);
-
- if (cparamblkptr->precompile != 1) {
- CInline_Finish();
- CParser_GlobalCleanup(1);
- }
-
- CClass_GenThunks();
- if (cparamblkptr->precompile != 1)
- CObjC_GenerateModule();
-
- CSOM_Cleanup();
- CInit_DefineTentativeData();
-}
diff --git a/compiler_and_linker/unsorted/CPrec.c b/compiler_and_linker/unsorted/CPrec.c
deleted file mode 100644
index e61b96e..0000000
--- a/compiler_and_linker/unsorted/CPrec.c
+++ /dev/null
@@ -1,3482 +0,0 @@
-#include "compiler/CPrec.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CObjC.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CScope.h"
-#include "compiler/CSOM.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/enode.h"
-#include "compiler/objc.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/som.h"
-#include "compiler/templates.h"
-#include "compiler/types.h"
-#include "cos.h"
-#include "compiler/CCompiler.h"
-#include "compiler/InlineAsm.h"
-
-#define RESOLVE_BUFFER(offset) ((void *) (((char *) cprec_buffer) + ((uintptr_t) (offset))))
-#define RESOLVE_RAW_BUFFER(offset) ((void *) (((char *) cprec_rawbuffer) + ((uintptr_t) (offset))))
-#define RESOLVE_SAFE(offset) (!(offset) ? NULL : ((void *) (((char *) cprec_rawbuffer) + ((uintptr_t) (offset)))))
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct StaticData {
- struct StaticData *next;
- Object *object;
- void *buffer;
- OLinkList *links;
- SInt32 size;
-} StaticData;
-
-typedef struct Header {
- UInt32 magic;
- UInt16 version;
- UInt16 x6;
- char target;
- Boolean check_header_flags;
- Boolean cplusplus;
- UInt32 xC;
- UInt32 x10;
- UInt32 x14;
- UInt32 x18;
- UInt32 x1C;
- UInt32 x20;
- UInt32 x24;
- UInt32 x28;
- UInt32 x2C;
- UInt32 x30;
- UInt32 compressedPatchCount;
- UInt32 compressedPatchSize;
- UInt32 compressedPatchOffset;
- UInt32 builtinPatchSize;
- UInt32 builtinPatchOffset;
- UInt32 tokenStreamPatchSize;
- UInt32 tokenStreamPatchOffset;
- UInt32 root_names;
- NameSpaceList *usings;
- TemplClass *ctempl_templates;
- CSOMStub *csom_stubs;
- StaticData *cprec_staticdata;
- UInt32 uniqueID;
- CallbackAction *callbackactions;
- Type *cobjc_type_class;
- Type *cobjc_type_id;
- Type *cobjc_type_sel;
- ObjCSelector **cobjc_selhashtable;
- BClassList *cobjc_classdefs;
- ObjCProtocol *cobjc_protocols;
- UInt32 cobjc_selrefcount;
- UInt32 cobjc_classrefcount;
- UInt32 cobjc_stringcount;
- InitExpr *init_expressions;
- CI_Action *cinline_tactionlist;
- TemplateFunction *ctempl_templatefuncs;
- UInt32 x9C;
- UInt32 xA0;
- UInt32 xA4;
- UInt32 xA8;
- UInt32 xAC;
- UInt32 xB0;
- UInt32 xB4;
- UInt32 xB8;
- UInt32 xBC;
- UInt32 xC0;
- UInt32 xC4;
- UInt32 xC8;
- UInt32 xCC;
- UInt32 xD0;
- UInt32 xD4;
- UInt32 xD8;
- UInt32 xDC;
- UInt32 xE0;
- UInt32 xE4;
- HashNameNode *nametable[0x800];
- Macro *macrotable[0x800];
- NameSpaceName *root_nametable[0x400];
-} Header;
-
-typedef struct Patch {
- struct Patch *next;
- SInt32 offset;
-} Patch;
-
-typedef struct AddrPatch {
- struct AddrPatch *next;
- void *addr;
- void *value;
-} AddrPatch;
-
-typedef struct BuiltIn {
- void *target;
- SInt32 idx;
- Patch *patches;
-} BuiltIn;
-
-static Boolean cprec_exportargnames;
-static Boolean cprec_dowrite;
-static OSErr cprec_ioerror;
-static void *cprec_rawbuffer;
-static void *cprec_buffer;
-static SInt32 cprec_zero_offset;
-static SInt32 cprec_offset;
-static int cprec_builtins;
-static void **cprec_builtin_array;
-
-typedef struct TokenPatch {
- struct TokenPatch *next;
- TStreamElement *tokens;
- SInt32 count;
-} TokenPatch;
-static TokenPatch *cprec_tokenpatches;
-static StaticData *cprec_staticdata;
-
-typedef struct PointerHash {
- struct PointerHash *next;
- TypePointer *tptr;
- TypePointer *prec_tptr;
-} PointerHash;
-static PointerHash **cprec_pointerhash;
-
-static BuiltIn *cprec_builtin;
-static Patch *cprec_patch_list;
-static AddrPatch **cprec_addrhash;
-static Header *cprec_header;
-static GList cprec_glist;
-static short cprec_refnum;
-char *precomp_target_str;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// Assorted forward declarations
-static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace);
-static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj);
-static Object *CPrec_GetObjectPatch(Object *obj);
-static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj);
-static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *ivar);
-static Type *CPrec_GetTypePatch(Type *type);
-static ENode *CPrec_GetExpressionPatch(ENode *expr);
-static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth);
-static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst);
-static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg);
-static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol);
-static OSErr CPrec_FlushBufferCheck(void);
-
-void SetupPrecompiler(Boolean isPrecompiling) {
- cprec_refnum = 0;
- cprec_glist.data = NULL;
- cprec_header = NULL;
- cprec_staticdata = NULL;
- cprec_ioerror = noErr;
-}
-
-void CleanupPrecompiler(void) {
- if (cprec_refnum) {
- COS_FileClose(cprec_refnum);
- cprec_refnum = 0;
- }
-
- if (cprec_glist.data)
- FreeGList(&cprec_glist);
-}
-
-static OLinkList *CPrec_OLinkListCopy(OLinkList *list) {
- OLinkList *copy;
-
- if (!list)
- return NULL;
-
- copy = galloc(sizeof(OLinkList));
- *copy = *list;
- copy->next = CPrec_OLinkListCopy(copy->next);
- return copy;
-}
-
-void PreComp_StaticData(Object *obj, const void *data, OLinkList *links, SInt32 size) {
- StaticData *entry;
-
- if (obj->sclass != TK_STATIC && !(obj->qual & (Q_20000 | Q_WEAK)))
- CError_Error(CErrorStr180);
-
- entry = galloc(sizeof(StaticData));
- entry->object = obj;
- entry->size = size;
-
- entry->next = cprec_staticdata;
- cprec_staticdata = entry;
-
- if (data) {
- entry->buffer = galloc(obj->type->size);
- memcpy(entry->buffer, data, obj->type->size);
- } else {
- entry->buffer = NULL;
- }
-
- entry->links = CPrec_OLinkListCopy(links);
-}
-
-static void CPrec_InitAddressHashTable(void) {
- cprec_addrhash = lalloc(0x4000 * sizeof(AddrPatch *));
- memclrw(cprec_addrhash, 0x4000 * sizeof(AddrPatch *));
-}
-
-static void CPrec_InitPointerHashTable(void) {
- cprec_pointerhash = lalloc(0x400 * sizeof(PointerHash *));
- memclrw(cprec_pointerhash, 0x400 * sizeof(PointerHash *));
-}
-
-static int CPrec_AddressHashVal(void *addr) {
- UInt32 v = (UInt32) addr;
- return (
- v +
- ((unsigned char *) &v)[0] +
- ((unsigned char *) &v)[1] +
- ((unsigned char *) &v)[2] +
- ((unsigned char *) &v)[3]
- ) & 0x3FFF;
-}
-
-static AddrPatch *CPrec_FindAddrPatch(void *addr) {
- AddrPatch *scan;
-
- for (scan = cprec_addrhash[CPrec_AddressHashVal(addr)]; scan; scan = scan->next) {
- if (scan->addr == addr)
- return scan;
- }
-
- return NULL;
-}
-
-static AddrPatch *CPrec_NewAddrPatch(void *addr, void *value) {
- AddrPatch **loc;
- AddrPatch *patch;
-
- loc = cprec_addrhash + CPrec_AddressHashVal(addr);
- patch = lalloc(sizeof(AddrPatch));
- patch->addr = addr;
- patch->value = value;
- patch->next = *loc;
- *loc = patch;
- return patch;
-}
-
-static void CPrec_SetupBuiltInArray(void) {
- int count1, count2;
- Boolean flag;
- void **array;
-
-#define REG_BUILTIN(a) \
- if (!flag) { array[count2++] = (a); } else { count1++; }
-
- for (count2 = count1 = 0, flag = 1; ;) {
- REG_BUILTIN(cscope_root);
- REG_BUILTIN(&stvoid);
- REG_BUILTIN(&stbool);
- REG_BUILTIN(&stchar);
- REG_BUILTIN(&stsignedchar);
- REG_BUILTIN(&stunsignedchar);
- REG_BUILTIN(&stwchar);
- REG_BUILTIN(&stsignedshort);
- REG_BUILTIN(&stunsignedshort);
- REG_BUILTIN(&stsignedint);
- REG_BUILTIN(&stunsignedint);
- REG_BUILTIN(&stsignedlong);
- REG_BUILTIN(&stunsignedlong);
- REG_BUILTIN(&stsignedlonglong);
- REG_BUILTIN(&stunsignedlonglong);
- REG_BUILTIN(&stfloat);
- REG_BUILTIN(&stshortdouble);
- REG_BUILTIN(&stdouble);
- REG_BUILTIN(&stlongdouble);
- REG_BUILTIN(&elipsis);
- REG_BUILTIN(&oldstyle);
- REG_BUILTIN(&stillegal);
- REG_BUILTIN(&sttemplexpr);
- REG_BUILTIN(&stvoid);
- REG_BUILTIN(&void_ptr);
- REG_BUILTIN(&rt_func);
- REG_BUILTIN(&catchinfostruct);
- REG_BUILTIN(newh_func);
- REG_BUILTIN(delh_func);
- REG_BUILTIN(copy_func);
- REG_BUILTIN(clear_func);
- REG_BUILTIN(Rgtid_func);
- REG_BUILTIN(Rdync_func);
- REG_BUILTIN(rt_ptmf_cast);
- REG_BUILTIN(rt_ptmf_cmpr);
- REG_BUILTIN(rt_ptmf_test);
- REG_BUILTIN(rt_ptmf_call);
- REG_BUILTIN(rt_ptmf_scall);
- REG_BUILTIN(rt_ptmf_null);
- REG_BUILTIN(rt_som_glue1);
- REG_BUILTIN(rt_som_glue2);
- REG_BUILTIN(rt_som_glue3);
- REG_BUILTIN(rt_som_check);
- REG_BUILTIN(rt_som_new);
- REG_BUILTIN(rt_som_newcheck);
- REG_BUILTIN(rt_ptmf_call4);
- REG_BUILTIN(rt_ptmf_scall4);
- REG_BUILTIN(carr_func);
- REG_BUILTIN(cnar_func);
- REG_BUILTIN(darr_func);
- REG_BUILTIN(dnar_func);
- REG_BUILTIN(dnar3_func);
- REG_BUILTIN(Xgreg_func);
- REG_BUILTIN(Xthrw_func);
- REG_BUILTIN(Xicth_func);
- REG_BUILTIN(Xecth_func);
- REG_BUILTIN(Xunex_func);
- REG_BUILTIN(&stvectorunsignedchar);
- REG_BUILTIN(&stvectorsignedchar);
- REG_BUILTIN(&stvectorboolchar);
- REG_BUILTIN(&stvectorunsignedshort);
- REG_BUILTIN(&stvectorsignedshort);
- REG_BUILTIN(&stvectorboolshort);
- REG_BUILTIN(&stvectorunsignedlong);
- REG_BUILTIN(&stvectorsignedlong);
- REG_BUILTIN(&stvectorboollong);
- REG_BUILTIN(&stvectorfloat);
- REG_BUILTIN(&stvectorpixel);
-
- if (flag) {
- array = lalloc(sizeof(void *) * count1);
- cprec_builtin_array = array;
- cprec_builtins = count1;
- flag = 0;
- } else {
- return;
- }
- }
-}
-
-static void CPrec_SetupBuiltIn(void) {
- int x;
-
- CPrec_SetupBuiltInArray();
- cprec_builtin = lalloc(sizeof(BuiltIn) * cprec_builtins);
- memclrw(cprec_builtin, sizeof(BuiltIn) * cprec_builtins);
-
- for (x = 0; x < cprec_builtins; x++) {
- cprec_builtin[x].target = cprec_builtin_array[x];
- cprec_builtin[x].idx = ~x;
- CPrec_NewAddrPatch(cprec_builtin[x].target, (void *) cprec_builtin[x].idx);
- }
-}
-
-static void CPrec_NewPointerPatch(void *src, void *ptr) {
- if (cprec_dowrite) {
- Patch *patch = lalloc(sizeof(Patch));
- patch->offset = (SInt32) src;
- CError_ASSERT(507, (patch->offset & 0x80000001) == 0);
-
- if ((SInt32) ptr < 0) {
- ptr = (void *) ~((SInt32) ptr);
- CError_ASSERT(513, (SInt32) ptr < cprec_builtins);
-
- patch->next = cprec_builtin[(SInt32) ptr].patches;
- cprec_builtin[(SInt32) ptr].patches = patch;
- ptr = NULL;
- } else {
- patch->next = cprec_patch_list;
- cprec_patch_list = patch;
- }
-
- src = (void *)((char *) src - cprec_zero_offset);
- CError_ASSERT(525, (SInt32) src >= 0 && (SInt32) src <= cprec_glist.size);
- *((void **) (*cprec_glist.data + (SInt32) src)) = ptr;
- }
-}
-
-static void CPrec_ExistingPointerPatch(void *src, void *ptr) {
- if (cprec_dowrite) {
- AddrPatch *addrPatch;
- Patch *patch;
-
- CError_ASSERT(543, addrPatch = CPrec_FindAddrPatch(ptr));
-
- patch = lalloc(sizeof(Patch));
- patch->offset = (SInt32) src;
- patch->next = cprec_patch_list;
- cprec_patch_list = patch;
-
- CError_ASSERT(548, (patch->offset & 0x80000001) == 0);
-
- src = (void *)((char *) src - cprec_zero_offset);
- CError_ASSERT(552, (SInt32) src >= 0 && (SInt32) src <= cprec_glist.size);
- *((void **) (*cprec_glist.data + (SInt32) src)) = addrPatch->value;
- }
-}
-
-static void CPrec_NamePatch(void *src, HashNameNode *name) {
- name->id = 1;
- CPrec_ExistingPointerPatch(src, name);
-}
-
-static void *CPrec_AppendAlign(void) {
- if (cprec_dowrite) {
- while (cprec_offset & 3) {
- AppendGListByte(&cprec_glist, 0);
- ++cprec_offset;
- }
- }
-
- return (void *) cprec_offset;
-}
-
-static UInt32 CPrec_AppendByte(UInt8 v) {
- if (cprec_dowrite)
- AppendGListByte(&cprec_glist, v);
- return cprec_offset++;
-}
-
-static UInt32 CPrec_AppendWord16(UInt16 v) {
- UInt32 offset;
- if (cprec_dowrite)
- AppendGListWord(&cprec_glist, v);
- offset = cprec_offset;
- cprec_offset += 2;
- return offset;
-}
-
-static UInt32 CPrec_AppendWord32(UInt32 v) {
- UInt32 offset;
- if (cprec_dowrite)
- AppendGListLong(&cprec_glist, v);
- offset = cprec_offset;
- cprec_offset += 4;
- return offset;
-}
-
-static UInt32 CPrec_AppendPointer(void *v) {
- UInt32 offset;
- if (cprec_dowrite)
- AppendGListLong(&cprec_glist, (SInt32) v);
- offset = cprec_offset;
- cprec_offset += 4;
- return offset;
-}
-
-static UInt32 CPrec_AppendPointerPatch(void *v) {
- AddrPatch *addrPatch;
-
- if (v) {
- CError_ASSERT(644, addrPatch = CPrec_FindAddrPatch(v));
-
- if (cprec_dowrite) {
- Patch *patch = lalloc(sizeof(Patch));
- patch->offset = cprec_offset;
- patch->next = cprec_patch_list;
- cprec_patch_list = patch;
- CError_ASSERT(651, (patch->offset & 0x80000001) == 0);
- }
-
- return CPrec_AppendPointer(addrPatch->value);
- } else {
- return CPrec_AppendPointer(NULL);
- }
-}
-
-static void CPrec_AppendNamePatch(HashNameNode *name) {
- if (name) {
- CPrec_AppendPointerPatch(name);
- name->id = 1;
- }
-}
-
-static void CPrec_AppendString(const char *str) {
- int len = strlen(str) + 1;
- if (cprec_dowrite)
- AppendGListData(&cprec_glist, str, len);
- cprec_offset += len;
-}
-
-static void CPrec_AppendData(const void *data, int len) {
- if (cprec_dowrite)
- AppendGListData(&cprec_glist, data, len);
- cprec_offset += len;
-}
-
-static void CPrec_RawMemPatch(void *source, const void *data, int len) {
- void *ptr = CPrec_AppendAlign();
- CPrec_AppendData(data, len);
- CPrec_NewPointerPatch(source, ptr);
-}
-
-static void CPrec_DumpNameTable(void) {
- HashNameNode *name;
- int i;
- HashNameNode *p;
- HashNameNode *next;
-
- if (cprec_dowrite) {
- i = 0;
- do {
- name = name_hash_nodes[i];
- while (name && name->id == 0)
- name = name->next;
-
- if (name) {
- p = CPrec_AppendAlign();
- cprec_header->nametable[i] = p;
-
- while (1) {
- CPrec_NewAddrPatch(name, p);
- CPrec_AppendPointer(NULL);
- CPrec_AppendWord32(0);
- CPrec_AppendWord16(name->hashval);
- CPrec_AppendString(name->name);
-
- name = name->next;
- while (name && name->id == 0)
- name = name->next;
-
- if (!name)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&p->next, next);
- p = next;
- }
- }
- } while (++i < 0x800);
- } else {
- i = 0;
- do {
- if ((name = name_hash_nodes[i])) {
- p = CPrec_AppendAlign();
- while (1) {
- CPrec_NewAddrPatch(name, p);
- CPrec_AppendPointer(NULL);
- CPrec_AppendWord32(0);
- CPrec_AppendWord16(name->hashval);
- CPrec_AppendString(name->name);
-
- name = name->next;
- if (!name)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&p->next, next);
- p = next;
- }
- }
- } while (++i < 0x800);
- }
-}
-
-static void CPrec_DumpMacroTable(void) {
- Macro *macro;
- int i;
- int j;
- Macro *p;
- Macro *next;
-
- i = 0;
- do {
- for (macro = macrohashtable[i]; macro; macro = macro->next) {
- if (macro->c) {
- CPrec_NewAddrPatch(macro->c, (void *) cprec_offset);
- CPrec_AppendString(macro->c);
- }
- }
- } while (++i < 0x800);
-
- i = 0;
- do {
- macro = macrohashtable[i];
-
- if (macro) {
- p = CPrec_AppendAlign();
- if (cprec_dowrite)
- cprec_header->macrotable[i] = p;
-
- while (1) {
- CPrec_AppendPointer(NULL);
- CPrec_AppendNamePatch(macro->name);
- CPrec_AppendPointerPatch(macro->c);
- CPrec_AppendWord16(macro->xC);
- CPrec_AppendByte(macro->is_special);
- CPrec_AppendByte(macro->xF);
-
- for (j = 1; j < (macro->xC & 0x7FFF); j++)
- CPrec_AppendNamePatch(macro->names[j - 1]);
-
- macro = macro->next;
- if (!macro)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&p->next, next);
- p = next;
- }
- }
- } while (++i < 0x800);
-}
-
-static BClassList *CPrec_GetClassAccessPatch(BClassList *path) {
- AddrPatch *addrPatch;
- BClassList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(path)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(path, first);
-
- while (1) {
- CPrec_AppendData(path, sizeof(BClassList));
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(path->type));
- if (!path->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- path = path->next;
- }
-
- return first;
-}
-
-static int CPrec_PointerHash(TypePointer *type) {
- Type *target;
- int work;
- FuncArg *arg;
-
- work = type->qual;
- target = type->target;
-
-restart:
- switch (target->type) {
- case TYPECLASS:
- if (TYPE_CLASS(target)->classname)
- work += TYPE_CLASS(target)->classname->hashval;
- break;
- case TYPEENUM:
- if (TYPE_ENUM(target)->enumname)
- work += TYPE_ENUM(target)->enumname->hashval;
- target = TYPE_ENUM(target)->enumtype;
- work += 3;
- case TYPEINT:
- case TYPEFLOAT:
- work += TYPE_INTEGRAL(target)->integral;
- break;
- case TYPEPOINTER:
- work += TYPE_POINTER(target)->qual;
- target = TYPE_POINTER(target)->target;
- goto restart;
- case TYPEARRAY:
- work += target->size;
- target = TYPE_POINTER(target)->target;
- goto restart;
- case TYPEFUNC:
- work += TYPE_FUNC(target)->functype->type;
- work += TYPE_FUNC(target)->functype->size;
- for (arg = TYPE_FUNC(target)->args; arg; arg = arg->next) {
- if (arg->type) {
- work += arg->type->type;
- work += arg->type->size;
- }
- }
- break;
- }
-
- work += target->type + target->size;
- return (work + (work >> 24) + (work >> 16) + (work >> 8)) & 0x3FF;
-}
-
-static TypePointer *CPrec_GetTypePointerPatch(TypePointer *tptr) {
- TypePointer *p;
- int hash;
- PointerHash *phash;
- TypePointer *scan1;
- TypePointer *scan2;
-
- if (tptr->qual & Q_IS_OBJC_ID) {
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(tptr, p);
- CPrec_AppendData(tptr, sizeof(TypeObjCID));
- if (TYPE_OBJC_ID(tptr)->protocols)
- CPrec_NewPointerPatch(&TYPE_OBJC_ID(p)->protocols, CPrec_GetObjCProtocolListPatch(TYPE_OBJC_ID(tptr)->protocols));
- } else {
- if (!copts.faster_pch_gen && cprec_dowrite && tptr->size > 0) {
- hash = CPrec_PointerHash(tptr);
- for (phash = cprec_pointerhash[hash]; phash; phash = phash->next) {
- scan1 = tptr;
- scan2 = phash->tptr;
- check_again:
- if (scan1->type == scan2->type && scan1->size == scan2->size && scan1->qual == scan2->qual) {
- scan1 = TYPE_POINTER(TPTR_TARGET(scan1));
- scan2 = TYPE_POINTER(TPTR_TARGET(scan2));
- if (scan1->type == TYPEPOINTER && scan1->type == TYPEARRAY)
- goto check_again;
- if (scan1 == scan2)
- return phash->prec_tptr;
- }
- }
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(tptr, p);
-
- phash = lalloc(sizeof(PointerHash));
- phash->tptr = tptr;
- phash->prec_tptr = p;
- phash->next = cprec_pointerhash[hash];
- cprec_pointerhash[hash] = phash;
- } else {
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(tptr, p);
- }
-
- CPrec_AppendData(tptr, sizeof(TypePointer));
- }
-
- CPrec_NewPointerPatch(&p->target, CPrec_GetTypePatch(tptr->target));
- return p;
-}
-
-static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) {
- TypeEnum *p = CPrec_AppendAlign();
-
- CPrec_NewAddrPatch(type, p);
- CPrec_AppendData(type, sizeof(TypeEnum));
-
- if (type->nspace)
- CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(type->nspace));
- if (type->enumlist)
- CPrec_NewPointerPatch(&p->enumlist, CPrec_GetObjEnumConstPatch(type->enumlist));
-
- CPrec_NewPointerPatch(&p->enumtype, CPrec_GetTypePatch(type->enumtype));
- if (type->enumname)
- CPrec_NamePatch(&p->enumname, type->enumname);
-
- return p;
-}
-
-static TypeBitfield *CPrec_GetTypeBitfieldPatch(TypeBitfield *type) {
- TypeBitfield *p = CPrec_AppendAlign();
-
- CPrec_NewAddrPatch(type, p);
- CPrec_AppendData(type, sizeof(TypeBitfield));
- CPrec_NewPointerPatch(&p->bitfieldtype, CPrec_GetTypePatch(type->bitfieldtype));
-
- return p;
-}
-
-static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *tstruct) {
- StructMember *member;
- TypeStruct *p;
- StructMember *current, *next;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(tstruct, p);
- CPrec_AppendData(tstruct, sizeof(TypeStruct));
-
- if (tstruct->name)
- CPrec_NamePatch(&p->name, tstruct->name);
-
- if ((member = tstruct->members)) {
- current = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&p->members, current);
-
- while (1) {
- CPrec_AppendData(member, sizeof(StructMember));
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(member->type));
- CPrec_NamePatch(&current->name, member->name);
-
- if (!member->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
-
- member = member->next;
- }
- }
-
- return p;
-}
-
-static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) {
- ExceptSpecList *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
- while (exspec) {
- CPrec_AppendData(exspec, sizeof(ExceptSpecList));
- if (exspec->type)
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(exspec->type));
-
- if (!exspec->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- exspec = exspec->next;
- }
-
- return first;
-}
-
-static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) {
- FuncArg *first, *current, *next;
- AddrPatch *addrPatch;
-
- if ((addrPatch = CPrec_FindAddrPatch(lst)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- if (!includeNames)
- lst->name = NULL;
- CPrec_AppendData(lst, sizeof(FuncArg));
- if (includeNames && lst->name)
- CPrec_NamePatch(&current->name, lst->name);
-
- if (lst->dexpr)
- CPrec_NewPointerPatch(&current->dexpr, CPrec_GetExpressionPatch(lst->dexpr));
- if (lst->type)
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(lst->type));
- else
- CError_FATAL(1167);
-
- if (!lst->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(lst->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- }
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- lst = lst->next;
- CPrec_NewAddrPatch(lst, next);
- }
-
- return first;
-}
-
-static TypeFunc *CPrec_GetTypeFuncPatch(TypeFunc *type) {
- TypeFunc *p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(type, p);
-
- CPrec_AppendData(type, (type->flags & FUNC_METHOD) ? sizeof(TypeMemberFunc) : sizeof(TypeFunc));
-
- CPrec_NewPointerPatch(&p->functype, CPrec_GetTypePatch(type->functype));
- if (type->args)
- CPrec_NewPointerPatch(&p->args, CPrec_GetArgListPatch(type->args, (type->flags & FUNC_IS_TEMPL_ANY) != 0));
- if (type->exspecs)
- CPrec_NewPointerPatch(&p->exspecs, CPrec_GetExceptSpecPatch(type->exspecs));
- if (type->flags & FUNC_METHOD)
- CPrec_NewPointerPatch(&TYPE_METHOD(p)->theclass, CPrec_GetTypePatch((Type *) TYPE_METHOD(type)->theclass));
-
- return p;
-}
-
-static TypeMemberPointer *CPrec_GetTypeMemberPointerPatch(TypeMemberPointer *type) {
- TypeMemberPointer *p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(type, p);
-
- CPrec_AppendData(type, sizeof(TypeMemberPointer));
-
- CPrec_NewPointerPatch(&p->ty1, CPrec_GetTypePatch(type->ty1));
- CPrec_NewPointerPatch(&p->ty2, CPrec_GetTypePatch(type->ty2));
-
- return p;
-}
-
-static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) {
- TypeTemplDep *p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(type, p);
-
- CPrec_AppendData(type, sizeof(TypeTemplDep));
-
- switch (type->dtype) {
- case TEMPLDEP_ARGUMENT:
- break;
- case TEMPLDEP_QUALNAME:
- CPrec_NewPointerPatch(&p->u.qual.type, CPrec_GetTypeTemplDepPatch(type->u.qual.type));
- CPrec_NamePatch(&p->u.qual.name, type->u.qual.name);
- break;
- case TEMPLDEP_TEMPLATE:
- CPrec_NewPointerPatch(&p->u.templ.templ, CPrec_GetTypePatch((Type *) type->u.templ.templ));
- CPrec_NewPointerPatch(&p->u.templ.args, CPrec_GetTemplateArgPatch(type->u.templ.args));
- break;
- case TEMPLDEP_ARRAY:
- CPrec_NewPointerPatch(&p->u.array.type, CPrec_GetTypePatch(type->u.array.type));
- CPrec_NewPointerPatch(&p->u.array.index, CPrec_GetExpressionPatch(type->u.array.index));
- break;
- case TEMPLDEP_QUALTEMPL:
- CPrec_NewPointerPatch(&p->u.qualtempl.type, CPrec_GetTypeTemplDepPatch(type->u.qualtempl.type));
- CPrec_NewPointerPatch(&p->u.qualtempl.args, CPrec_GetTemplateArgPatch(type->u.qualtempl.args));
- break;
- case TEMPLDEP_BITFIELD:
- CPrec_NewPointerPatch(&p->u.bitfield.type, CPrec_GetTypePatch(type->u.bitfield.type));
- CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size));
- break;
- default:
- CError_FATAL(1295);
- }
-
- return p;
-}
-
-static ClassList *CPrec_GetClassListPatch(ClassList *cl) {
- AddrPatch *addrPatch;
- ClassList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(cl)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(cl, first);
-
- do {
- CPrec_AppendData(cl, sizeof(ClassList));
- CPrec_NewPointerPatch(&current->base, CPrec_GetTypePatch((Type *) cl->base));
-
- if (!cl->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(cl->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- cl = cl->next;
- }
- } while (1);
-
- return first;
-}
-
-static VClassList *CPrec_GetVClassListPatch(VClassList *vcl) {
- VClassList *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(vcl, sizeof(VClassList));
- CPrec_NewPointerPatch(&current->base, CPrec_GetTypePatch((Type *) vcl->base));
-
- if (!vcl->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- vcl = vcl->next;
- } while (1);
-
- return first;
-}
-
-static ClassFriend *CPrec_GetClassFriendPatch(ClassFriend *cf) {
- ClassFriend *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(cf, sizeof(ClassFriend));
- if (cf->isclass)
- CPrec_NewPointerPatch(&current->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass));
- else
- CPrec_NewPointerPatch(&current->u.theclass, CPrec_GetObjectPatch(cf->u.obj));
-
- if (!cf->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- cf = cf->next;
- } while (1);
-
- return first;
-}
-
-static BClassList *CPrec_GetBClassListPatch(BClassList *bcl) {
- BClassList *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(bcl, sizeof(BClassList));
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch((Type *) bcl->type));
-
- if (!bcl->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- bcl = bcl->next;
- } while (1);
-
- return first;
-}
-
-static VTable *CPrec_GetVTablePatch(VTable *vtbl) {
- VTable *p = CPrec_AppendAlign();
- CPrec_AppendData(vtbl, sizeof(VTable));
-
- if (vtbl->object)
- CPrec_NewPointerPatch(&p->object, CPrec_GetObjectPatch(vtbl->object));
- if (vtbl->owner)
- CPrec_NewPointerPatch(&p->owner, CPrec_GetTypePatch((Type *) vtbl->owner));
-
- return p;
-}
-
-static SOMReleaseOrder *CPrec_GetSOMReleaseOrderPatch(SOMReleaseOrder *sro) {
- SOMReleaseOrder *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(sro, sizeof(SOMReleaseOrder));
- CPrec_NamePatch(&current->name, sro->name);
- if (!sro->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- sro = sro->next;
- } while (1);
-
- return first;
-}
-
-static SOMInfo *CPrec_GetSOMInfoPatch(SOMInfo *som) {
- SOMInfo *p = CPrec_AppendAlign();
- CPrec_AppendData(som, sizeof(SOMInfo));
-
- if (som->metaclass)
- CPrec_NewPointerPatch(&p->metaclass, CPrec_GetTypePatch((Type *) som->metaclass));
- if (som->classdataobject)
- CPrec_NewPointerPatch(&p->classdataobject, CPrec_GetObjectPatch(som->classdataobject));
- if (som->order)
- CPrec_NewPointerPatch(&p->order, CPrec_GetSOMReleaseOrderPatch(som->order));
-
- return p;
-}
-
-static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) {
- ObjCMethodArg *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(arg, sizeof(ObjCMethod));
- if (arg->selector)
- CPrec_NamePatch(&current->selector, arg->selector);
- if (arg->name)
- CPrec_NamePatch(&current->name, arg->name);
- if (arg->type)
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(arg->type));
-
- if (!arg->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- arg = arg->next;
- } while (1);
-
- return first;
-}
-
-static ObjCMethodList *CPrec_GetObjCMethodListPatch(ObjCMethodList *lst) {
- AddrPatch *addrPatch;
- ObjCMethodList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(lst)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(lst, first);
-
- do {
- CPrec_AppendData(lst, sizeof(ObjCMethodList));
- if (lst->method)
- CPrec_NewPointerPatch(&current->method, CPrec_GetObjCMethodPatch(lst->method));
-
- if (!lst->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(lst->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- lst = lst->next;
- CPrec_NewAddrPatch(lst, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjCSelector *CPrec_GetObjCSelectorPatch(ObjCSelector *sel) {
- AddrPatch *addrPatch;
- ObjCSelector *current, *first, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(sel)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(sel, first);
-
- do {
- CPrec_AppendData(sel, sizeof(ObjCSelector));
- if (sel->selobject)
- CPrec_NewPointerPatch(&current->selobject, CPrec_GetObjectPatch(sel->selobject));
- CPrec_NamePatch(&current->name, sel->name);
- if (sel->methods)
- CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodListPatch(sel->methods));
-
- if (!sel->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(sel->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- sel = sel->next;
- CPrec_NewAddrPatch(sel, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth) {
- // does not match - affected by weirdness where the arg goes into r31 instead of r28
- AddrPatch *addrPatch;
- ObjCMethod *current, *first, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(meth)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(meth, first);
-
- do {
- CPrec_AppendData(meth, sizeof(ObjCMethod));
- if (meth->object)
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(meth->object));
- if (meth->functype)
- CPrec_NewPointerPatch(&current->functype, CPrec_GetTypePatch((Type *) meth->functype));
- if (meth->selector)
- CPrec_NewPointerPatch(&current->selector, CPrec_GetObjCSelectorPatch(meth->selector));
- if (meth->return_type)
- CPrec_NewPointerPatch(&current->return_type, CPrec_GetTypePatch(meth->return_type));
- if (meth->selector_args)
- CPrec_NewPointerPatch(&current->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args));
-
- if (!meth->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(meth->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- meth = meth->next;
- CPrec_NewAddrPatch(meth, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjCProtocol *CPrec_GetObjCProtocolPatch(ObjCProtocol *prot) {
- AddrPatch *addrPatch;
- ObjCProtocol *current, *first, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(prot)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(prot, first);
-
- do {
- CPrec_AppendData(prot, sizeof(ObjCProtocol));
- CPrec_NamePatch(&current->name, prot->name);
- if (prot->protocols)
- CPrec_NewPointerPatch(&current->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols));
- if (prot->methods)
- CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodPatch(prot->methods));
- if (prot->object)
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(prot->object));
-
- if (!prot->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(prot->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- prot = prot->next;
- CPrec_NewAddrPatch(prot, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst) {
- AddrPatch *addrPatch;
- ObjCProtocolList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(lst)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(lst, first);
-
- do {
- CPrec_AppendData(lst, sizeof(ObjCProtocolList));
- CPrec_NewPointerPatch(&current->protocol, CPrec_GetObjCProtocolPatch(lst->protocol));
-
- if (!lst->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- lst = lst->next;
- } while (1);
-
- return first;
-}
-
-static ObjCCategory *CPrec_GetObjCCategoryPatch(ObjCCategory *cat) {
- AddrPatch *addrPatch;
- ObjCCategory *current, *first, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(cat)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(cat, first);
-
- do {
- CPrec_AppendData(cat, sizeof(ObjCCategory));
- CPrec_NamePatch(&current->name, cat->name);
- if (cat->protocols)
- CPrec_NewPointerPatch(&current->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols));
- if (cat->methods)
- CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodPatch(cat->methods));
-
- if (!cat->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(cat->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- cat = cat->next;
- CPrec_NewAddrPatch(cat, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjCInfo *CPrec_GetObjCInfoPatch(ObjCInfo *info) {
- ObjCInfo *p = CPrec_AppendAlign();
- CPrec_AppendData(info, sizeof(ObjCInfo));
-
- if (info->classobject)
- CPrec_NewPointerPatch(&p->classobject, CPrec_GetObjectPatch(info->classobject));
- if (info->metaobject)
- CPrec_NewPointerPatch(&p->metaobject, CPrec_GetObjectPatch(info->metaobject));
- if (info->classrefobj)
- CPrec_NewPointerPatch(&p->classrefobj, CPrec_GetObjectPatch(info->classrefobj));
- if (info->methods)
- CPrec_NewPointerPatch(&p->methods, CPrec_GetObjCMethodPatch(info->methods));
- if (info->protocols)
- CPrec_NewPointerPatch(&p->protocols, CPrec_GetObjCProtocolListPatch(info->protocols));
- if (info->categories)
- CPrec_NewPointerPatch(&p->categories, CPrec_GetObjCCategoryPatch(info->categories));
-
- return p;
-}
-
-static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) {
- TemplArg *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(arg, sizeof(TemplArg));
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (arg->data.typeparam.type)
- CPrec_NewPointerPatch(&current->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type));
- break;
- case TPT_NONTYPE:
- if (arg->data.paramdecl.expr)
- CPrec_NewPointerPatch(&current->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr));
- break;
- case TPT_TEMPLATE:
- if (arg->data.ttargtype)
- CPrec_NewPointerPatch(&current->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype));
- break;
- default:
- CError_FATAL(1879);
- }
-
- if (!arg->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- arg = arg->next;
- } while (1);
-
- return first;
-}
-
-static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) {
- // register swap issues
- TemplParam *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(param, sizeof(TemplParam));
- if (param->name)
- CPrec_NamePatch(&current->name, param->name);
-
- switch (param->pid.type) {
- case TPT_TYPE:
- if (param->data.typeparam.type)
- CPrec_NewPointerPatch(&current->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type));
- break;
- case TPT_NONTYPE:
- CPrec_NewPointerPatch(&current->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type));
- if (param->data.paramdecl.defaultarg)
- CPrec_NewPointerPatch(&current->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg));
- break;
- case TPT_TEMPLATE:
- if (param->data.templparam.plist)
- CPrec_NewPointerPatch(&current->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist));
- CError_ASSERT(1953, !param->data.templparam.defaultarg);
- break;
- default:
- CError_FATAL(1958);
- }
-
- if (!param->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- param = param->next;
- } while (1);
-
- return first;
-}
-
-static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 count) {
- TStreamElement elem;
- TStreamElement *first, *current, *scan;
- SInt32 x;
-
- scan = tokens;
- x = 0;
- while (x < count) {
- elem = *scan;
- memclrw(scan, sizeof(TStreamElement));
-
- scan->tokentype = elem.tokentype;
- switch (elem.tokentype) {
- case TK_IDENTIFIER:
- scan->data.tkidentifier = elem.data.tkidentifier;
- break;
- case TK_INTCONST:
- scan->subtype = elem.subtype;
- scan->data.tkintconst = elem.data.tkintconst;
- break;
- case TK_FLOATCONST:
- scan->subtype = elem.subtype;
- scan->data.tkfloatconst = elem.data.tkfloatconst;
- break;
- case TK_STRING:
- case TK_STRING_WIDE:
- scan->subtype = elem.subtype;
- scan->data.tkstring = elem.data.tkstring;
- break;
- }
- x++;
- scan++;
- }
-
- first = current = CPrec_AppendAlign();
- CPrec_AppendData(tokens, count * sizeof(TStreamElement));
-
- if (cprec_dowrite) {
- TokenPatch *tp = lalloc(sizeof(TokenPatch));
- tp->tokens = current;
- tp->count = count;
- tp->next = cprec_tokenpatches;
- cprec_tokenpatches = tp;
- }
-
- x = 0;
- while (x < count) {
- switch (tokens->tokentype) {
- case TK_IDENTIFIER:
- CPrec_NamePatch(&current->data.tkidentifier, tokens->data.tkidentifier);
- break;
- case TK_INTCONST:
- case TK_FLOATCONST:
- break;
- case TK_STRING:
- case TK_STRING_WIDE:
- CPrec_RawMemPatch(&current->data.tkstring.data, tokens->data.tkstring.data, tokens->data.tkstring.size);
- break;
- case TK_EOL:
- break;
- default:
- if (tokens->tokentype < 0)
- CError_FATAL(2063);
- }
- x++;
- tokens++;
- current++;
- }
-
- return first;
-}
-
-static TemplFuncInstance *CPrec_GetTemplFuncInstancePatch(TemplFuncInstance *inst) {
- AddrPatch *addrPatch;
- TemplFuncInstance *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(inst)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(inst, first);
-
- do {
- CPrec_AppendData(inst, sizeof(TemplFuncInstance));
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(inst->object));
- CPrec_NewPointerPatch(&current->args, CPrec_GetTemplateArgPatch(inst->args));
-
- if (!inst->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(inst->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- inst = inst->next;
- CPrec_NewAddrPatch(inst, next);
- }
- } while (1);
-
- return first;
-}
-
-static TemplateMember *CPrec_GetTemplateMemberPatch(TemplateMember *memb) {
- TemplateMember *current, *first, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- memclrw(&memb->fileoffset, sizeof(FileOffsetInfo));
- memb->srcfile = NULL;
- memb->startoffset = 0;
- memb->endoffset = 0;
-
- CPrec_AppendData(memb, sizeof(TemplateMember));
- if (memb->params)
- CPrec_NewPointerPatch(&current->params, CPrec_GetTemplateParamPatch(memb->params));
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(memb->object));
- if (memb->stream.firsttoken)
- CPrec_NewPointerPatch(&current->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens));
-
- if (!memb->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- memb = memb->next;
- } while (1);
-
- return first;
-}
-
-static TemplPartialSpec *CPrec_GetTemplPartialSpecPatch(TemplPartialSpec *pspec) {
- TemplPartialSpec *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(pspec, sizeof(TemplPartialSpec));
- if (pspec->templ)
- CPrec_NewPointerPatch(&current->templ, CPrec_GetTypePatch((Type *) pspec->templ));
- if (pspec->args)
- CPrec_NewPointerPatch(&current->args, CPrec_GetTemplateArgPatch(pspec->args));
-
- if (!pspec->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- pspec = pspec->next;
- } while (1);
-
- return first;
-}
-
-static TemplateFriend *CPrec_GetTemplateFriendPatch(TemplateFriend *frnd) {
- TemplateFriend *p;
-
- memclrw(&frnd->fileoffset, sizeof(FileOffsetInfo));
- p = CPrec_AppendAlign();
- CPrec_AppendData(frnd, sizeof(TemplateFriend));
-
- if (frnd->decl.thetype)
- CPrec_NewPointerPatch(&p->decl.thetype, CPrec_GetTypePatch(frnd->decl.thetype));
- if (frnd->decl.nspace)
- CPrec_NewPointerPatch(&p->decl.nspace, CPrec_GetNameSpacePatch(frnd->decl.nspace));
- if (frnd->decl.name)
- CPrec_NamePatch(&p->decl.name, frnd->decl.name);
- if (frnd->decl.expltargs)
- CPrec_NewPointerPatch(&p->decl.expltargs, CPrec_GetTemplateArgPatch(frnd->decl.expltargs));
- if (frnd->stream.firsttoken)
- CPrec_NewPointerPatch(&p->stream.firsttoken, CPrec_GetTStreamPatch(frnd->stream.firsttoken, frnd->stream.tokens));
-
- return p;
-}
-
-static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) {
- // register swap issue
- TemplateAction *current, *first, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- memclrw(&act->source_ref, sizeof(TStreamElement));
- CPrec_AppendData(act, sizeof(TemplateAction));
-
- switch (act->type) {
- case TAT_NESTEDCLASS:
- CPrec_NewPointerPatch(&current->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype));
- break;
- case TAT_ENUMTYPE:
- CPrec_NewPointerPatch(&current->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype));
- break;
- case TAT_FRIEND:
- CPrec_NewPointerPatch(&current->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend));
- break;
- case TAT_ENUMERATOR:
- CPrec_NewPointerPatch(&current->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst));
- if (act->u.enumerator.initexpr)
- CPrec_NewPointerPatch(&current->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr));
- break;
- case TAT_BASE:
- CPrec_NewPointerPatch(&current->u.base.type, CPrec_GetTypePatch(act->u.base.type));
- if (act->u.base.insert_after)
- CPrec_NewPointerPatch(&current->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after));
- break;
- case TAT_OBJECTINIT:
- CPrec_NewPointerPatch(&current->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object));
- CPrec_NewPointerPatch(&current->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr));
- break;
- case TAT_USINGDECL:
- CPrec_NewPointerPatch(&current->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type));
- break;
- case TAT_OBJECTDEF:
- CPrec_NewPointerPatch(&current->u.refobj, CPrec_GetObjBasePatch(act->u.refobj));
- break;
- default:
- CError_FATAL(2410);
- }
-
- if (!act->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- act = act->next;
- } while (1);
-
- return first;
-}
-
-static TemplateFunction *CPrec_GetTemplateFunctionPatch(TemplateFunction *tf) {
- // the same cursed register swaps
- AddrPatch *addrPatch;
- TemplateFunction *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(tf)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(tf, first);
-
- do {
- memclrw(&tf->deftoken, sizeof(TStreamElement));
- tf->srcfile = NULL;
- tf->startoffset = 0;
- tf->endoffset = 0;
-
- CPrec_AppendData(tf, sizeof(TemplateFunction));
- if (tf->unk4)
- CPrec_NewPointerPatch(&current->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4));
- CPrec_NamePatch(&current->name, tf->name);
- if (tf->params)
- CPrec_NewPointerPatch(&current->params, CPrec_GetTemplateParamPatch(tf->params));
- if (tf->stream.firsttoken)
- CPrec_NewPointerPatch(&current->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens));
- CPrec_NewPointerPatch(&current->tfunc, CPrec_GetObjectPatch(tf->tfunc));
- if (tf->instances)
- CPrec_NewPointerPatch(&current->instances, CPrec_GetTemplFuncInstancePatch(tf->instances));
-
- if (!tf->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(tf->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- tf = tf->next;
- CPrec_NewAddrPatch(tf, next);
- }
- } while (1);
-
- return first;
-}
-
-static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) {
- TypeClass *first, *current, *next;
- Boolean hasNextTempl, hasNextTemplInst;
- first = current = CPrec_AppendAlign();
-
- do_over:
- hasNextTempl = hasNextTemplInst = 0;
- CPrec_NewAddrPatch(tclass, current);
-
- if (tclass->flags & CLASS_IS_TEMPL) {
- // template class
- CPrec_AppendData(tclass, sizeof(TemplClass));
- if (TEMPL_CLASS(tclass)->next)
- hasNextTempl = 1;
- if (TEMPL_CLASS(tclass)->templ_parent)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ_parent));
- if (TEMPL_CLASS(tclass)->inst_parent)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->inst_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->inst_parent));
- if (TEMPL_CLASS(tclass)->templ__params)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params));
- if (TEMPL_CLASS(tclass)->members)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->members, CPrec_GetTemplateMemberPatch(TEMPL_CLASS(tclass)->members));
- if (TEMPL_CLASS(tclass)->instances)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->instances, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->instances));
- if (TEMPL_CLASS(tclass)->pspec_owner)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspec_owner, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->pspec_owner));
- if (TEMPL_CLASS(tclass)->pspecs)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspecs, CPrec_GetTemplPartialSpecPatch(TEMPL_CLASS(tclass)->pspecs));
- if (TEMPL_CLASS(tclass)->actions)
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->actions, CPrec_GetTemplateActionPatch(TEMPL_CLASS(tclass)->actions));
- } else if (tclass->flags & CLASS_IS_TEMPL_INST) {
- // template class instance
- CPrec_AppendData(tclass, sizeof(TemplClassInst));
- if (TEMPL_CLASS_INST(tclass)->next)
- hasNextTemplInst = 1;
- if (TEMPL_CLASS_INST(tclass)->parent)
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->parent));
- if (TEMPL_CLASS_INST(tclass)->templ)
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->templ));
- if (TEMPL_CLASS_INST(tclass)->inst_args)
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->inst_args, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->inst_args));
- if (TEMPL_CLASS_INST(tclass)->oargs)
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->oargs, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->oargs));
- } else {
- // base
- CPrec_AppendData(tclass, sizeof(TypeClass));
- }
-
- if (tclass->nspace)
- CPrec_NewPointerPatch(&current->nspace, CPrec_GetNameSpacePatch(tclass->nspace));
- if (tclass->classname)
- CPrec_NamePatch(&current->classname, tclass->classname);
- if (tclass->bases)
- CPrec_NewPointerPatch(&current->bases, CPrec_GetClassListPatch(tclass->bases));
- if (tclass->vbases)
- CPrec_NewPointerPatch(&current->vbases, CPrec_GetVClassListPatch(tclass->vbases));
- if (tclass->ivars)
- CPrec_NewPointerPatch(&current->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars));
- if (tclass->friends)
- CPrec_NewPointerPatch(&current->friends, CPrec_GetClassFriendPatch(tclass->friends));
- if (tclass->vtable)
- CPrec_NewPointerPatch(&current->vtable, CPrec_GetVTablePatch(tclass->vtable));
- if (tclass->sominfo)
- CPrec_NewPointerPatch(&current->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo));
- if (tclass->objcinfo)
- CPrec_NewPointerPatch(&current->objcinfo, CPrec_GetObjCInfoPatch(tclass->objcinfo));
-
- if (hasNextTempl) {
- AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS(tclass)->next);
- if (!addrPatch) {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, next);
- current = next;
- tclass = (TypeClass *) TEMPL_CLASS(tclass)->next;
- goto do_over;
- } else {
- CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, addrPatch->value);
- }
- }
-
- if (hasNextTemplInst) {
- AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS_INST(tclass)->next);
- if (!addrPatch) {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, next);
- current = next;
- tclass = (TypeClass *) TEMPL_CLASS_INST(tclass)->next;
- goto do_over;
- } else {
- CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, addrPatch->value);
- }
- }
-
- return first;
-}
-
-static Type *CPrec_GetTypePatch(Type *type) {
- AddrPatch *addrPatch = CPrec_FindAddrPatch(type);
- if (addrPatch)
- return addrPatch->value;
-
- switch (type->type) {
- case TYPEPOINTER:
- case TYPEARRAY:
- return (Type *) CPrec_GetTypePointerPatch(TYPE_POINTER(type));
- case TYPEENUM:
- return (Type *) CPrec_GetTypeEnumPatch(TYPE_ENUM(type));
- case TYPEBITFIELD:
- return (Type *) CPrec_GetTypeBitfieldPatch(TYPE_BITFIELD(type));
- case TYPESTRUCT:
- return (Type *) CPrec_GetTypeStructPatch(TYPE_STRUCT(type));
- case TYPEFUNC:
- return (Type *) CPrec_GetTypeFuncPatch(TYPE_FUNC(type));
- case TYPEMEMBERPOINTER:
- return (Type *) CPrec_GetTypeMemberPointerPatch(TYPE_MEMBER_POINTER(type));
- case TYPETEMPLATE:
- return (Type *) CPrec_GetTypeTemplDepPatch(TYPE_TEMPLATE(type));
- case TYPECLASS:
- return (Type *) CPrec_GetTypeClassPatch(TYPE_CLASS(type));
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPELABEL:
- case TYPEOBJCID:
- case TYPETEMPLDEPEXPR:
- default:
- CError_FATAL(2796);
- return NULL;
- }
-}
-
-static ExceptionAction *CPrec_GetExceptionPatch(ExceptionAction *exc) {
- ExceptionAction *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
-repeat:
- CPrec_AppendData(exc, sizeof(ExceptionAction));
- switch (exc->type) {
- case EAT_DESTROYLOCAL:
- CPrec_NewPointerPatch(&current->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor));
- break;
- case EAT_DESTROYLOCALCOND:
- CPrec_NewPointerPatch(&current->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor));
- break;
- case EAT_DESTROYLOCALOFFSET:
- CPrec_NewPointerPatch(&current->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor));
- break;
- case EAT_DESTROYLOCALPOINTER:
- CPrec_NewPointerPatch(&current->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor));
- break;
- case EAT_DESTROYLOCALARRAY:
- CPrec_NewPointerPatch(&current->data.destroy_local_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_array.dtor));
- break;
- case EAT_DESTROYPARTIALARRAY:
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- CPrec_NewPointerPatch(&current->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor));
- break;
- case EAT_DESTROYMEMBERCOND:
- CPrec_NewPointerPatch(&current->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor));
- break;
- case EAT_DESTROYMEMBERARRAY:
- CPrec_NewPointerPatch(&current->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor));
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- CPrec_NewPointerPatch(&current->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc));
- break;
- case EAT_DELETEPOINTERCOND:
- CPrec_NewPointerPatch(&current->data.delete_pointer_cond.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer_cond.deletefunc));
- break;
- case EAT_CATCHBLOCK:
- if (exc->data.catch_block.catch_typeid) {
- CPrec_NewPointerPatch(&current->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid));
- CPrec_NewPointerPatch(&current->data.catch_block.catch_type, CPrec_GetTypePatch(exc->data.catch_block.catch_type));
- }
- break;
- case EAT_ACTIVECATCHBLOCK:
- break;
- case EAT_SPECIFICATION:
- if (exc->data.specification.unexp_id) {
- int x;
- char *ptrs;
- ptrs = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->data.specification.unexp_id, ptrs);
- CPrec_AppendData(exc->data.specification.unexp_id, sizeof(Object *) * exc->data.specification.unexp_ids);
- for (x = 0; x < exc->data.specification.unexp_ids; x++) {
- CPrec_NewPointerPatch(ptrs + x * sizeof(Object *), CPrec_GetObjectPatch(exc->data.specification.unexp_id[x]));
- }
- }
- break;
- case EAT_TERMINATE:
- break;
- default:
- CError_FATAL(2905);
- }
-
- if (exc->prev) {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->prev, next);
- current = next;
- exc = exc->prev;
- goto repeat;
- }
- return first;
-}
-
-static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) {
- ENodeList *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(lst, sizeof(ENodeList));
- CPrec_NewPointerPatch(&current->node, CPrec_GetExpressionPatch(lst->node));
-
- if (!lst->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- lst = lst->next;
- } while (1);
-
- return first;
-}
-
-static EMemberInfo *CPrec_GetEMemberInfoPatch(EMemberInfo *emember) {
- EMemberInfo *p;
-
- CError_FATAL(2953);
-
- p = CPrec_AppendAlign();
- CPrec_AppendData(emember, sizeof(EMemberInfo));
-
- if (emember->path)
- CPrec_NewPointerPatch(&p->path, CPrec_GetClassAccessPatch(emember->path));
- if (emember->expr)
- CPrec_NewPointerPatch(&p->expr, CPrec_GetExpressionPatch(emember->expr));
- CError_ASSERT(2968, !emember->templargs);
- CPrec_NewPointerPatch(&p->list, CPrec_GetNameSpaceObjectListPatch(emember->list));
-
- return p;
-}
-
-static ENode *CPrec_GetExpressionPatch(ENode *expr) {
- ENode *p;
-
- if (ENODE_IS(expr, ETEMPLDEP) && expr->data.templdep.subtype == TDE_SOURCEREF)
- expr->data.templdep.u.sourceref.token = NULL;
-
- p = CPrec_AppendAlign();
- CPrec_AppendData(expr, sizeof(ENode));
-
- CPrec_NewPointerPatch(&p->rtype, CPrec_GetTypePatch(expr->rtype));
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- CPrec_NewPointerPatch(&p->data.monadic, CPrec_GetExpressionPatch(expr->data.monadic));
- break;
- ENODE_CASE_DIADIC_ALL:
- CPrec_NewPointerPatch(&p->data.diadic.left, CPrec_GetExpressionPatch(expr->data.diadic.left));
- CPrec_NewPointerPatch(&p->data.diadic.right, CPrec_GetExpressionPatch(expr->data.diadic.right));
- break;
- case ECOND:
- CPrec_NewPointerPatch(&p->data.cond.cond, CPrec_GetExpressionPatch(expr->data.cond.cond));
- CPrec_NewPointerPatch(&p->data.cond.expr1, CPrec_GetExpressionPatch(expr->data.cond.expr1));
- CPrec_NewPointerPatch(&p->data.cond.expr2, CPrec_GetExpressionPatch(expr->data.cond.expr2));
- break;
- case ESTRINGCONST:
- CPrec_RawMemPatch(&p->data.string.data, expr->data.string.data, expr->data.string.size);
- break;
- case EOBJREF:
- CPrec_NewPointerPatch(&p->data.objref, CPrec_GetObjectPatch(expr->data.objref));
- break;
- case EOBJLIST:
- CPrec_NewPointerPatch(&p->data.objlist.list, CPrec_GetNameSpaceObjectListPatch(expr->data.objlist.list));
- CError_ASSERT(3043, !expr->data.objlist.templargs);
- if (expr->data.objlist.name)
- CPrec_NamePatch(&p->data.objlist.name, expr->data.objlist.name);
- break;
- case EMFPOINTER:
- CPrec_NewPointerPatch(&p->data.mfpointer.accessnode, CPrec_GetExpressionPatch(expr->data.mfpointer.accessnode));
- CPrec_NewPointerPatch(&p->data.mfpointer.mfpointer, CPrec_GetExpressionPatch(expr->data.mfpointer.mfpointer));
- break;
- case ENULLCHECK:
- CPrec_NewPointerPatch(&p->data.nullcheck.nullcheckexpr, CPrec_GetExpressionPatch(expr->data.nullcheck.nullcheckexpr));
- CPrec_NewPointerPatch(&p->data.nullcheck.condexpr, CPrec_GetExpressionPatch(expr->data.nullcheck.condexpr));
- break;
- case ETEMP:
- CPrec_NewPointerPatch(&p->data.temp.type, CPrec_GetTypePatch(expr->data.temp.type));
- break;
- case EFUNCCALL:
- case EFUNCCALLP:
- CPrec_NewPointerPatch(&p->data.funccall.funcref, CPrec_GetExpressionPatch(expr->data.funccall.funcref));
- CPrec_NewPointerPatch(&p->data.funccall.functype, CPrec_GetTypePatch(TYPE(expr->data.funccall.functype)));
- if (expr->data.funccall.args)
- CPrec_NewPointerPatch(&p->data.funccall.args, CPrec_GetExpressionListPatch(expr->data.funccall.args));
- break;
- case EMEMBER:
- CPrec_NewPointerPatch(&p->data.emember, CPrec_GetEMemberInfoPatch(expr->data.emember));
- break;
- case ETEMPLDEP:
- switch (expr->data.templdep.subtype) {
- case TDE_PARAM:
- break;
- case TDE_SIZEOF:
- case TDE_ALIGNOF:
- CPrec_NewPointerPatch(&p->data.templdep.u.typeexpr.type, CPrec_GetTypePatch(expr->data.templdep.u.typeexpr.type));
- break;
- case TDE_CAST:
- if (expr->data.templdep.u.cast.args)
- CPrec_NewPointerPatch(&p->data.templdep.u.cast.args, CPrec_GetExpressionListPatch(expr->data.templdep.u.cast.args));
- CPrec_NewPointerPatch(&p->data.templdep.u.cast.type, CPrec_GetTypePatch(expr->data.templdep.u.cast.type));
- break;
- case TDE_QUALNAME:
- CPrec_NamePatch(&p->data.templdep.u.qual.name, expr->data.templdep.u.qual.name);
- CPrec_NewPointerPatch(&p->data.templdep.u.qual.type, CPrec_GetTypePatch(TYPE(expr->data.templdep.u.qual.type)));
- break;
- case TDE_OBJ:
- CPrec_NewPointerPatch(&p->data.templdep.u.obj, CPrec_GetObjectPatch(expr->data.templdep.u.obj));
- break;
- case TDE_SOURCEREF:
- CPrec_NewPointerPatch(&p->data.templdep.u.sourceref.expr, CPrec_GetExpressionPatch(expr->data.templdep.u.sourceref.expr));
- break;
- case TDE_ADDRESS_OF:
- CPrec_NewPointerPatch(&p->data.templdep.u.monadic, CPrec_GetExpressionPatch(expr->data.templdep.u.monadic));
- break;
- default:
- CError_FATAL(3136);
- }
- break;
- case EINTCONST:
- case EFLOATCONST:
- case EPRECOMP:
- case EARGOBJ:
- case ELOCOBJ:
- case ELABEL:
- case EINSTRUCTION:
- case EVECTOR128CONST:
- break;
- default:
- CError_FATAL(3142);
- }
-
- return p;
-}
-
-static CI_Switch *CPrec_GetSwitchInfoPatch(CI_Switch *si) {
- CI_Switch *p = CPrec_AppendAlign();
- CPrec_AppendData(si, sizeof(CI_Switch) + sizeof(CI_SwitchCase) * (si->numcases - 1));
-
- CPrec_NewPointerPatch(&p->expr, CPrec_GetExpressionPatch(si->expr));
- CPrec_NewPointerPatch(&p->unkSwitch8, CPrec_GetTypePatch(si->unkSwitch8));
- return p;
-}
-
-static InlineAsm *CPrec_GetInlineAsmPatch(InlineAsm *ia, SInt32 size) {
- InlineAsm *p;
- SInt32 index;
- SInt32 offset;
- Object *object;
-
- p = CPrec_AppendAlign();
- CPrec_AppendData(ia, size);
-
- index = 0;
- while (1) {
- object = InlineAsm_GetObjectOffset(ia, index, &offset);
- if (!object)
- break;
-
- object = CPrec_GetObjectPatch(object);
- CPrec_NewPointerPatch((char *) p + offset, object);
- index++;
- }
-
- return p;
-}
-
-static CI_Statement *CPrec_GetStatementPatch(CI_Statement *stmt, short count) {
- short i;
- CI_Statement *first, *current;
-
- for (i = 0; i < count; i++) {
- stmt[i].sourcefilepath = NULL;
- stmt[i].sourceoffset = -1;
- }
-
- first = current = CPrec_AppendAlign();
- CPrec_AppendData(stmt, sizeof(CI_Statement) * count);
-
- for (i = 0; i < count; i++) {
- if (stmt->dobjstack)
- CPrec_NewPointerPatch(&current->dobjstack, CPrec_GetExceptionPatch(stmt->dobjstack));
-
- switch (stmt->type) {
- case ST_EXPRESSION:
- case ST_RETURN:
- case ST_BEGINCATCH:
- case ST_ENDCATCH:
- case ST_ENDCATCHDTOR:
- if (stmt->u.expr)
- CPrec_NewPointerPatch(&current->u.expr, CPrec_GetExpressionPatch(stmt->u.expr));
- break;
- case ST_IFGOTO:
- case ST_IFNGOTO:
- CPrec_NewPointerPatch(&current->u.ifgoto.expr, CPrec_GetExpressionPatch(stmt->u.ifgoto.expr));
- break;
- case ST_SWITCH:
- CPrec_NewPointerPatch(&current->u.switchdata, CPrec_GetSwitchInfoPatch(stmt->u.switchdata));
- break;
- case ST_ASM:
- CPrec_NewPointerPatch(&current->u.asmdata.data, CPrec_GetInlineAsmPatch(stmt->u.asmdata.data, stmt->u.asmdata.size));
- break;
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- break;
- default:
- CError_FATAL(3261);
- }
-
- current++;
- stmt++;
- }
-
- return first;
-}
-
-static CI_Var *CPrec_GetLocObjectPatch(CI_Var *obj, short count) {
- CI_Var *first, *current;
- short i;
-
- first = current = CPrec_AppendAlign();
- CPrec_AppendData(obj, sizeof(CI_Var) * count);
-
- for (i = 0; i < count; i++) {
- CPrec_NamePatch(&current->name, obj->name);
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(obj->type));
- current++;
- obj++;
- }
-
- return first;
-}
-
-static CI_FuncData *CPrec_GetInlineFuncPatch(CI_FuncData *ifunc) {
- CI_FuncData *p;
-
- memclrw(&ifunc->fileoffset, sizeof(FileOffsetInfo));
- ifunc->symdecloffset = 0;
- ifunc->functionbodyoffset = 0;
- ifunc->functionbodypath = NULL;
- ifunc->symdeclend = 0;
-
- p = CPrec_AppendAlign();
- CPrec_AppendData(ifunc, sizeof(CI_FuncData));
-
- if (ifunc->numarguments)
- CPrec_NewPointerPatch(&p->arguments, CPrec_GetLocObjectPatch(ifunc->arguments, ifunc->numarguments));
- if (ifunc->numlocals)
- CPrec_NewPointerPatch(&p->locals, CPrec_GetLocObjectPatch(ifunc->locals, ifunc->numlocals));
- if (ifunc->numstatements)
- CPrec_NewPointerPatch(&p->statements, CPrec_GetStatementPatch(ifunc->statements, ifunc->numstatements));
-
- return p;
-}
-
-static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) {
- AddrPatch *addrPatch;
- ObjEnumConst *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(obj)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(obj, first);
-
- do {
- CPrec_AppendData(obj, sizeof(ObjEnumConst));
- if (cprec_dowrite) {
- CError_ASSERT(3349, obj->access != 255);
- obj->access = 255;
- }
- CPrec_NamePatch(&current->name, obj->name);
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch( obj->type));
-
- if (!obj->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(obj->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- obj = obj->next;
- CPrec_NewAddrPatch(obj, next);
- }
- } while (1);
-
- return first;
-}
-
-static ObjType *CPrec_GetObjTypePatch(ObjType *obj) {
- AddrPatch *addrPatch;
- ObjType *p;
-
- if ((addrPatch = CPrec_FindAddrPatch(obj)))
- return addrPatch->value;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(obj, p);
- CPrec_AppendData(obj, sizeof(ObjType));
- CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type));
- return p;
-}
-
-static ObjTypeTag *CPrec_GetObjTypeTagPatch(ObjTypeTag *obj) {
- AddrPatch *addrPatch;
- ObjTypeTag *p;
-
- if ((addrPatch = CPrec_FindAddrPatch(obj)))
- return addrPatch->value;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(obj, p);
- CPrec_AppendData(obj, sizeof(ObjTypeTag));
- CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type));
- return p;
-}
-
-static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) {
- AddrPatch *addrPatch;
- ObjNameSpace *p;
-
- if ((addrPatch = CPrec_FindAddrPatch(obj)))
- return addrPatch->value;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(obj, p);
- CPrec_AppendData(obj, sizeof(ObjNameSpace));
- CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace));
- return p;
-}
-
-static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *ivar) {
- AddrPatch *addrPatch;
- ObjMemberVar *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(ivar)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(ivar, first);
-
- while (1) {
- if (ivar->has_path) {
- CPrec_AppendData(ivar, sizeof(ObjMemberVarPath));
- if (OBJ_MEMBER_VAR_PATH(ivar)->path)
- CPrec_NewPointerPatch(
- &OBJ_MEMBER_VAR_PATH(current)->path,
- CPrec_GetClassAccessPatch(OBJ_MEMBER_VAR_PATH(ivar)->path));
- } else {
- CPrec_AppendData(ivar, sizeof(ObjMemberVar));
- }
-
- if (ivar->name)
- CPrec_NamePatch(&current->name, ivar->name);
- CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(ivar->type));
-
- if (!ivar->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(ivar->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- }
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
-
- current = next;
- ivar = ivar->next;
- CPrec_NewAddrPatch(ivar, current);
- }
-
- return first;
-}
-
-static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) {
- DefArgCtorInfo *p = CPrec_AppendAlign();
- CPrec_AppendData(dac, sizeof(DefArgCtorInfo));
- CPrec_NewPointerPatch(&p->default_func, CPrec_GetObjectPatch(dac->default_func));
- CPrec_NewPointerPatch(&p->default_arg, CPrec_GetExpressionPatch(dac->default_arg));
- return p;
-}
-
-static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) {
- InlineXRef *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(ix, sizeof(InlineXRef) + sizeof(XRefOffset) * (ix->numxrefs - 1));
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(ix->object));
-
- if (!ix->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- ix = ix->next;
- } while (1);
-
- return first;
-}
-
-static Object *CPrec_GetObjectPatch(Object *obj) {
- AddrPatch *addrPatch;
- Object *p;
-
- if (CWUserBreak(cparams.context) != cwNoErr)
- CError_UserBreak();
-
- if ((addrPatch = CPrec_FindAddrPatch(obj)))
- return addrPatch->value;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(obj, p);
-
- obj->toc = NULL;
-
- if ((obj->qual & Q_IS_TEMPLATED) && obj->datatype != DALIAS) {
- CPrec_AppendData(obj, sizeof(ObjectTemplated));
- CPrec_NewPointerPatch(&OBJECT_TEMPL(p)->parent, CPrec_GetObjectPatch(OBJECT_TEMPL(obj)->parent));
- } else {
- CPrec_AppendData(obj, sizeof(Object));
- }
-
- if (obj->nspace)
- CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace));
- if (obj->name)
- CPrec_NamePatch(&p->name, obj->name);
- CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type));
-
- switch (obj->datatype) {
- case DABSOLUTE:
- break;
-
- case DLOCAL:
- CError_FATAL(3580);
- break;
-
- case DFUNC:
- case DVFUNC:
- if (IS_TEMPL_FUNC(obj->type))
- CPrec_NewPointerPatch(&p->u.func.u.templ, CPrec_GetTemplateFunctionPatch(obj->u.func.u.templ));
- else if ((obj->qual & Q_INLINE) && obj->u.func.u.ifuncdata)
- CPrec_NewPointerPatch(&p->u.func.u.ifuncdata, CPrec_GetInlineFuncPatch(obj->u.func.u.ifuncdata));
-
- if (obj->u.func.defargdata)
- CPrec_NewPointerPatch(&p->u.func.defargdata, CPrec_GetDefArgCtorInfoPatch(obj->u.func.defargdata));
- if (obj->u.func.linkname)
- CPrec_NamePatch(&p->u.func.linkname, obj->u.func.linkname);
- if (obj->u.func.inst)
- CPrec_NewPointerPatch(&p->u.func.inst, CPrec_GetTemplFuncInstancePatch(obj->u.func.inst));
- break;
-
- case DDATA:
- CError_ASSERT(3622, !obj->u.data.info);
- if (obj->qual & Q_INLINE_DATA) {
- switch (obj->type->type) {
- case TYPEINT:
- case TYPEENUM:
- case TYPEPOINTER:
- break;
- case TYPEFLOAT:
- CPrec_RawMemPatch(&p->u.data.u.floatconst, obj->u.data.u.floatconst, sizeof(Float));
- break;
- default:
- CError_FATAL(3638);
- }
- }
- if (obj->u.data.linkname)
- CPrec_NamePatch(&p->u.data.linkname, obj->u.data.linkname);
- break;
-
- case DINLINEFUNC:
- CPrec_RawMemPatch(&p->u.ifunc.data, obj->u.ifunc.data, obj->u.ifunc.size);
- if (obj->u.ifunc.xrefs)
- CPrec_NewPointerPatch(&p->u.ifunc.xrefs, CPrec_GetInlineXRefPatch(obj->u.ifunc.xrefs));
- break;
-
- case DALIAS:
- CPrec_NewPointerPatch(&p->u.alias.object, CPrec_GetObjectPatch(obj->u.alias.object));
- if (obj->u.alias.member)
- CPrec_NewPointerPatch(&p->u.alias.member, CPrec_GetClassAccessPatch(obj->u.alias.member));
- break;
-
- default:
- CError_FATAL(3677);
- }
-
- if (cprec_dowrite)
- obj->datatype = -1;
-
- return p;
-}
-
-static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) {
- switch (obj->otype) {
- default:
- CError_FATAL(3694);
- case OT_ENUMCONST:
- return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj);
- case OT_TYPE:
- return (ObjBase *) CPrec_GetObjTypePatch((ObjType *) obj);
- case OT_TYPETAG:
- return (ObjBase *) CPrec_GetObjTypeTagPatch((ObjTypeTag *) obj);
- case OT_NAMESPACE:
- return (ObjBase *) CPrec_GetObjNameSpacePatch((ObjNameSpace *) obj);
- case OT_MEMBERVAR:
- return (ObjBase *) CPrec_GetObjMemberVarPatch((ObjMemberVar *) obj);
- case OT_OBJECT:
- return (ObjBase *) CPrec_GetObjectPatch((Object *) obj);
- }
-}
-
-static ObjectList *CPrec_GetObjectListPatch(ObjectList *ol) {
- AddrPatch *addrPatch;
- ObjectList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(ol)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(ol, first);
-restart:
- CPrec_AppendData(ol, sizeof(ObjectList));
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(ol->object));
- if (ol->next) {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- ol = ol->next;
- goto restart;
- }
-
- return first;
-}
-
-static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol) {
- AddrPatch *addrPatch;
- NameSpaceObjectList *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(nsol)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(nsol, first);
-
- do {
- CPrec_AppendData(nsol, sizeof(NameSpaceObjectList));
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjBasePatch(nsol->object));
-
- if (!nsol->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- nsol = nsol->next;
- CPrec_NewAddrPatch(nsol, next);
- }
- } while (1);
-
- return first;
-}
-
-static NameSpaceName *CPrec_GetNameSpaceNamePatch(NameSpaceName *nsn, Boolean flag) {
- AddrPatch *addrPatch;
- NameSpaceName *first, *current, *next;
-
- if ((addrPatch = CPrec_FindAddrPatch(nsn)))
- return addrPatch->value;
-
- first = current = CPrec_AppendAlign();
- CPrec_NewAddrPatch(nsn, first);
-
- do {
- CPrec_AppendData(nsn, sizeof(NameSpaceName));
- CPrec_NamePatch(&current->name, nsn->name);
- CPrec_NewPointerPatch(&current->first.object, CPrec_GetObjBasePatch(nsn->first.object));
- if (nsn->first.next)
- CPrec_NewPointerPatch(&current->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next));
-
- if (!nsn->next)
- break;
-
- if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) {
- CPrec_NewPointerPatch(&current->next, addrPatch->value);
- break;
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- nsn = nsn->next;
- CPrec_NewAddrPatch(nsn, next);
- }
- } while (!flag || !cprec_dowrite || CPrec_FlushBufferCheck() == noErr);
-
- return first;
-}
-
-static NameSpaceList *CPrec_GetNameSpaceListPatch(NameSpaceList *nsl) {
- NameSpaceList *first, *current, *next;
- first = current = CPrec_AppendAlign();
-
- do {
- CPrec_AppendData(nsl, sizeof(NameSpaceList));
- CPrec_NewPointerPatch(&current->nspace, CPrec_GetNameSpacePatch(nsl->nspace));
-
- if (!nsl->next)
- break;
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- nsl = nsl->next;
- } while (1);
-
- return first;
-}
-
-static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) {
- NameSpace *p;
- AddrPatch *addrPatch;
-
- if ((addrPatch = CPrec_FindAddrPatch(nspace)))
- return addrPatch->value;
-
- p = CPrec_AppendAlign();
- CPrec_NewAddrPatch(nspace, p);
- CPrec_AppendData(nspace, sizeof(NameSpace));
-
- if (nspace->parent)
- CPrec_NewPointerPatch(&p->parent, CPrec_GetNameSpacePatch(nspace->parent));
- if (nspace->name)
- CPrec_NamePatch(&p->name, nspace->name);
- if (nspace->usings)
- CPrec_NewPointerPatch(&p->usings, CPrec_GetNameSpaceListPatch(nspace->usings));
- if (nspace->theclass)
- CPrec_NewPointerPatch(&p->theclass, CPrec_GetTypePatch((Type *) nspace->theclass));
-
- if (nspace->is_hash) {
- char *hash;
- int i;
- hash = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&p->data.hash, hash);
- CPrec_AppendData(nspace->data.hash, sizeof(NameSpaceName *) * 1024);
- for (i = 0; i < 1024; i++) {
- if (nspace->data.hash[i])
- CPrec_NewPointerPatch(hash + (i * sizeof(NameSpaceName *)), CPrec_GetNameSpaceNamePatch(nspace->data.hash[i], 0));
- }
- } else if (nspace->data.list) {
- CPrec_NewPointerPatch(&p->data.list, CPrec_GetNameSpaceNamePatch(nspace->data.list, 0));
- }
-
- return p;
-}
-
-static void CPrec_DumpRootNameSpace(void) {
- NameSpaceList *nslist;
- NameSpaceName *nsname;
- int i;
-
- CError_ASSERT(3905, cscope_root->is_hash);
-
- if (cscope_root->usings) {
- nslist = CPrec_GetNameSpaceListPatch(cscope_root->usings);
- if (cprec_dowrite)
- cprec_header->usings = nslist;
- }
-
- if (cprec_dowrite)
- cprec_header->root_names = cscope_root->names;
-
- i = 0;
- do {
- if (cscope_root->data.hash[i]) {
- nsname = CPrec_GetNameSpaceNamePatch(cscope_root->data.hash[i], 1);
- if (cprec_dowrite) {
- if (cprec_ioerror != noErr)
- break;
- cprec_header->root_nametable[i] = nsname;
- }
- }
- } while (++i < 0x400);
-}
-
-static CSOMStub *CPrec_GetSOMPatch(CSOMStub *stub) {
- CSOMStub *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- CPrec_AppendData(stub, sizeof(CSOMStub));
-
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(stub->object));
- CPrec_NewPointerPatch(&current->tclass, CPrec_GetTypePatch(TYPE(stub->tclass)));
-
- if (!stub->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- stub = stub->next;
- }
-
- return first;
-}
-
-static OLinkList *CPrec_GetOLinkPatch(OLinkList *olink) {
- OLinkList *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- CPrec_AppendData(olink, sizeof(OLinkList));
-
- CPrec_NewPointerPatch(&current->obj, CPrec_GetObjectPatch(olink->obj));
-
- if (!olink->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- olink = olink->next;
- }
-
- return first;
-}
-
-static StaticData *CPrec_GetStaticDataPatch(StaticData *sd) {
- StaticData *current, *first, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- CPrec_AppendData(sd, sizeof(StaticData));
-
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(sd->object));
- if (sd->buffer)
- CPrec_RawMemPatch(&current->buffer, sd->buffer, sd->object->type->size);
- if (sd->links)
- CPrec_NewPointerPatch(&current->links, CPrec_GetOLinkPatch(sd->links));
-
- if (!sd->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- sd = sd->next;
- }
-
- return first;
-}
-
-static CallbackAction *CPrec_GetCallbackPatch(CallbackAction *ca) {
- CallbackAction *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- CPrec_AppendData(ca, sizeof(CallbackAction));
-
- CPrec_NewPointerPatch(&current->obj, CPrec_GetObjectPatch(ca->obj));
- CPrec_NewPointerPatch(&current->tclass, CPrec_GetTypePatch(TYPE(ca->tclass)));
-
- if (!ca->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- ca = ca->next;
- }
-
- return first;
-}
-
-static ObjCSelector **CPrec_GetSelHashTablePatch(ObjCSelector **table) {
- ObjCSelector **first, **current;
- int i;
-
- first = current = CPrec_AppendAlign();
- CPrec_AppendData(table, sizeof(ObjCSelector *) * 0x400);
-
- for (i = 0; i < 0x400; i++) {
- if (*table)
- CPrec_NewPointerPatch(current, CPrec_GetObjCSelectorPatch(*table));
- table++;
- current++;
- }
-
- return first;
-}
-
-static InitExpr *CPrec_GetIExpressionPatch(InitExpr *initexpr) {
- InitExpr *first, *current, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- CPrec_AppendData(initexpr, sizeof(InitExpr));
-
- CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(initexpr->object));
- CPrec_NewPointerPatch(&current->expr, CPrec_GetExpressionPatch(initexpr->expr));
-
- if (!initexpr->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- initexpr = initexpr->next;
- }
-
- return first;
-}
-
-static CI_Action *CPrec_GetInlineActionPatch(CI_Action *act) {
- CI_Action *current, *first, *next;
-
- first = current = CPrec_AppendAlign();
- while (1) {
- if (act->actiontype == CI_ActionInlineFunc)
- memclrw(&act->u.inlinefunc.fileoffset, sizeof(FileOffsetInfo));
-
- CPrec_AppendData(act, sizeof(CI_Action));
-
- CPrec_NewPointerPatch(&current->obj, CPrec_GetObjectPatch(act->obj));
-
- switch (act->actiontype) {
- case CI_ActionInlineFunc:
- if (act->u.inlinefunc.stream.firsttoken)
- CPrec_NewPointerPatch(
- &current->u.inlinefunc.stream.firsttoken,
- CPrec_GetTStreamPatch(act->u.inlinefunc.stream.firsttoken, act->u.inlinefunc.stream.tokens));
- if (act->u.inlinefunc.tclass)
- CPrec_NewPointerPatch(&current->u.inlinefunc.tclass, CPrec_GetTypePatch(TYPE(act->u.inlinefunc.tclass)));
- break;
-
- case CI_ActionMemberFunc:
- CPrec_NewPointerPatch(&current->u.memberfunc.templ, CPrec_GetTypePatch(TYPE(act->u.memberfunc.templ)));
- CPrec_NewPointerPatch(&current->u.memberfunc.inst, CPrec_GetTypePatch(TYPE(act->u.memberfunc.inst)));
- CPrec_NewPointerPatch(&current->u.memberfunc.tmemb, CPrec_GetTemplateMemberPatch(act->u.memberfunc.tmemb));
- break;
-
- case CI_ActionTemplateFunc:
- CPrec_NewPointerPatch(&current->u.templatefunc.func, CPrec_GetTemplateFunctionPatch(act->u.templatefunc.func));
- CPrec_NewPointerPatch(&current->u.templatefunc.inst, CPrec_GetTemplFuncInstancePatch(act->u.templatefunc.inst));
- break;
-
- case CI_ActionDefaultFunc:
- break;
-
- default:
- CError_FATAL(4177);
- }
-
- if (!act->next)
- break;
-
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- act = act->next;
- }
-
- return first;
-}
-
-static void CPrec_GenerateBuiltinPatches(void) {
- int x;
- int y;
- Patch *scan;
-
- for (x = 0; x < cprec_builtins; x++) {
- y = 0;
- for (scan = cprec_builtin[x].patches; scan; scan = scan->next)
- ++y;
-
- if (y) {
- CPrec_AppendWord32(y);
- CPrec_AppendWord32(x);
- for (scan = cprec_builtin[x].patches; scan; scan = scan->next)
- CPrec_AppendWord32(scan->offset);
- }
- }
-
- CPrec_AppendWord32(0);
-}
-
-static void CPrec_GenerateTokenStreamPatches(void) {
- TokenPatch *scan;
-
- for (scan = cprec_tokenpatches; scan; scan = scan->next) {
- CPrec_AppendWord32((UInt32) scan->tokens);
- CPrec_AppendWord32((UInt32) scan->count);
- }
- CPrec_AppendWord32(0);
-}
-
-static OSErr CPrec_CompressWrite(const char *data, SInt32 size) {
- char buf[2048 + 256];
- OSErr err;
- int bufpos = 0;
- int blockstart;
- int c;
- const char *p = data;
- const char *end = data + size;
-
- for (;;) {
- if (p < end) {
- if (!*p) {
- c = 224;
- while (!*p && p < end && c < 256) {
- c++;
- p++;
- }
- buf[bufpos++] = c - 1;
- } else {
- blockstart = bufpos++;
- c = 0;
- while (p < end && c < 224) {
- if (!p[0] && !p[1]) {
- break;
- } else {
- buf[bufpos++] = *(p++);
- c++;
- }
- }
- buf[blockstart] = c - 1;
- }
- }
-
- if (p >= end || bufpos > 2048) {
- if ((err = COS_FileWrite(cprec_refnum, buf, bufpos)))
- return err;
-
- if (p >= end)
- break;
- else
- bufpos = 0;
- }
- }
-
- return noErr;
-}
-
-static OSErr CPrec_FlushRawBuffer(void) {
- OSErr err;
-
- if (cprec_dowrite) {
- CPrec_AppendAlign();
- cprec_zero_offset += cprec_glist.size;
- COS_LockHandle(cprec_glist.data);
- err = CPrec_CompressWrite(*cprec_glist.data, cprec_glist.size);
- COS_UnlockHandle(cprec_glist.data);
- cprec_glist.size = 0;
-
- return err;
- } else {
- return noErr;
- }
-}
-
-static OSErr CPrec_FlushBufferCheck(void) {
- static SInt32 flushmax;
- OSErr err;
-
- if (cprec_glist.size > flushmax)
- flushmax = cprec_glist.size;
-
- if (cprec_glist.size > 10000) {
- err = CPrec_FlushRawBuffer();
- if (err) {
- cprec_ioerror = err;
- return err;
- }
- }
-
- return noErr;
-}
-
-static int CPrec_CompressPatches(void) {
- Patch *scan;
- int count;
- SInt32 last;
-
- cprec_glist.size = 0;
-
- scan = cprec_patch_list;
- last = 0;
- count = 0;
- while (scan) {
- CError_ASSERT(4339, (scan->offset & 0x80000001) == 0);
-
- if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126)
- CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80);
- else
- CPrec_AppendWord32(scan->offset);
-
- last = scan->offset;
- scan = scan->next;
- count++;
- }
-
- return count;
-}
-
-static OSErr CPrec_DumpColorSymbolTable(Boolean doWrite) {
- OSErr err;
-
- freelheap();
-
- CPrec_InitAddressHashTable();
- CPrec_InitPointerHashTable();
-
- cprec_patch_list = NULL;
- cprec_tokenpatches = NULL;
- cprec_offset = 0;
- cprec_zero_offset = 0;
- cprec_dowrite = doWrite;
- cprec_ioerror = noErr;
-
- CPrec_SetupBuiltIn();
- CPrec_AppendWord32(0);
-
- CPrec_DumpNameTable();
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
-
- CPrec_DumpMacroTable();
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
-
- CPrec_DumpRootNameSpace();
- if (doWrite) {
- if (cprec_ioerror != noErr)
- return cprec_ioerror;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (ctempl_templates) {
- TemplClass *p = TEMPL_CLASS(CPrec_GetTypePatch(TYPE(ctempl_templates)));
- if (doWrite)
- cprec_header->ctempl_templates = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (ctempl_templatefuncs) {
- TemplateFunction *p = CPrec_GetTemplateFunctionPatch(ctempl_templatefuncs);
- if (doWrite)
- cprec_header->ctempl_templatefuncs = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (csom_stubs) {
- CSOMStub *p = CPrec_GetSOMPatch(csom_stubs);
- if (doWrite)
- cprec_header->csom_stubs = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cprec_staticdata) {
- StaticData *p = CPrec_GetStaticDataPatch(cprec_staticdata);
- if (doWrite)
- cprec_header->cprec_staticdata = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (callbackactions) {
- CallbackAction *p = CPrec_GetCallbackPatch(callbackactions);
- if (doWrite)
- cprec_header->callbackactions = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_type_class) {
- Type *p = CPrec_GetTypePatch(cobjc_type_class);
- if (doWrite)
- cprec_header->cobjc_type_class = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_type_id) {
- Type *p = CPrec_GetTypePatch(cobjc_type_id);
- if (doWrite)
- cprec_header->cobjc_type_id = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_type_sel) {
- Type *p = CPrec_GetTypePatch(cobjc_type_sel);
- if (doWrite)
- cprec_header->cobjc_type_sel = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_selhashtable) {
- ObjCSelector **p = CPrec_GetSelHashTablePatch(cobjc_selhashtable);
- if (doWrite)
- cprec_header->cobjc_selhashtable = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_classdefs) {
- BClassList *p = CPrec_GetBClassListPatch(cobjc_classdefs);
- if (doWrite)
- cprec_header->cobjc_classdefs = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cobjc_protocols) {
- ObjCProtocol *p = CPrec_GetObjCProtocolPatch(cobjc_protocols);
- if (doWrite)
- cprec_header->cobjc_protocols = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (init_expressions) {
- InitExpr *p = CPrec_GetIExpressionPatch(init_expressions);
- if (doWrite)
- cprec_header->init_expressions = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- if (cinline_tactionlist) {
- CI_Action *p = CPrec_GetInlineActionPatch(cinline_tactionlist);
- if (doWrite)
- cprec_header->cinline_tactionlist = p;
- if ((err = CPrec_FlushRawBuffer()) != noErr)
- return err;
- }
-
- return noErr;
-}
-
-static OSErr CPrec_FileAlign(short refnum, SInt32 *len) {
- OSErr err;
- SInt32 n;
- char buf[8];
-
- n = *len;
- if ((n & 7) == 0)
- return noErr;
-
- memclrw(buf, 8);
- err = COS_FileWrite(refnum, buf, n = 8 - (n & 7));
- *len += n;
-
- return err;
-}
-
-static OSErr CPrec_WriteFile(void) {
- char str[128];
- int i;
- HashNameNode *name;
- OSErr err;
- SInt32 offset;
-
- if (InitGList(&cprec_glist, 0x40000))
- CError_NoMem();
-
- CompilerGetCString(10, str);
- CWShowStatus(cparams.context, str, "");
- CPrep_RemoveSpecialMacros();
-
- for (i = 0; i < 0x800; i++) {
- for (name = name_hash_nodes[i]; name; name = name->next)
- name->id = 0;
- }
-
- if ((err = CPrec_DumpColorSymbolTable(0)) != noErr)
- return err;
-
- CompilerGetCString(11, str);
- CWShowStatus(cparams.context, str, "");
-
- cprec_header = galloc(sizeof(Header));
- memclrw(cprec_header, sizeof(Header));
-
- cprec_header->magic = 0xBEEFFACE;
- cprec_header->version = 1047;
- cprec_header->target = 2;
- cprec_header->check_header_flags = copts.checkprecompflags;
- cprec_header->cplusplus = copts.cplusplus;
- cprec_header->uniqueID = CParser_GetUniqueID();
- cprec_header->cobjc_selrefcount = cobjc_selrefcount;
- cprec_header->cobjc_classrefcount = cobjc_classrefcount;
- cprec_header->cobjc_stringcount = cobjc_stringcount;
-
- if ((err = COS_FileWrite(cprec_refnum, cprec_header, sizeof(Header))) != noErr)
- return err;
-
- offset = sizeof(Header);
-
- if ((err = CPrec_DumpColorSymbolTable(1)) != noErr)
- return err;
-
- cprec_header->x28 = cprec_offset;
- cprec_header->x30 = offset;
-
- if ((err = COS_FileGetPos(cprec_refnum, &offset)) != noErr)
- return err;
-
- cprec_header->x2C = offset - cprec_header->x30;
-
- cprec_header->compressedPatchCount = CPrec_CompressPatches();
- cprec_header->compressedPatchSize = cprec_glist.size;
- cprec_header->compressedPatchOffset = offset;
-
- if (cprec_header->compressedPatchCount) {
- if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr)
- return err;
- offset += cprec_glist.size;
- }
-
- if ((err = CPrec_FileAlign(cprec_refnum, &offset)) != noErr)
- return err;
-
- cprec_glist.size = 0;
- CPrec_GenerateBuiltinPatches();
- cprec_header->builtinPatchSize = cprec_glist.size;
- cprec_header->builtinPatchOffset = offset;
-
- if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr)
- return err;
- offset += cprec_glist.size;
-
- if (cprec_tokenpatches) {
- cprec_glist.size = 0;
- CPrec_GenerateTokenStreamPatches();
- cprec_header->tokenStreamPatchSize = cprec_glist.size;
- cprec_header->tokenStreamPatchOffset = offset;
-
- if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr)
- return err;
- offset += cprec_glist.size;
- }
-
- if ((err = COS_FileSetPos(cprec_refnum, 0)) != noErr)
- return err;
-
- if ((err = COS_FileWrite(cprec_refnum, cprec_header, sizeof(Header))) != noErr)
- return err;
-
- return noErr;
-}
-
-void PrecompilerWrite(void) {
- OSErr err;
- short strindex;
- char str[128];
- FSSpec spec;
-
- spec = cparamblkptr->sourcefile;
- if (CWGetPrecompiledHeaderSpec(cparamblkptr->context, &spec, precomp_target_str) == cwNoErr) {
- strindex = 3;
- err = COS_FileNew(&spec, &cprec_refnum, copts.appltype, copts.headtype);
- if (err == noErr) {
- strindex = 4;
- err = CPrec_WriteFile();
- }
- CleanupPrecompiler();
-
- if (err != noErr) {
- CompilerGetCString(strindex, str);
- sprintf(string, str, err);
- CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0);
- } else {
- CWFileTime time = 0;
- CWSetModDate(cparamblkptr->context, &spec, &time, 1);
- }
- }
-}
-
-static void CPrec_ReadData(SInt32 offset, void *buffer, SInt32 size) {
- if (
- COS_FileSetPos(cprec_refnum, offset) != noErr ||
- COS_FileRead(cprec_refnum, buffer, size) != noErr
- )
- CError_ErrorTerm(CErrorStr181);
-}
-
-static void CPrec_ReadRawBuffer(void) {
- UInt8 *buffer;
- UInt8 *work;
- UInt8 *end;
- UInt32 size;
- int ch;
-
- if (!cprec_buffer) {
- size = cprec_header->x28 + (cprec_header->x28 >> 7) + 64;
- buffer = galloc(size);
- cprec_rawbuffer = buffer;
-
- work = buffer + size - cprec_header->x2C;
- CPrec_ReadData(cprec_header->x30, work, cprec_header->x2C);
- } else {
- buffer = galloc(cprec_header->x28);
- cprec_rawbuffer = buffer;
- work = (UInt8 *) cprec_buffer + cprec_header->x30;
- }
-
- end = work + cprec_header->x2C;
-
- while (work < end) {
- if ((ch = *(work++)) >= 0xE0) {
- ch -= 0xE0;
- do {
- *(buffer++) = 0;
- } while (--ch >= 0);
- } else {
- do {
- *(buffer++) = *(work++);
- } while (--ch >= 0);
- }
- }
-
- if (work != end || buffer != RESOLVE_RAW_BUFFER(cprec_header->x28))
- CError_ErrorTerm(CErrorStr181);
-}
-
-static void CPrec_RelocateRawBuffer(void) {
- UInt8 *patches;
- UInt32 offset;
- UInt8 *dest;
- SInt32 count;
- UInt8 *patch;
- UInt32 var;
-
- if ((count = cprec_header->compressedPatchCount)) {
- if (!cprec_buffer) {
- patches = lalloc(cprec_header->compressedPatchSize);
- CPrec_ReadData(cprec_header->compressedPatchOffset, patches, cprec_header->compressedPatchSize);
- } else {
- patches = RESOLVE_BUFFER(cprec_header->compressedPatchOffset);
- }
-
- offset = 0;
- patch = patches;
- dest = cprec_rawbuffer;
- do {
- if (!(*patch & 0x80)) {
- ((UInt8 *) &var)[0] = *(patch++);
- ((UInt8 *) &var)[1] = *(patch++);
- ((UInt8 *) &var)[2] = *(patch++);
- ((UInt8 *) &var)[3] = *(patch++);
- offset = var;
- } else {
- offset += (char) (*(patch++) * 2);
- }
- *((uintptr_t *) (dest + offset)) += (uintptr_t) dest;
- } while (--count > 0);
-
- freelheap();
-
- if (patch != (patches + cprec_header->compressedPatchSize))
- CError_ErrorTerm(CErrorStr181);
- }
-}
-
-static void CPrec_RelocateBuiltins(void) {
- UInt32 *patches;
- void *builtin;
- UInt32 count;
- UInt8 *buffer;
-
- if (cprec_header->builtinPatchSize) {
- CPrec_SetupBuiltInArray();
- if (!cprec_buffer) {
- patches = lalloc(cprec_header->builtinPatchSize);
- CPrec_ReadData(cprec_header->builtinPatchOffset, patches, cprec_header->builtinPatchSize);
- } else {
- patches = RESOLVE_BUFFER(cprec_header->builtinPatchOffset);
- }
-
- buffer = cprec_rawbuffer;
- while (1) {
- if (!(count = *(patches++)))
- break;
-
- builtin = cprec_builtin_array[*(patches++)];
- do {
- *((void **) (buffer + *(patches++))) = builtin;
- } while (--count);
- }
- }
-}
-
-static void CPrec_RelocateTokenStreams(void) {
- UInt32 *patches;
- UInt32 count;
- TStreamElement *tokens;
- UInt8 *buffer;
- CPrepFileInfo *file;
- SInt32 pos;
-
- if (cprec_header->tokenStreamPatchSize) {
- CPrep_GetPrepPos(&file, &pos);
-
- if (!cprec_buffer) {
- patches = lalloc(cprec_header->tokenStreamPatchSize);
- CPrec_ReadData(cprec_header->tokenStreamPatchOffset, patches, cprec_header->tokenStreamPatchSize);
- } else {
- patches = RESOLVE_BUFFER(cprec_header->tokenStreamPatchOffset);
- }
-
- buffer = cprec_rawbuffer;
- while (1) {
- if (!*patches)
- break;
-
- tokens = (TStreamElement *) (buffer + *(patches++));
- count = *(patches++);
-
- while (count--) {
- tokens->tokenfile = file;
- tokens->tokenoffset = pos;
- tokens++;
- }
- }
- }
-}
-
-static void CPrec_RelocateMacroTable(void) {
- int i;
- int j;
- int count;
- UInt8 *buffer;
- Macro **prec_table;
- Macro **table;
- Macro *macro;
- uintptr_t offset;
-
- buffer = cprec_rawbuffer;
- prec_table = cprec_header->macrotable;
- table = macrohashtable;
-
- i = 0;
- do {
- for (macro = *table; macro; macro = macro->next) {
- macro->name = GetHashNameNodeExport(macro->name->name);
- count = macro->xC & 0x7FFF;
- for (j = 1; j < count; j++)
- macro->names[j - 1] = GetHashNameNodeExport(macro->names[j - 1]->name);
- }
-
- if ((offset = (uintptr_t) *prec_table)) {
- if (*table) {
- macro = (Macro *) (buffer + offset);
- while (macro->next)
- macro = macro->next;
- macro->next = *table;
- }
- *table = (Macro *) (buffer + offset);
- }
-
- prec_table++;
- table++;
- } while (++i < 0x800);
-}
-
-static void CPrec_RelocateTable(void **table, int size, void **dest) {
- int i;
- void *buffer = cprec_rawbuffer;
-
- for (i = 0; i < size; i++) {
- if (*table)
- *dest = (char *) buffer + (uintptr_t) *table;
- else
- *dest = NULL;
- table++;
- dest++;
- }
-}
-
-static void CPrec_RelocateRootNameSpace(void) {
- CError_ASSERT(4981, cscope_root->is_hash);
-
- cscope_root->names = cprec_header->root_names;
- CPrec_RelocateTable(
- (void **) cprec_header->root_nametable,
- 0x400,
- (void **) cscope_root->data.hash);
-}
-
-static void CPrec_FixNameIds(void) {
- int i;
- HashNameNode *node;
-
- for (i = 0; i < 2048; i++) {
- for (node = name_hash_nodes[i]; node; node = node->next)
- node->id = -1;
- }
-}
-
-static void CPrec_DefineStaticData(void) {
- StaticData *sd = cprec_staticdata;
- cprec_staticdata = NULL;
-
- while (sd) {
- CInit_DeclareData(sd->object, sd->buffer, sd->links, sd->size);
- sd = sd->next;
- }
-}
-
-void PrecompilerRead(short refnum, void *buffer) {
- cprec_refnum = refnum;
- cprec_buffer = buffer;
-
- CPrep_RemoveSpecialMacros();
-
- if (!CScope_IsEmptySymTable())
- CError_ErrorTerm(CErrorStr180);
-
- if (!cprec_buffer) {
- cprec_header = galloc(sizeof(Header));
- CPrec_ReadData(0, cprec_header, sizeof(Header));
- } else {
- cprec_header = cprec_buffer;
- }
-
- if (cprec_header->magic != 0xBEEFFACE)
- CError_ErrorTerm(CErrorStr181);
- if (cprec_header->version != 1047)
- CError_ErrorTerm(CErrorStr222);
- if (cprec_header->target != 2)
- CError_ErrorTerm(CErrorStr223);
-
- copts.checkprecompflags = cprec_header->check_header_flags;
-
- CPrec_ReadRawBuffer();
- CPrec_RelocateRawBuffer();
- CPrec_RelocateBuiltins();
- CPrec_RelocateTable((void **) cprec_header->nametable, 0x800, (void **) name_hash_nodes);
- CPrec_FixNameIds();
- CPrec_RelocateMacroTable();
- CPrec_RelocateTokenStreams();
- CPrec_RelocateRootNameSpace();
-
- if (!cprec_header->usings)
- cscope_root->usings = NULL;
- else
- cscope_root->usings = RESOLVE_RAW_BUFFER(cprec_header->usings);
-
- ctempl_templates = RESOLVE_SAFE(cprec_header->ctempl_templates);
- ctempl_templatefuncs = RESOLVE_SAFE(cprec_header->ctempl_templatefuncs);
- csom_stubs = RESOLVE_SAFE(cprec_header->csom_stubs);
- cprec_staticdata = RESOLVE_SAFE(cprec_header->cprec_staticdata);
- callbackactions = RESOLVE_SAFE(cprec_header->callbackactions);
- cobjc_type_class = RESOLVE_SAFE(cprec_header->cobjc_type_class);
- cobjc_type_id = RESOLVE_SAFE(cprec_header->cobjc_type_id);
- cobjc_type_sel = RESOLVE_SAFE(cprec_header->cobjc_type_sel);
- cobjc_selhashtable = RESOLVE_SAFE(cprec_header->cobjc_selhashtable);
- cobjc_classdefs = RESOLVE_SAFE(cprec_header->cobjc_classdefs);
- cobjc_protocols = RESOLVE_SAFE(cprec_header->cobjc_protocols);
- init_expressions = RESOLVE_SAFE(cprec_header->init_expressions);
- cinline_tactionlist = RESOLVE_SAFE(cprec_header->cinline_tactionlist);
- CParser_SetUniqueID(cprec_header->uniqueID);
- cobjc_selrefcount = cprec_header->cobjc_selrefcount;
- cobjc_classrefcount = cprec_header->cobjc_classrefcount;
- cobjc_stringcount = cprec_header->cobjc_stringcount;
-
- cprec_refnum = 0;
-
- CleanupPrecompiler();
- cscope_current = cscope_root;
-
- if (!CParser_ReInitRuntimeObjects(1))
- CError_ErrorTerm(CErrorStr181);
-
- CPrep_InsertSpecialMacros();
-
- if (cparamblkptr->precompile != 1)
- CPrec_DefineStaticData();
-}
diff --git a/compiler_and_linker/unsorted/CPreprocess.c b/compiler_and_linker/unsorted/CPreprocess.c
deleted file mode 100644
index 4e6b3c0..0000000
--- a/compiler_and_linker/unsorted/CPreprocess.c
+++ /dev/null
@@ -1,676 +0,0 @@
-#include "compiler/CPreprocess.h"
-#include "compiler/CError.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CompilerTools.h"
-#include "cos.h"
-
-void CPrep_PreprocessDumpNewLine(void) {
- if (copts.line_prepdump && pplist.data && filesp >= 0)
- AppendGListData(&pplist, "\r", 1);
-}
-
-void CPrep_PreprocessDumpFileInfo(Boolean flag) {
- char linebuf[512];
- int size;
- SInt16 tmp16;
- SInt32 tmp32;
- Str255 filename;
-
- if (pplist.data && filesp >= 0) {
- if (nlflag && flag && pplist.size > 0)
- AppendGListName(&pplist, "\r");
-
- if (copts.line_prepdump)
- size = sprintf(linebuf, "#line % " PRId32 "\t\"", linenumber);
- else
- size = sprintf(linebuf, "/* #line % " PRId32 "\t\"", linenumber);
- AppendGListData(&pplist, linebuf, size);
-
- if (copts.fullpath_prepdump) {
- if (prep_file->nameNode) {
- AppendGListData(&pplist, prep_file->nameNode->name, strlen(prep_file->nameNode->name));
- } else {
- COS_FileGetPathName(linebuf, &prep_file->textfile, &tmp32);
- AppendGListData(&pplist, linebuf, strlen(linebuf));
- }
- } else {
- if (prep_file->nameNode) {
- char *work = prep_file->nameNode->name + strlen(prep_file->nameNode->name);
- while (work > prep_file->nameNode->name && !strchr("/\\:", work[-1]))
- work--;
-
- AppendGListData(&pplist, work, strlen(work));
- } else {
- COS_FileGetFSSpecInfo(&prep_file->textfile, &tmp16, &tmp32, filename);
- AppendGListData(&pplist, &filename[1], filename[0]);
- }
- }
-
- size = sprintf(linebuf, "\"\t/* stack depth % " PRId32 " */", filesp);
- AppendGListData(&pplist, linebuf, size);
-
- if (copts.line_prepdump && flag)
- CPrep_PreprocessDumpNewLine();
-
- nlflag = 1;
- }
-}
-
-static void CPrep_DumpWString(UInt16 *str, short len) {
- int divisor;
- int i;
-
- while (len--) {
- if (*str < 32) {
- AppendGListByte(&pplist, '\\');
- switch (*str) {
- case 7:
- AppendGListByte(&pplist, 'a');
- break;
- case 8:
- AppendGListByte(&pplist, 'b');
- break;
- case 27:
- AppendGListByte(&pplist, 'e');
- break;
- case 12:
- AppendGListByte(&pplist, 'f');
- break;
- case 10:
- AppendGListByte(&pplist, 'n');
- break;
- case 13:
- AppendGListByte(&pplist, 'r');
- break;
- case 9:
- AppendGListByte(&pplist, 't');
- break;
- case 11:
- AppendGListByte(&pplist, 'v');
- break;
- default:
- if (*str >= 8)
- AppendGListByte(&pplist, '0' + (*str / 8));
- AppendGListByte(&pplist, '0' + (*str % 8));
- }
- } else if (*str > 255) {
- AppendGListByte(&pplist, '\\');
- AppendGListByte(&pplist, 'x');
-
- divisor = 0x1000;
- for (i = 0; i < 4; i++) {
- AppendGListByte(&pplist, "0123456789ABCDEF"[(*str / divisor) % 16]);
- divisor /= 16;
- }
- } else {
- switch (*str) {
- case '"':
- case '\\':
- AppendGListByte(&pplist, '\\');
- default:
- AppendGListByte(&pplist, *str);
- }
- }
- str++;
- }
-}
-
-static void CPrep_DumpString(UInt8 *str, short len) {
- while (len--) {
- if (*str < 32) {
- AppendGListByte(&pplist, '\\');
- switch (*str) {
- case 7:
- AppendGListByte(&pplist, 'a');
- break;
- case 8:
- AppendGListByte(&pplist, 'b');
- break;
- case 12:
- AppendGListByte(&pplist, 'f');
- break;
- case 10:
- AppendGListByte(&pplist, 'n');
- break;
- case 13:
- AppendGListByte(&pplist, 'r');
- break;
- case 9:
- AppendGListByte(&pplist, 't');
- break;
- case 11:
- AppendGListByte(&pplist, 'v');
- break;
- default:
- if (*str >= 8)
- AppendGListByte(&pplist, '0' + (*str / 8));
- AppendGListByte(&pplist, '0' + (*str % 8));
- }
- } else {
- switch (*str) {
- case '"':
- case '\\':
- AppendGListByte(&pplist, '\\');
- default:
- AppendGListByte(&pplist, *str);
- }
- }
- str++;
- }
-}
-
-void CPrep_Preprocess(void) {
- short innertoken;
- short token;
- char startToken;
- char endToken;
- int depth;
- Boolean save_asmpoundcomment; // r16
- Boolean save_cplusplus; // r15
- char *p;
-
- startToken = 0;
- depth = 0;
-
- if (InitGList(&pplist, 10000))
- CError_NoMem();
-
- nlflag = 0;
- spaceskip = 0;
-
- if ((token = lex())) {
- do {
- if (nlflag) {
- if (!copts.line_prepdump)
- AppendGListData(&pplist, "\r", 1);
- } else {
- if (spaceskip)
- AppendGListByte(&pplist, ' ');
- }
-
- while (1) {
- switch ((innertoken = token)) {
- case '(':
- case ')':
- case '{':
- case '}':
- AppendGListByte(&pplist, token);
- if (cprep_nostring) {
- if (innertoken == startToken) {
- depth++;
- } else if (innertoken == endToken) {
- if (--depth == 0) {
- cprep_nostring = 0;
- in_assembler = 0;
- copts.cplusplus = save_cplusplus;
- copts.asmpoundcomment = save_asmpoundcomment;
- }
- }
- }
- break;
-
- case TK_INTCONST:
- case TK_FLOATCONST:
- if (tokenstacklevel > 0)
- p = macropos;
- else
- p = prep_file_start + ts_current[-1].tokenoffset;
- AppendGListData(&pplist, p, pos - p);
- break;
-
- case TK_IDENTIFIER:
- AppendGListData(&pplist, tkidentifier->name, strlen(tkidentifier->name));
- break;
-
- case TK_AUTO:
- AppendGListData(&pplist, "auto", 4);
- break;
- case TK_REGISTER:
- AppendGListData(&pplist, "register", 8);
- break;
- case TK_STATIC:
- AppendGListData(&pplist, "static", 6);
- break;
- case TK_EXTERN:
- AppendGListData(&pplist, "extern", 6);
- break;
- case TK_TYPEDEF:
- AppendGListData(&pplist, "typedef", 7);
- break;
- case TK_INLINE:
- AppendGListData(&pplist, "inline", 6);
- break;
- case TK_VOID:
- AppendGListData(&pplist, "void", 4);
- break;
- case TK_CHAR:
- AppendGListData(&pplist, "char", 4);
- break;
- case TK_SHORT:
- AppendGListData(&pplist, "short", 5);
- break;
- case TK_INT:
- AppendGListData(&pplist, "int", 3);
- break;
- case TK_LONG:
- AppendGListData(&pplist, "long", 4);
- break;
- case TK_FLOAT:
- AppendGListData(&pplist, "float", 5);
- break;
- case TK_DOUBLE:
- AppendGListData(&pplist, "double", 6);
- break;
- case TK_SIGNED:
- AppendGListData(&pplist, "signed", 6);
- break;
- case TK_UNSIGNED:
- AppendGListData(&pplist, "unsigned", 8);
- break;
- case TK_STRUCT:
- AppendGListData(&pplist, "struct", 6);
- break;
- case TK_UNION:
- AppendGListData(&pplist, "union", 5);
- break;
- case TK_ENUM:
- AppendGListData(&pplist, "enum", 4);
- break;
- case TK_CLASS:
- AppendGListData(&pplist, "class", 5);
- break;
- case TK_CONST:
- AppendGListData(&pplist, "const", 5);
- break;
- case TK_VOLATILE:
- AppendGListData(&pplist, "volatile", 8);
- break;
- case TK_PASCAL:
- AppendGListData(&pplist, "pascal", 6);
- break;
- case TK_UU_FAR:
- AppendGListData(&pplist, "__far", 5);
- break;
- case TK_ONEWAY:
- AppendGListData(&pplist, "oneway", 6);
- break;
- case TK_IN:
- AppendGListData(&pplist, "in", 2);
- break;
- case TK_OUT:
- AppendGListData(&pplist, "out", 3);
- break;
- case TK_INOUT:
- AppendGListData(&pplist, "inout", 5);
- break;
- case TK_BYCOPY:
- AppendGListData(&pplist, "bycopy", 6);
- break;
- case TK_BYREF:
- AppendGListData(&pplist, "byref", 5);
- break;
- case TK_ASM:
- AppendGListData(&pplist, "asm", 3);
- endToken = 0;
- startToken = 0;
- AppendGListByte(&pplist, ' ');
- token = lex();
- if (token == TK_VOLATILE || (token == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__volatile__"))) {
- AppendGListData(&pplist, "volatile", 8);
- token = lex();
- }
- if (token) {
- if (token < ' ' || token > 255)
- continue;
- AppendGListByte(&pplist, token);
-
- if (token == '(') {
- startToken = '(';
- endToken = ')';
- } else if (token == '{') {
- startToken = '{';
- endToken = '}';
- } else {
- continue;
- }
-
- cprep_nostring = 1;
- in_assembler = 1;
- depth = 1;
- save_asmpoundcomment = copts.asmpoundcomment;
- save_cplusplus = copts.cplusplus;
-
- token = lex();
- if (token == '"') {
- AppendGListByte(&pplist, token);
- copts.cplusplus = 0;
- copts.asmpoundcomment = 1;
- break;
- } else if (token == 0) {
- break;
- }
- continue;
- }
- break;
-
- case TK_CASE:
- AppendGListData(&pplist, "case", 4);
- break;
- case TK_DEFAULT:
- AppendGListData(&pplist, "default", 7);
- break;
- case TK_IF:
- AppendGListData(&pplist, "if", 2);
- break;
- case TK_ELSE:
- AppendGListData(&pplist, "else", 4);
- break;
- case TK_SWITCH:
- AppendGListData(&pplist, "switch", 6);
- break;
- case TK_WHILE:
- AppendGListData(&pplist, "while", 5);
- break;
- case TK_DO:
- AppendGListData(&pplist, "do", 2);
- break;
- case TK_FOR:
- AppendGListData(&pplist, "for", 3);
- break;
- case TK_GOTO:
- AppendGListData(&pplist, "goto", 4);
- break;
- case TK_CONTINUE:
- AppendGListData(&pplist, "continue", 8);
- break;
- case TK_BREAK:
- AppendGListData(&pplist, "break", 5);
- break;
- case TK_RETURN:
- AppendGListData(&pplist, "return", 6);
- break;
- case TK_SIZEOF:
- AppendGListData(&pplist, "sizeof", 6);
- break;
- case TK_CATCH:
- AppendGListData(&pplist, "catch", 5);
- break;
- case TK_DELETE:
- AppendGListData(&pplist, "delete", 6);
- break;
- case TK_FRIEND:
- AppendGListData(&pplist, "friend", 6);
- break;
- case TK_NEW:
- AppendGListData(&pplist, "new", 3);
- break;
- case TK_OPERATOR:
- AppendGListData(&pplist, "operator", 8);
- break;
- case TK_PRIVATE:
- AppendGListData(&pplist, "private", 7);
- break;
- case TK_PROTECTED:
- AppendGListData(&pplist, "protected", 9);
- break;
- case TK_PUBLIC:
- AppendGListData(&pplist, "public", 6);
- break;
- case TK_TEMPLATE:
- AppendGListData(&pplist, "template", 8);
- break;
- case TK_THIS:
- AppendGListData(&pplist, "this", 4);
- break;
- case TK_THROW:
- AppendGListData(&pplist, "throw", 5);
- break;
- case TK_TRY:
- AppendGListData(&pplist, "try", 3);
- break;
- case TK_VIRTUAL:
- AppendGListData(&pplist, "virtual", 7);
- break;
- case TK_INHERITED:
- AppendGListData(&pplist, "inherited", 9);
- break;
- case TK_CONST_CAST:
- AppendGListData(&pplist, "const_cast", 10);
- break;
- case TK_DYNAMIC_CAST:
- AppendGListData(&pplist, "dynamic_cast", 12);
- break;
- case TK_EXPLICIT:
- AppendGListData(&pplist, "explicit", 8);
- break;
- case TK_MUTABLE:
- AppendGListData(&pplist, "mutable", 7);
- break;
- case TK_NAMESPACE:
- AppendGListData(&pplist, "namespace", 9);
- break;
- case TK_REINTERPRET_CAST:
- AppendGListData(&pplist, "reinterpret_cast", 16);
- break;
- case TK_STATIC_CAST:
- AppendGListData(&pplist, "static_cast", 11);
- break;
- case TK_USING:
- AppendGListData(&pplist, "using", 5);
- break;
- case TK_WCHAR_T:
- AppendGListData(&pplist, "wchar_t", 7);
- break;
- case TK_TYPENAME:
- AppendGListData(&pplist, "typename", 8);
- break;
- case TK_TRUE:
- AppendGListData(&pplist, "true", 4);
- break;
- case TK_FALSE:
- AppendGListData(&pplist, "false", 5);
- break;
- case TK_TYPEID:
- AppendGListData(&pplist, "typeid", 6);
- break;
- case TK_EXPORT:
- AppendGListData(&pplist, "export", 6);
- break;
- case TK_UU_STDCALL:
- AppendGListData(&pplist, "__stdcall", 9);
- break;
- case TK_UU_CDECL:
- AppendGListData(&pplist, "__cdecl", 7);
- break;
- case TK_UU_FASTCALL:
- AppendGListData(&pplist, "__fastcall", 10);
- break;
- case TK_UU_DECLSPEC:
- AppendGListData(&pplist, "__declspec", 10);
- break;
- case TK_MULT_ASSIGN:
- AppendGListData(&pplist, "*=", 2);
- break;
- case TK_DIV_ASSIGN:
- AppendGListData(&pplist, "/=", 2);
- break;
- case TK_MOD_ASSIGN:
- AppendGListData(&pplist, "%=", 2);
- break;
- case TK_ADD_ASSIGN:
- AppendGListData(&pplist, "+=", 2);
- break;
- case TK_SUB_ASSIGN:
- AppendGListData(&pplist, "-=", 2);
- break;
- case TK_SHL_ASSIGN:
- AppendGListData(&pplist, "<<=", 3);
- break;
- case TK_SHR_ASSIGN:
- AppendGListData(&pplist, ">>=", 3);
- break;
- case TK_AND_ASSIGN:
- AppendGListData(&pplist, "&=", 2);
- break;
- case TK_XOR_ASSIGN:
- AppendGListData(&pplist, "^=", 2);
- break;
- case TK_OR_ASSIGN:
- AppendGListData(&pplist, "|=", 2);
- break;
- case TK_LOGICAL_OR:
- AppendGListData(&pplist, "||", 2);
- break;
- case TK_LOGICAL_AND:
- AppendGListData(&pplist, "&&", 2);
- break;
- case TK_LOGICAL_EQ:
- AppendGListData(&pplist, "==", 2);
- break;
- case TK_LOGICAL_NE:
- AppendGListData(&pplist, "!=", 2);
- break;
- case TK_LESS_EQUAL:
- AppendGListData(&pplist, "<=", 2);
- break;
- case TK_GREATER_EQUAL:
- AppendGListData(&pplist, ">=", 2);
- break;
- case TK_SHL:
- AppendGListData(&pplist, "<<", 2);
- break;
- case TK_SHR:
- AppendGListData(&pplist, ">>", 2);
- break;
- case TK_INCREMENT:
- AppendGListData(&pplist, "++", 2);
- break;
- case TK_DECREMENT:
- AppendGListData(&pplist, "--", 2);
- break;
- case TK_ARROW:
- AppendGListData(&pplist, "->", 2);
- break;
- case TK_ELLIPSIS:
- AppendGListData(&pplist, "...", 3);
- break;
- case TK_DOT_STAR:
- AppendGListData(&pplist, ".*", 2);
- break;
- case TK_ARROW_STAR:
- AppendGListData(&pplist, "->*", 3);
- break;
- case TK_COLON_COLON:
- AppendGListData(&pplist, "::", 2);
- break;
- case TK_AT_INTERFACE:
- AppendGListData(&pplist, "@interface", 10);
- break;
- case TK_AT_IMPLEMENTATION:
- AppendGListData(&pplist, "@implementation", 15);
- break;
- case TK_AT_PROTOCOL:
- AppendGListData(&pplist, "@protocol", 9);
- break;
- case TK_AT_END:
- AppendGListData(&pplist, "@end", 4);
- break;
- case TK_AT_PRIVATE:
- AppendGListData(&pplist, "@private", 8);
- break;
- case TK_AT_PROTECTED:
- AppendGListData(&pplist, "@protected", 10);
- break;
- case TK_AT_PUBLIC:
- AppendGListData(&pplist, "@public", 7);
- break;
- case TK_AT_CLASS:
- AppendGListData(&pplist, "@class", 6);
- break;
- case TK_AT_SELECTOR:
- AppendGListData(&pplist, "@selector", 9);
- break;
- case TK_AT_ENCODE:
- AppendGListData(&pplist, "@encode", 7);
- break;
- case TK_AT_DEFS:
- AppendGListData(&pplist, "@defs", 5);
- break;
- case TK_SELF:
- AppendGListData(&pplist, "self", 4);
- break;
- case TK_SUPER:
- AppendGListData(&pplist, "super", 5);
- break;
- case TK_BOOL:
- if (!copts.cplusplus && copts.c9x)
- AppendGListData(&pplist, "_Bool", 5);
- else
- AppendGListData(&pplist, "bool", 4);
- break;
- case TK_RESTRICT:
- if (copts.c9x)
- AppendGListData(&pplist, "restrict", 8);
- else
- AppendGListData(&pplist, "__restrict", 10);
- break;
- case TK_UU_VECTOR:
- AppendGListData(&pplist, "__vector", 8);
- break;
- case TK_UU_TYPEOF_UU:
- AppendGListData(&pplist, "__typeof__", 10);
- break;
- case TK_UU_ATTRIBUTE_UU:
- AppendGListData(&pplist, "__attribute__", 13);
- break;
- case TK_UU_ALIGNOF_UU:
- AppendGListData(&pplist, "__alignof__", 11);
- break;
- case TK_UU_UUIDOF:
- AppendGListData(&pplist, "__uuidof", 8);
- break;
- case TK_U_COMPLEX:
- AppendGListData(&pplist, "_Complex", 8);
- break;
- case TK_U_IMAGINARY:
- AppendGListData(&pplist, "_Imaginary", 10);
- break;
-
- case TK_STRING:
- if (ispascalstring) {
- AppendGListData(&pplist, "\"\\p", 3);
- CPrep_DumpString((UInt8 *) tkstring + 1, tksize - 1);
- } else {
- AppendGListByte(&pplist, '"');
- CPrep_DumpString((UInt8 *) tkstring, tksize - 1);
- }
- AppendGListByte(&pplist, '"');
- break;
-
- case TK_STRING_WIDE:
- AppendGListData(&pplist, "L\"", 2);
- CPrep_DumpWString((UInt16 *) tkstring, (tksize / stwchar.size) - 1);
- AppendGListByte(&pplist, '"');
- break;
-
- default:
- if (token >= 32 && token <= 255)
- AppendGListByte(&pplist, token);
- else
- CError_FATAL(563);
- }
- break;
- }
-
- CPrep_TokenStreamFlush();
- nlflag = 0;
- spaceskip = 0;
- } while ((token = lex()));
- }
-
- AppendGListByte(&pplist, 0);
- COS_ResizeHandle(pplist.data, pplist.size);
-}
diff --git a/compiler_and_linker/unsorted/CRTTI.c b/compiler_and_linker/unsorted/CRTTI.c
deleted file mode 100644
index 3881153..0000000
--- a/compiler_and_linker/unsorted/CRTTI.c
+++ /dev/null
@@ -1,940 +0,0 @@
-#include "compiler/CRTTI.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInit.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CPrep.h"
-
-typedef struct Offset {
- struct Offset *next;
- SInt32 offset;
-} Offset;
-
-static Offset *crtti_offsets;
-static OLinkList *crtti_olinks;
-
-// forward decls
-static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual);
-
-typedef struct RTTISubClassList {
- struct RTTISubClassList *next;
- TypeClass *base;
- SInt32 voffset;
-} RTTISubClassList;
-
-typedef struct RTTIBaseList {
- struct RTTIBaseList *next;
- TypeClass *base;
- RTTISubClassList *subclasses;
- SInt32 voffset;
- short numsubclasses;
- Boolean x12;
- Boolean x13;
-} RTTIBaseList;
-
-static RTTIBaseList *CRTTI_CreateBaseList(TypeClass *tclass, TypeClass *tclassbase, RTTIBaseList *list, SInt32 voffset, Boolean flag) {
- RTTIBaseList *scan;
- ClassList *base;
- Boolean flag27;
- SInt32 newvoffset;
-
- if (tclass != tclassbase) {
- flag27 = 0;
-
- for (scan = list; scan; scan = scan->next) {
- if (scan->base == tclassbase) {
- if (scan->voffset == voffset) {
- if (!flag)
- scan->x12 = 0;
- flag27 = 0;
- } else {
- scan->x13 = 1;
- flag27 = 1;
- }
- break;
- }
- }
-
- if (!scan || flag27) {
- scan = lalloc(sizeof(RTTIBaseList));
- memclrw(scan, sizeof(RTTIBaseList));
-
- scan->next = list;
- list = scan;
- scan->base = tclassbase;
- scan->voffset = voffset;
- scan->x12 = flag;
- scan->x13 = flag27;
- }
- }
-
- for (base = tclassbase->bases; base; base = base->next) {
- if (base->is_virtual)
- newvoffset = CClass_VirtualBaseOffset(tclass, base->base);
- else
- newvoffset = voffset + base->offset;
-
- list = CRTTI_CreateBaseList(tclass, base->base, list, newvoffset, flag || base->access == ACCESSPRIVATE);
- }
-
- return list;
-}
-
-static void CRTTI_CreateSubClassList(TypeClass *tclass, RTTIBaseList *baselist, TypeClass *tclassbase, SInt32 voffset, Boolean flag) {
- ClassList *base;
- RTTISubClassList *scan;
- SInt32 newvoffset;
-
- if (baselist->base != tclassbase) {
- for (scan = baselist->subclasses; scan; scan = scan->next) {
- if (scan->base == tclassbase && scan->voffset == voffset)
- break;
- }
-
- if (!scan) {
- scan = lalloc(sizeof(RTTISubClassList));
- scan->next = baselist->subclasses;
- baselist->subclasses = scan;
-
- scan->base = tclassbase;
- scan->voffset = voffset;
- baselist->numsubclasses++;
- }
- }
-
- for (base = tclassbase->bases; base; base = base->next) {
- if (base->access == ACCESSPUBLIC) {
- if (base->is_virtual) {
- if (!flag)
- continue;
- newvoffset = CClass_VirtualBaseOffset(tclass, base->base);
- } else {
- newvoffset = voffset + base->offset;
- }
-
- CRTTI_CreateSubClassList(tclass, baselist, base->base, newvoffset, flag);
- }
- }
-}
-
-static Object *CRTTI_CreateBaseListObject(TypeClass *tclass) {
- RTTIBaseList *baselist;
- OLinkList *refs;
- Object *object;
- SInt32 *buf;
- SInt32 size;
- short count1;
- short count2;
- short total;
- OLinkList *ref;
- RTTIBaseList *scan;
- RTTISubClassList *subclass;
- SInt32 *work;
- SInt32 *work2;
-
- baselist = CRTTI_CreateBaseList(tclass, tclass, NULL, 0, 0);
- if (!baselist)
- return NULL;
-
- count1 = 0;
- count2 = 0;
- total = 0;
-
- for (scan = baselist; scan; scan = scan->next) {
- if (scan->x13 || scan->x12) {
- CRTTI_CreateSubClassList(tclass, scan, scan->base, scan->voffset, scan->x13 == 0);
- if (scan->numsubclasses) {
- total += scan->numsubclasses;
- count2++;
- }
- } else {
- count1++;
- }
- }
-
- if (!count1 && !count2)
- return NULL;
-
- size = (count1 + total) * 8 + count2 * 12 + 4;
- buf = lalloc(size);
- memclrw(buf, size);
-
- object = CParser_NewCompilerDefDataObject();
- object->name = CParser_GetUniqueName();
- object->type = CDecl_NewStructType(size, 4);
- object->qual = Q_CONST;
- object->sclass = TK_STATIC;
- refs = NULL;
-
- work = buf;
-
- if (count1) {
- for (scan = baselist; scan; scan = scan->next) {
- if (!scan->x12 && !scan->x13) {
- ref = lalloc(sizeof(OLinkList));
- ref->next = refs;
- refs = ref;
-
- ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0);
- ref->offset = ((char *) work) - ((char *) buf);
- ref->somevalue = 0;
-
- work[1] = CTool_EndianConvertWord32(scan->voffset);
- work += 2;
- }
- }
- }
-
- if (count2) {
- for (scan = baselist; scan; scan = scan->next) {
- if (scan->numsubclasses) {
- ref = lalloc(sizeof(OLinkList));
- ref->next = refs;
- refs = ref;
-
- ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0);
- ref->offset = ((char *) work) - ((char *) buf);
- ref->somevalue = 0;
-
- work[1] = CTool_EndianConvertWord32(scan->voffset | 0x80000000);
- work[2] = CTool_EndianConvertWord32(scan->numsubclasses);
- work2 = work + 3;
-
- for (subclass = scan->subclasses; subclass; subclass = subclass->next) {
- ref = lalloc(sizeof(OLinkList));
- ref->next = refs;
- refs = ref;
-
- ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(subclass->base), 0);
- ref->offset = ((char *) work2) - ((char *) buf);
- ref->somevalue = 0;
-
- work2[1] = CTool_EndianConvertWord32(subclass->voffset);
- work2 += 2;
- }
-
- work = work2;
- }
- }
- }
-
- CInit_DeclareData(object, buf, refs, object->type->size);
- return object;
-}
-
-static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual) {
- Object *baselistobj;
- Object *nameobj;
- HashNameNode *rttiname;
- OLinkList *refs;
- char *namestr;
- int namelen;
- Object *object;
- NameSpaceObjectList *list;
- TypePointer tptr_copy;
- TypeMemberPointer tmemptr_copy;
- UInt32 data[2];
-
- switch (type->type) {
- case TYPEPOINTER:
- if (TPTR_QUAL(type) & (Q_CONST | Q_VOLATILE)) {
- tptr_copy = *TYPE_POINTER(type);
- tptr_copy.qual &= ~(Q_CONST | Q_VOLATILE);
- type = TYPE(&tptr_copy);
- }
- break;
- case TYPEMEMBERPOINTER:
- if (TYPE_MEMBER_POINTER(type)->qual & (Q_CONST | Q_VOLATILE)) {
- tmemptr_copy = *TYPE_MEMBER_POINTER(type);
- tmemptr_copy.qual &= ~(Q_CONST | Q_VOLATILE);
- type = TYPE(&tmemptr_copy);
- }
- break;
- default:
- qual = 0;
- }
-
- if (IS_TYPE_CLASS(type) && type->size == 0) {
- CDecl_CompleteType(type);
- if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, type, 0);
- }
-
- rttiname = CMangler_RTTIObjectName(type, qual);
- list = CScope_FindName(cscope_root, rttiname);
-
- if (!list || (object = OBJECT(list->object))->otype != OT_OBJECT || object->datatype != DDATA) {
- namestr = CError_GetTypeName(type, qual, 0);
- namelen = strlen(namestr) + 1;
- nameobj = CInit_DeclareString(namestr, namelen, 0, 0);
-
- baselistobj = NULL;
- if (IS_TYPE_CLASS(type))
- baselistobj = CRTTI_CreateBaseListObject(TYPE_CLASS(type));
-
- memclrw(data, sizeof(data));
-
- object = CParser_NewCompilerDefDataObject();
- object->name = rttiname;
- object->type = CDecl_NewStructType(sizeof(data), 4);
- object->qual = Q_CONST;
- object->sclass = TK_STATIC;
-
- refs = lalloc(sizeof(OLinkList));
- refs->next = NULL;
- refs->obj = nameobj;
- refs->offset = 0;
- refs->somevalue = 0;
-
- if (baselistobj) {
- refs->next = lalloc(sizeof(OLinkList));
- refs->next->next = NULL;
- refs->next->obj = baselistobj;
- refs->next->offset = 4;
- refs->next->somevalue = 0;
- }
-
- CScope_AddGlobalObject(object);
- CInit_DeclareData(object, data, refs, object->type->size);
- }
-
- return object;
-}
-
-static void CRTTI_ConstructVTableHeader(TypeClass *tclass1, TypeClass *tclass2, Object *typeinfoObj, char *data, SInt32 offset, SInt32 voffset) {
- ClassList *base;
- Offset *o;
- OLinkList *olink;
- SInt32 tmp;
- SInt32 newoffset;
- SInt32 newvoffset;
-
- if (tclass2->vtable->owner == tclass2) {
- for (o = crtti_offsets; o; o = o->next) {
- if (o->offset == voffset)
- break;
- }
-
- if (!o) {
- o = lalloc(sizeof(Offset));
- o->next = crtti_offsets;
- o->offset = voffset;
- crtti_offsets = o;
-
- olink = lalloc(sizeof(OLinkList));
- olink->next = crtti_olinks;
- olink->obj = typeinfoObj;
- olink->offset = voffset;
- olink->somevalue = 0;
- crtti_olinks = olink;
-
- *((SInt32 *) (data + voffset + 4)) = CTool_EndianConvertWord32(-offset);
- } else {
- tmp = *((SInt32 *) (data + voffset + 4));
- CError_ASSERT(404, tmp == CTool_EndianConvertWord32(-offset));
- }
- }
-
- for (base = tclass2->bases; base; base = base->next) {
- if (base->base->vtable) {
- if (base->is_virtual) {
- newoffset = CClass_VirtualBaseOffset(tclass1, base->base);
- newvoffset = CClass_VirtualBaseVTableOffset(tclass1, base->base);
- } else {
- newoffset = offset + base->offset;
- newvoffset = voffset + base->voffset;
- }
-
- CRTTI_ConstructVTableHeader(tclass1, base->base, typeinfoObj, data, newoffset, newvoffset);
- }
- }
-}
-
-OLinkList *CRTTI_ConstructVTableHeaders(TypeClass *tclass, void *data, OLinkList *links) {
- crtti_offsets = NULL;
- crtti_olinks = links;
-
- CRTTI_ConstructVTableHeader(
- tclass, tclass,
- CRTTI_ConstructTypeInfoObject(TYPE(tclass), 0),
- data, 0, 0);
-
- return crtti_olinks;
-}
-
-static Type *CRTTI_FindTypeInfoType(void) {
- NameSpace *nspace;
- NameSpaceObjectList *list;
- Type *type;
-
- if ((list = CScope_FindName(cscope_root, GetHashNameNodeExport("std"))) && list->object->otype == OT_NAMESPACE)
- nspace = OBJ_NAMESPACE(list->object)->nspace;
- else
- nspace = cscope_root;
-
- type = CScope_GetLocalTagType(nspace, GetHashNameNodeExport("type_info"));
- if (type && IS_TYPE_CLASS(type) && type->size)
- return type;
-
- CError_Error(CErrorStr140, "::std::type_info");
- return TYPE(&stchar);
-}
-
-ENode *CRTTI_ParseTypeID(void) {
- ENode *expr;
- Type *type;
- Type *typeinfoType;
- UInt32 qual;
-
- if (!copts.RTTI)
- CError_Warning(CErrorStr257);
-
- typeinfoType = CRTTI_FindTypeInfoType();
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return nullnode();
- }
-
- tk = lex();
- if ((type = CParser_ParseTypeID(&qual, NULL))) {
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
- } else {
- expr = s_expression();
-
- if (tk != ')')
- CError_ErrorSkip(CErrorStr115);
- else
- tk = lex();
-
- type = expr->rtype;
- qual = ENODE_QUALS(expr);
-
- if (IS_TYPE_REFERENCE(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->vtable) {
- expr = funccallexpr(
- Rgtid_func,
- getnodeaddress(expr, 0),
- intconstnode(TYPE(&stsignedlong), TYPE_CLASS(type)->vtable->offset),
- NULL,
- NULL);
- expr->rtype = CDecl_NewPointerType(typeinfoType);
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = typeinfoType;
- expr->flags = ENODE_FLAG_CONST;
- return expr;
- }
- }
-
- expr = create_objectrefnode(CRTTI_ConstructTypeInfoObject(type, qual));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = typeinfoType;
- expr->flags = ENODE_FLAG_CONST;
- return expr;
-}
-
-static void CRTTI_ConstCastQualCheck(UInt32 qual1, UInt32 qual2) {
- if (
- ((qual1 & Q_CONST) && !(qual2 & Q_CONST)) ||
- ((qual1 & Q_VOLATILE) && !(qual2 & Q_VOLATILE))
- )
- CError_Error(CErrorStr258);
-}
-
-static void CRTTI_ConstCastCheck(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2) {
- Boolean flag = 1;
- if (IS_TYPE_REFERENCE(type2)) {
- type2 = TPTR_TARGET(type2);
- flag = 0;
- }
-
- while (1) {
- if (type1->type != type2->type)
- break;
-
- switch (type1->type) {
- case TYPEPOINTER:
- if (!flag)
- CRTTI_ConstCastQualCheck(TPTR_QUAL(type1), TPTR_QUAL(type2));
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- flag = 0;
- continue;
-
- case TYPEMEMBERPOINTER:
- if (!flag)
- CRTTI_ConstCastQualCheck(TYPE_MEMBER_POINTER(type1)->qual, TYPE_MEMBER_POINTER(type2)->qual);
- type1 = TYPE_MEMBER_POINTER(type1)->ty1;
- type2 = TYPE_MEMBER_POINTER(type2)->ty1;
- flag = 0;
- continue;
- }
-
- break;
- }
-
- if (!flag && !IS_TYPE_FUNC(type1) && !IS_TYPE_FUNC(type2))
- CRTTI_ConstCastQualCheck(CParser_GetCVTypeQualifiers(type1, qual1), CParser_GetCVTypeQualifiers(type2, qual2));
-}
-
-static ENode *CRTTI_ParseCast(DeclInfo *di) {
- ENode *expr;
-
- if (lex() != '<') {
- CError_Error(CErrorStr230);
- return NULL;
- }
-
- tk = lex();
-
- memclrw(di, sizeof(DeclInfo));
- CParser_GetDeclSpecs(di, 0);
- scandeclarator(di);
-
- if (di->name)
- CError_Error(CErrorStr164);
-
- if (tk != '>') {
- CError_Error(CErrorStr231);
- return NULL;
- }
-
- if (lex() != '(') {
- CError_Error(CErrorStr114);
- return NULL;
- }
-
- tk = lex();
- expr = s_expression();
- if (!IS_TYPE_REFERENCE(di->thetype))
- expr = pointer_generation(expr);
-
- if (tk != ')') {
- CError_Error(CErrorStr115);
- return NULL;
- }
-
- tk = lex();
- return expr;
-}
-
-static void CRTTI_IncompleteCheck(Type *type) {
- if (IS_TYPE_POINTER_ONLY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type) && type->size == 0) {
- CDecl_CompleteType(type);
- if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
- CError_Error(CErrorStr136, type, 0);
- }
-}
-
-static Boolean CRTTI_IsSameType(Type *a, Type *b) {
- while (1) {
- if (a->type != b->type)
- return 0;
-
- switch (a->type) {
- case TYPEVOID:
- return 1;
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- return a == b;
- case TYPEPOINTER:
- a = TPTR_TARGET(a);
- b = TPTR_TARGET(b);
- continue;
- default:
- return is_typesame(a, b);
- }
- }
-}
-
-static ENode *CRTTI_UniversalCast(ENode *expr, Type *type, UInt32 qual, UInt8 mode) {
- // type/qual are the target type
- Boolean isSimpleCast;
- Boolean needsTypcon;
- Boolean failed;
-
- if (ENODE_IS(expr, EOBJLIST))
- return CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1);
-
- isSimpleCast = needsTypcon = failed = 0;
-
- switch (type->type) {
- case TYPEINT:
- case TYPEENUM:
- if (mode == 2 && IS_TYPE_POINTER_ONLY(expr->rtype) && type != TYPE(&stbool))
- failed = 1;
- break;
-
- case TYPEPOINTER:
- if (TPTR_QUAL(type) & Q_REFERENCE) {
- if (
- !CRTTI_IsSameType(TPTR_TARGET(type), expr->rtype) &&
- mode == 2 &&
- !(
- IS_TYPE_CLASS(TPTR_TARGET(type)) &&
- IS_TYPE_CLASS(expr->rtype) &&
- (
- CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(expr->rtype), NULL, 0, 1) ||
- CClass_IsBaseClass(TYPE_CLASS(expr->rtype), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1)
- )
- )
- )
- {
- failed = 1;
- }
- } else if (IS_TYPE_POINTER_ONLY(expr->rtype)) {
- if (
- mode == 3 ||
- CRTTI_IsSameType(type, expr->rtype) ||
- IS_TYPE_VOID(TPTR_TARGET(type)) ||
- IS_TYPE_VOID(TPTR_TARGET(expr->rtype))
- )
- {
- isSimpleCast = needsTypcon = 1;
- }
- else if (
- mode == 2 &&
- !(
- IS_TYPE_CLASS(TPTR_TARGET(type)) &&
- IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) &&
- (
- CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(TPTR_TARGET(expr->rtype)), NULL, 0, 1) ||
- CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1)
- )
- )
- )
- {
- failed = 1;
- }
- } else {
- if (IS_TYPE_ENUM(expr->rtype))
- expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
-
- if (IS_TYPE_INT(expr->rtype)) {
- if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
- isSimpleCast = 1;
- break;
- }
-
- if (mode != 2)
- break;
- }
-
- if (IS_TYPE_CLASS(expr->rtype)) {
- if (mode == 2)
- break;
- }
-
- failed = 1;
- }
- break;
- }
-
- if (failed) {
- CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
- return expr;
- }
-
- if (isSimpleCast) {
- if (needsTypcon && ENODE_IS(expr, EINDIRECT) && (copts.pointercast_lvalue || !copts.ANSIstrict))
- expr = makemonadicnode(expr, ETYPCON);
-
- expr->rtype = type;
- expr->flags = qual & ENODE_FLAG_QUALS;
- return expr;
- }
-
- if (copts.old_argmatch)
- return do_typecast(expr, type, qual);
-
- return CExpr_Convert(expr, type, qual, 1, 1);
-}
-
-ENode *CRTTI_Parse_dynamic_cast(void) {
- Boolean isRef;
- ENode *expr;
- TypeClass *srcclass;
- TypeClass *destclass;
- ENode *typeinfo;
- DeclInfo di;
-
- expr = CRTTI_ParseCast(&di);
- if (!expr)
- return nullnode();
-
- if (!copts.RTTI)
- CError_Warning(CErrorStr257);
-
- CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
- if (!IS_TYPE_POINTER_ONLY(di.thetype)) {
- CError_Error(CErrorStr164);
- return expr;
- }
-
- isRef = (TPTR_QUAL(di.thetype) & Q_REFERENCE) != 0;
-
- if (IS_TYPE_CLASS(TPTR_TARGET(di.thetype))) {
- destclass = TYPE_CLASS(TPTR_TARGET(di.thetype));
- CDecl_CompleteType(TYPE(destclass));
- if (!(destclass->flags & CLASS_COMPLETED)) {
- CError_Error(CErrorStr136, destclass, 0);
- return expr;
- }
- } else if (!IS_TYPE_VOID(TPTR_TARGET(di.thetype))) {
- CError_Error(CErrorStr164);
- return expr;
- } else {
- destclass = NULL;
- }
-
- if (isRef) {
- if (!IS_TYPE_CLASS(expr->rtype)) {
- CError_Error(CErrorStr164);
- return expr;
- }
-
- srcclass = TYPE_CLASS(expr->rtype);
- if (destclass) {
- if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1))
- return do_typecast(expr, di.thetype, di.qual);
- }
-
- expr = getnodeaddress(expr, 1);
- } else {
- if (!IS_TYPE_POINTER_ONLY(expr->rtype) || !IS_TYPE_CLASS(TPTR_TARGET(expr->rtype))) {
- CError_Error(CErrorStr164);
- return expr;
- }
-
- srcclass = TYPE_CLASS(TPTR_TARGET(expr->rtype));
- if (destclass) {
- if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1))
- return do_typecast(expr, di.thetype, di.qual);
- }
- }
-
- if (!(srcclass->flags & CLASS_COMPLETED)) {
- CError_Error(CErrorStr136, srcclass, 0);
- return expr;
- }
-
- if (!srcclass->vtable) {
- CError_Error(CErrorStr164);
- return expr;
- }
-
- if (srcclass->sominfo) {
- CError_Error(CErrorStr164);
- return expr;
- }
-
- if (destclass) {
- typeinfo = create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(destclass), 0));
- if (destclass->sominfo) {
- CError_Error(CErrorStr164);
- return expr;
- }
- } else {
- typeinfo = nullnode();
- }
-
- expr = CExpr_FuncCallSix(
- Rdync_func,
- expr,
- intconstnode(TYPE(&stsignedlong), srcclass->vtable->offset),
- typeinfo,
- create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(srcclass), 0)),
- intconstnode(TYPE(&stsignedshort), isRef),
- NULL
- );
-
- if (isRef) {
- expr->rtype = CDecl_NewPointerType(TYPE(destclass));
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TYPE(destclass);
- } else {
- expr->rtype = di.thetype;
- }
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- return expr;
-}
-
-ENode *CRTTI_Parse_static_cast(void) {
- ENode *expr;
- DeclInfo di;
-
- expr = CRTTI_ParseCast(&di);
- if (!expr)
- return nullnode();
-
- CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
-
- if (IS_TYPE_REFERENCE(di.thetype)) {
- if (IS_TYPE_CLASS(expr->rtype) && CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual)) {
- expr = CExpr_Convert(expr, di.thetype, di.qual, 0, 1);
- CError_ASSERT(959, IS_TYPE_POINTER_ONLY(expr->rtype));
-
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(di.thetype);
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- return expr;
- }
- } else {
- if (CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual))
- return CExpr_Convert(expr, di.thetype, di.qual, 1, 1);
- }
-
- if (!IS_TYPE_VOID(di.thetype) && !(IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_VOID(TPTR_TARGET(expr->rtype)))) {
- CRTTI_IncompleteCheck(di.thetype);
- CRTTI_IncompleteCheck(expr->rtype);
- }
-
- return CRTTI_UniversalCast(expr, di.thetype, di.qual, 2);
-}
-
-ENode *CRTTI_Parse_reinterpret_cast(void) {
- ENode *expr;
- Type *origtype;
- ENode *lvalue;
- DeclInfo di;
-
- expr = CRTTI_ParseCast(&di);
- if (!expr)
- return nullnode();
-
- CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
-
- if (IS_TYPE_REFERENCE(di.thetype)) {
- lvalue = CExpr_LValue(expr, 0, 1);
- if (!ENODE_IS(lvalue, EINDIRECT))
- return lvalue;
-
- lvalue->data.monadic->rtype = CDecl_NewPointerType(lvalue->rtype);
- expr = lvalue->data.monadic;
- origtype = di.thetype;
- di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype));
- } else {
- origtype = NULL;
- }
-
- switch (di.thetype->type) {
- case TYPEINT:
- switch (expr->rtype->type) {
- case TYPEMEMBERPOINTER:
- case TYPEPOINTER:
- expr = do_typecast(expr, di.thetype, di.qual);
- break;
- default:
- CError_Error(CErrorStr164);
- }
- break;
- case TYPEPOINTER:
- switch (expr->rtype->type) {
- case TYPEINT:
- case TYPEENUM:
- if (origtype)
- di.thetype = origtype;
- expr = do_typecast(expr, di.thetype, di.qual);
- break;
- case TYPEPOINTER:
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = di.thetype;
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- break;
- default:
- CError_Error(CErrorStr164);
- }
- break;
- case TYPEMEMBERPOINTER:
- if (IS_TYPE_MEMBERPOINTER(expr->rtype)) {
- if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(di.thetype)->ty1)) {
- if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) {
- expr->rtype = di.thetype;
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- break;
- }
- } else {
- if (!IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) {
- expr->rtype = di.thetype;
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- break;
- }
- }
- }
- expr = do_typecast(expr, di.thetype, di.qual);
- break;
- default:
- CError_Error(CErrorStr164);
- }
-
- if (origtype && IS_TYPE_POINTER_ONLY(expr->rtype)) {
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = TPTR_TARGET(di.thetype);
- }
-
- return expr;
-}
-
-ENode *CRTTI_Parse_const_cast(void) {
- DeclInfo di;
- ENode *expr;
-
- if (!(expr = CRTTI_ParseCast(&di)))
- return nullnode();
-
- if (IS_TYPE_POINTER_ONLY(di.thetype)) {
- if (TPTR_QUAL(di.thetype) & Q_REFERENCE) {
- if (!iscpp_typeequal(TPTR_TARGET(di.thetype), expr->rtype))
- CError_Error(CErrorStr164);
-
- if (ENODE_IS(expr, EINDIRECT)) {
- expr->rtype = TPTR_TARGET(di.thetype);
- expr->flags = di.qual & ENODE_FLAG_QUALS;
- } else {
- CError_Error(CErrorStr142);
- }
- } else {
- if (!iscpp_typeequal(di.thetype, expr->rtype))
- CError_Error(CErrorStr164);
-
- expr = do_typecast(expr, di.thetype, di.qual);
- }
- } else if (IS_TYPE_MEMBERPOINTER(di.thetype)) {
- if (!iscpp_typeequal(di.thetype, expr->rtype))
- CError_Error(CErrorStr164);
-
- expr = do_typecast(expr, di.thetype, di.qual);
- } else {
- if (!is_typesame(di.thetype, expr->rtype))
- CError_Error(CErrorStr164);
- else
- expr = do_typecast(expr, di.thetype, di.qual);
- }
-
- return expr;
-}
diff --git a/compiler_and_linker/unsorted/CSOM.c b/compiler_and_linker/unsorted/CSOM.c
deleted file mode 100644
index afd68a3..0000000
--- a/compiler_and_linker/unsorted/CSOM.c
+++ /dev/null
@@ -1,2069 +0,0 @@
-#include "compiler/CSOM.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-#include "cos.h"
-
-// all pointers have been converted to UInt32 for the sake of maintaining 32-bit compat
-
-typedef struct {
- SInt32 zero;
- /* struct somStaticClassInfo * */ UInt32 sci;
- /* void * */ UInt32 instanceDataToken;
- SInt32 reserved[3];
- /* void * */ UInt32 tokens[1];
-} somClassDataStructure;
-
-enum {
- mtVirtualMethod = 0,
- mtProcedure = 1,
- mtNonStatic = 2,
- mtEmpty = 3,
- mtDToken = 4
-};
-
-enum {
- pdUByte = 0,
- pdSByte = 1,
- pdUHalf = 2,
- pdSHalf = 3,
- pdULong = 4,
- pdSLong = 5,
- pdVLong = 6,
- pdVoid = 7,
- pdSFlt = 8,
- pdDFlt = 9,
- pdLFlt = 10,
- pdVSAgg = 11,
- pdNPtr = 12,
- pdLPtr = 13,
- pdSAgg = 14,
- pdLAgg = 15
-};
-
-enum {
- fgShortOrChars = 1,
- fgShortFloats = 2,
- fgAnyFloats = 4,
- fgAnyNon4Bytes = 8
-};
-
-enum {
- cfSharedStrings = 1,
- cfTempClass = 2,
- cfProxyClass = 4,
- cfClassAllocate = 0x100,
- cfClassDeallocate = 0x200,
- cfClassInit = 0x400,
- cfClassUninit = 0x800
-};
-
-typedef struct {
- UInt32 majorVersion;
- UInt32 minorVersion;
- UInt32 flags;
- UInt16 dataAlignment;
- UInt16 classTokenCount;
- UInt16 numDirectParents;
- UInt16 numMetaClasses;
- UInt16 numOverriddenAncestors;
- UInt16 numMigratedMethods;
- UInt16 numSelectInherited;
- UInt16 numUnused;
- UInt16 dummy2a[4];
-} somStaticClassCounts;
-
-typedef UInt8 somSlotUsage;
-typedef UInt8 somSignatureInfo;
-typedef UInt16 somOverrideData;
-typedef UInt16 somMigratedMethods;
-typedef UInt16 somSelectedInherited;
-typedef UInt32 somParentVersions;
-
-typedef struct {
- /* const char * */ UInt32 className;
- UInt32 instanceDataSize;
- /* const somParentVersions * */ UInt32 parentVersions;
- /* const somSlotUsage * */ UInt32 ttSlotUsage;
- /* const somSignatureInfo * */ UInt32 signatureInfo;
- /* const char * */ UInt32 methodNames;
- /* const somOverrideData * */ UInt32 overrideData;
- /* const somMigratedMethods * */ UInt32 migratedMethods;
- /* const somSelectedInherited * */ UInt32 selectedInherited;
- /* const void * */ UInt32 unused;
- /* const void * */ UInt32 dummy4b[4];
-} somStaticClassDescription;
-
-typedef struct somStaticClassInfo {
- UInt32 layoutVersion;
- /* somClassDataStructure * */ UInt32 tokenTable;
- /* somMethodPtr * */ UInt32 overrideMethods;
- /* somClassDataStructure ** */ UInt32 specifiedAncestry;
- /* somOpaque */ UInt32 DLLDesignator;
- /* somMethodPtr * */ UInt32 specialProcs;
- /* somRuntimeClassInfo * */ UInt32 runtimeClassInfo;
- SInt32 interesting;
- /* somClassDataStructure ** */ UInt32 actualAncestry;
- /* void * */ UInt32 extra[4];
- /* const somStaticClassCounts * */ UInt32 classCounts;
- somStaticClassDescription classDescription;
-} somStaticClassInfo;
-
-CSOMStub *csom_stubs;
-static HashNameNode *csom_initname;
-static HashNameNode *csom_uninitname;
-static HashNameNode *csom_envname;
-static HashNameNode *csom_selfname;
-
-static FuncArg SOMIDT_arg1 = {
- NULL,
- NULL,
- NULL,
- TYPE(&void_ptr),
- 0,
- 0,
- 0,
- 0
-};
-
-static TypeFunc SOMIDT_type = {
- TYPEFUNC,
- 0,
- &SOMIDT_arg1,
- NULL,
- TYPE(&void_ptr),
- 0,
- 0
-};
-
-void CSOM_Setup(Boolean flag) {
- if (!flag)
- csom_stubs = NULL;
-
- csom_initname = GetHashNameNodeExport("somInit");
- csom_uninitname = GetHashNameNodeExport("somUninit");
- csom_envname = GetHashNameNodeExport("Environment");
- csom_selfname = GetHashNameNodeExport("__somself");
-}
-
-void CSOM_Cleanup(void) {
- CSOMStub *stub;
-
- if (cparamblkptr->precompile != 1) {
- for (stub = csom_stubs; stub; stub = stub->next) {
- switch (stub->x10) {
- case 0:
- CodeGen_SOMStub(stub->object, rt_som_glue1, stub->tclass->sominfo->classdataobject, stub->offset);
- break;
- case 1:
- CodeGen_SOMStub(stub->object, rt_som_glue2, stub->tclass->sominfo->classdataobject, stub->offset);
- break;
- case 2:
- CodeGen_SOMStub(stub->object, rt_som_glue3, stub->tclass->sominfo->classdataobject, stub->offset);
- break;
- default:
- CError_FATAL(132);
- }
- }
- }
-}
-
-static HashNameNode *CSOM_NameTranslate(HashNameNode *name) {
- if (name == constructor_name_node)
- name = csom_initname;
- else if (name == destructor_name_node)
- name = csom_uninitname;
- return name;
-}
-
-static Type *CSOM_FindClassType(HashNameNode *name) {
- Type *type;
-
- type = CScope_GetTagType(cscope_current, name);
- if (!type) {
- CPrep_ErrorName(CErrorStr281, name->name);
- type = &stvoid;
- }
-
- return type;
-}
-
-CW_INLINE UInt16 CSOM_GetTokenTableIndex(const Object *object) {
- CError_ASSERT(173, IS_TYPE_METHOD(object->type));
- return TYPE_METHOD(object->type)->vtbl_index;
-}
-
-static SInt32 CSOM_GetTokenOffset(Object *object) {
- return 24 + 4 * CSOM_GetTokenTableIndex(object);
-}
-
-typedef struct TypeSig {
- UInt8 x0;
- UInt8 x1;
- UInt8 x2;
-} TypeSig;
-
-static int CSOM_GetTypeSig(TypeSig *sig, Type *type, Boolean flag) {
- if (type->size > 4)
- sig->x1 |= fgAnyNon4Bytes;
-
- switch (type->type) {
- case TYPEVOID:
- if (flag)
- return pdVoid;
- break;
- case TYPEINT:
- case TYPEENUM:
- if (is_unsigned(type)) {
- switch (type->size) {
- case 1:
- sig->x1 |= fgShortOrChars;
- return pdUByte;
- case 2:
- sig->x1 |= fgShortOrChars;
- return pdUHalf;
- case 4:
- return pdULong;
- case 8:
- return pdVLong;
- }
- } else {
- switch (type->size) {
- case 1:
- sig->x1 |= fgShortOrChars;
- return pdSByte;
- case 2:
- sig->x1 |= fgShortOrChars;
- return pdSHalf;
- case 4:
- return pdSLong;
- case 8:
- return pdVLong;
- }
- }
- break;
- case TYPEFLOAT:
- sig->x1 |= fgAnyFloats;
- switch (type->size) {
- case 4:
- sig->x1 |= fgShortFloats;
- return pdSFlt;
- case 8:
- return pdDFlt;
- case 12:
- case 16:
- return pdLFlt;
- }
- break;
- case TYPEPOINTER:
- return pdNPtr;
- case TYPESTRUCT:
- case TYPECLASS:
- if (flag) {
- if (type->size <= 2) {
- sig->x1 |= fgShortOrChars;
- return pdVSAgg;
- } else if (type->size <= 4) {
- return pdSAgg;
- } else {
- return pdLAgg;
- }
- }
- break;
- }
-
- CError_Error(CErrorStr273);
- return 5;
-}
-
-static void CSOM_GetFuncSig(TypeFunc *tfunc, Boolean flag) {
- FuncArg *arg;
- Boolean pendingData;
- UInt8 work;
- TypeSig sig;
-
- sig.x2 = CSOM_GetTypeSig(&sig, tfunc->functype, 1);
- sig.x1 = 0;
- sig.x0 = 0;
-
- for (arg = tfunc->args; arg; arg = arg->next) {
- if (arg == &elipsis || arg == &oldstyle || (++sig.x0 == 0)) {
- CError_Error(CErrorStr273);
- break;
- }
-
- CSOM_GetTypeSig(&sig, arg->type, 0);
- }
-
- if (flag) {
- if ((arg = tfunc->args)) {
- if (TYPE_METHOD(tfunc)->is_static == 0)
- arg = arg->next;
- if (arg && CMach_GetFunctionResultClass(tfunc) != 0)
- arg = arg->next;
- }
-
- AppendGListByte(&name_mangle_list, sig.x0);
- AppendGListByte(&name_mangle_list, (sig.x1 << 4) | sig.x2);
- if (sig.x1) {
- pendingData = 0;
- work = 0;
- while (arg) {
- work = (work << 4) | CSOM_GetTypeSig(&sig, arg->type, 0);
- if (pendingData) {
- AppendGListByte(&name_mangle_list, work);
- pendingData = 0;
- work = 0;
- } else {
- pendingData = 1;
- }
- arg = arg->next;
- }
-
- if (pendingData)
- AppendGListByte(&name_mangle_list, work << 4);
- }
- }
-}
-
-void CSOM_CheckFuncType(TypeFunc *tfunc) {
- CSOM_GetFuncSig(tfunc, 0);
-}
-
-static Object *CSOM_MakeObject(char *name1, char *name2, SInt32 size) {
- Object *object = CParser_NewCompilerDefDataObject();
- object->name = CParser_NameConcat(name1, name2);
- object->type = CDecl_NewStructType(size, 4);
- CScope_AddObject(object->nspace, object->name, OBJ_BASE(object));
- return object;
-}
-
-void CSOM_MakeSOMClass(TypeClass *tclass) {
- ClassList *base;
-
- for (base = tclass->bases; base; base = base->next) {
- if (!base->base->sominfo) {
- CError_Error(CErrorStr267);
- break;
- }
- }
-
- if (!tclass->sominfo) {
- SOMInfo *info = galloc(sizeof(SOMInfo));
- memclrw(info, sizeof(SOMInfo));
- tclass->sominfo = info;
-
- info->classdataobject = CSOM_MakeObject(tclass->classname->name, "ClassData", 28);
- info->classdataobject->flags = info->classdataobject->flags | OBJECT_EXPORT;
- }
-}
-
-static Boolean CSOM_IsTokenListFunc(Object *object) {
- Type *type = object->type;
- if (
- IS_TYPE_FUNC(type) &&
- !(TYPE_FUNC(type)->flags & FUNC_FLAGS_20) &&
- !TYPE_METHOD(type)->is_static &&
- (!(object->qual & Q_INLINE) || object->datatype == DVFUNC)
- )
- return 1;
-
- return 0;
-}
-
-static Object **CSOM_GetLexicalOrderMethodArray(TypeClass *tclass, int *resultCount) {
- Object *object;
- int count;
- Object **array;
- CScopeObjectIterator iter;
-
- count = 0;
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (IS_TYPE_METHOD(object->type)) {
- if (CSOM_IsTokenListFunc(object)) {
- if (TYPE_METHOD(object->type)->vtbl_index > count)
- count = TYPE_METHOD(object->type)->vtbl_index;
- } else {
- TYPE_METHOD(object->type)->vtbl_index = 0;
- }
- }
- }
-
- *resultCount = ++count;
-
- array = lalloc(sizeof(Object *) * count);
- memclrw(array, sizeof(Object *) * count);
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (CSOM_IsTokenListFunc(object))
- array[TYPE_METHOD(object->type)->vtbl_index] = object;
- }
-
- return array;
-}
-
-void CSOM_ClassComplete(TypeClass *tclass) {
- Object *object;
- CScopeObjectIterator iter;
- SInt32 counter;
- SOMReleaseOrder *order;
-
- if (tclass->sominfo->order) {
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (CSOM_IsTokenListFunc(object)) {
- HashNameNode *name;
-
- name = CSOM_NameTranslate(object->name);
- for (order = tclass->sominfo->order, counter = 0; order; order = order->next, counter++) {
- if (order->name == name) {
- order->state = SOMMS_Method;
- TYPE_METHOD(object->type)->vtbl_index = counter;
- break;
- }
- }
-
- if (!order)
- CError_Error(CErrorStr278, object);
- }
- }
-
- for (order = tclass->sominfo->order; order; order = order->next) {
- if (order->state == SOMMS_Deleted) {
- SOMReleaseOrder *order2;
- VClassList *vbase;
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- for (order2 = vbase->base->sominfo->order; order2; order2 = order2->next) {
- if (order->name == order2->name && order2->state == SOMMS_Method) {
- order->state = SOMMS_Migrated;
- break;
- }
- }
- }
- }
- }
- } else {
- Object **array;
- int arrayCount;
- SInt32 i;
-
- array = CSOM_GetLexicalOrderMethodArray(tclass, &arrayCount);
- for (i = counter = 0; i < arrayCount; i++) {
- object = array[i];
- if (object) {
- if (counter == 0 && copts.pedantic)
- CError_Warning(CErrorStr291);
- TYPE_METHOD(object->type)->vtbl_index = counter++;
- }
- }
- }
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- NameSpaceObjectList *nsol;
- if (!(nsol = CScope_NextObjectIteratorObjectList(&iter)))
- break;
-
- if (nsol->object->otype == OT_OBJECT && nsol->next && nsol->next->object->otype == OT_OBJECT) {
- while (nsol) {
- if (
- nsol->object->otype == OT_OBJECT &&
- (!(OBJECT(nsol->object)->qual & Q_INLINE) || OBJECT(nsol->object)->datatype == DVFUNC)
- )
- CError_Error(CErrorStr270, nsol->object);
- nsol = nsol->next;
- }
- }
- }
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (!(object->qual & Q_INLINE)) {
- CError_ASSERT(529, IS_TYPE_FUNC(object->type));
-
- TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_4;
- tclass->action = CLASS_ACTION_1;
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (IS_TYPE_FUNC(object->type))
- TYPE_FUNC(object->type)->flags &= ~FUNC_FLAGS_4;
- }
- break;
- }
- }
-
- if (tclass->sominfo->oidl_callstyle == 0) {
- Type *envType;
- envType = CSOM_FindClassType(csom_envname);
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- IS_TYPE_FUNC(object->type) &&
- TYPE_METHOD(object->type)->is_static == 0 &&
- !(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20) &&
- !(
- TYPE_FUNC(object->type)->args &&
- TYPE_FUNC(object->type)->args->next &&
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->args->next->type) &&
- TPTR_TARGET(TYPE_FUNC(object->type)->args->next->type) == envType
- )
- )
- {
- CError_Error(CErrorStr282, object);
- }
- }
- }
-
- if (tclass->action == CLASS_ACTION_0)
- CError_Error(CErrorStr280);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct SOMOverride {
- struct SOMOverride *next;
- Object *a;
- Object *b;
-} SOMOverride;
-
-typedef struct SOMAncestor {
- struct SOMAncestor *next;
- TypeClass *tclass;
- SOMOverride *overrides;
- Boolean xC;
- Boolean xD;
-} SOMAncestor;
-
-typedef struct SOMMethod {
- struct SOMMethod *next;
- HashNameNode *name;
- union {
- Object *object;
- struct {
- UInt16 a;
- UInt16 b;
- } pair;
- } u;
- SOMMethodState state;
-} SOMMethod;
-
-typedef struct SOMGenerator {
- SOMMethod *methods;
- SOMAncestor *ancestors;
- Object *sciObj;
- Object *classAncestorsObj;
- Object *overrideProcsObj;
- Object *dlldFunc;
- Object *specialProcsObj;
- somStaticClassCounts counts;
- int overrideProcsCount;
- Boolean hasNew;
- Boolean hasDelete;
-} SOMGenerator;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static SOMAncestor *CSOM_FindAddAncestor(SOMGenerator *gen, TypeClass *tclass, TypeClass *ancestorClass, UInt16 *resultIndex) {
- SOMAncestor *ancestor;
- SOMAncestor *scan;
- UInt16 index;
-
- ancestor = gen->ancestors;
- for (scan = ancestor, index = 0; scan; scan = scan->next, index++) {
- if (scan->tclass == ancestorClass) {
- if (resultIndex)
- *resultIndex = index;
- return scan;
- }
- }
-
- if (ancestor) {
- index = 1;
- while (ancestor->next) {
- index++;
- ancestor = ancestor->next;
- }
-
- ancestor->next = lalloc(sizeof(SOMAncestor));
- memclrw(ancestor->next, sizeof(SOMAncestor));
- ancestor = ancestor->next;
- } else {
- index = 0;
- ancestor = lalloc(sizeof(SOMAncestor));
- memclrw(ancestor, sizeof(SOMAncestor));
- gen->ancestors = ancestor;
- }
-
- ancestor->tclass = ancestorClass;
- if (resultIndex)
- *resultIndex = index;
- return ancestor;
-}
-
-static void CSOM_GenerateOverrideIntroLists(SOMGenerator *gen, TypeClass *tclass) {
- Object *object;
- VClassList *vbase;
- ClassList *base;
- SOMMethod *method;
- SOMMethod **ptr;
- CScopeObjectIterator iter;
-
- for (base = tclass->bases; base; base = base->next) {
- SOMAncestor *ancestor = CSOM_FindAddAncestor(gen, tclass, base->base, NULL);
- ancestor->xD = 1;
- gen->counts.numDirectParents++;
- }
-
- if (tclass->sominfo->metaclass && tclass->sominfo->metaclass->sominfo) {
- SOMAncestor *ancestor = CSOM_FindAddAncestor(gen, tclass, tclass->sominfo->metaclass, NULL);
- ancestor->xC = 1;
- gen->counts.numMetaClasses++;
- }
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (IS_TYPE_FUNC(object->type) && (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20)) {
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- Object *object2;
- CScopeObjectIterator iter2;
- CScope_InitObjectIterator(&iter2, vbase->base->nspace);
- while (1) {
- if (!(object2 = OBJECT(CScope_NextObjectIteratorObject(&iter2))))
- break;
-
- if (
- IS_TYPE_FUNC(object2->type) &&
- object->name == object2->name &&
- object2->datatype == DVFUNC &&
- !(TYPE_FUNC(object2->type)->flags & FUNC_FLAGS_20) &&
- CClass_GetOverrideKind(TYPE_FUNC(object->type), TYPE_FUNC(object2->type), 0) != 0
- )
- {
- SOMAncestor *ancestor;
- SOMOverride *override;
- ancestor = CSOM_FindAddAncestor(gen, tclass, vbase->base, NULL);
- if (ancestor->overrides) {
- override = lalloc(sizeof(SOMOverride));
- memclrw(override, sizeof(SOMOverride));
- override->next = ancestor->overrides;
- ancestor->overrides = override;
- } else {
- override = lalloc(sizeof(SOMOverride));
- memclrw(override, sizeof(SOMOverride));
- ancestor->overrides = override;
- gen->counts.numOverriddenAncestors++;
- }
- override->a = object;
- override->b = object2;
- break;
- }
- }
- }
- gen->overrideProcsCount++;
- }
- }
-
- ptr = &gen->methods;
- if (tclass->sominfo->order) {
- SOMReleaseOrder *order;
- SOMReleaseOrder *order2;
- SInt32 index;
- UInt16 index2;
-
- for (order = tclass->sominfo->order, index = 0; order; order = order->next, index++) {
- method = lalloc(sizeof(SOMMethod));
- memclrw(method, sizeof(SOMMethod));
- *ptr = method;
- ptr = &method->next;
-
- method->name = order->name;
- method->state = order->state;
- switch (order->state) {
- case SOMMS_Migrated:
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- for (order2 = vbase->base->sominfo->order, index2 = 0; order2; order2 = order2->next, index2++) {
- if (order->name == order2->name && order2->state == SOMMS_Method) {
- CSOM_FindAddAncestor(gen, tclass, vbase->base, &method->u.pair.a);
- method->u.pair.b = index2;
- break;
- }
- }
-
- if (order2)
- break;
- }
- gen->counts.numMigratedMethods++;
- break;
-
- case SOMMS_Method:
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (
- IS_TYPE_FUNC(object->type) &&
- CSOM_NameTranslate(object->name) == order->name
- )
- {
- CError_ASSERT(733, TYPE_METHOD(object->type)->vtbl_index == index);
- method->u.object = object;
- break;
- }
- }
-
- CError_ASSERT(737, object != NULL);
- break;
- }
-
- gen->counts.classTokenCount++;
- }
- } else {
- Object **array;
- int arrayCount;
- SInt32 i;
-
- array = CSOM_GetLexicalOrderMethodArray(tclass, &arrayCount);
- for (i = 0; i < arrayCount; i++) {
- object = array[i];
- if (object) {
- method = lalloc(sizeof(SOMMethod));
- memclrw(method, sizeof(SOMMethod));
- *ptr = method;
- ptr = &method->next;
-
- method->u.object = object;
- method->name = object->name;
- method->state = SOMMS_Method;
- gen->counts.classTokenCount++;
- }
- }
- }
-}
-
-static void CSOM_GenerateClassAncestors(SOMGenerator *gen, TypeClass *tclass) {
- SOMAncestor *ancestor;
- Object *object;
- OLinkList *relocs;
- SInt32 size;
- char *buf;
-
- if (gen->ancestors) {
- object = CSOM_MakeObject(tclass->classname->name, "ClassAncestors", 4);
- object->sclass = TK_STATIC;
-
- relocs = NULL;
- size = 0;
- for (ancestor = gen->ancestors; ancestor; ancestor = ancestor->next) {
- OLinkList *reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = ancestor->tclass->sominfo->classdataobject;
- reloc->offset = size;
- reloc->somevalue = 0;
- size += 4;
- }
-
- buf = lalloc(size);
- memclrw(buf, size);
- object->type->size = size;
- CInit_DeclareData(object, buf, relocs, object->type->size);
- gen->classAncestorsObj = object;
- }
-}
-
-static void CSOM_GenerateOverrideProcs(SOMGenerator *gen, TypeClass *tclass) {
- SOMOverride *override;
- SOMAncestor *ancestor;
- Object *object;
- OLinkList *relocs;
- SInt32 size;
- SInt32 offset;
- char *buf;
-
- if (gen->overrideProcsCount) {
- size = gen->overrideProcsCount * 4;
- object = CSOM_MakeObject(tclass->classname->name, "OverrideProcs", size);
- object->sclass = TK_STATIC;
-
- relocs = NULL;
- offset = 0;
- for (ancestor = gen->ancestors; ancestor; ancestor = ancestor->next) {
- if (ancestor->overrides) {
- for (override = ancestor->overrides; override; override = override->next) {
- OLinkList *reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = override->a;
- reloc->offset = offset;
- reloc->somevalue = 0;
- offset += 4;
- }
- }
- }
-
- buf = lalloc(size);
- memclrw(buf, size);
- CInit_DeclareData(object, buf, relocs, object->type->size);
- gen->overrideProcsObj = object;
- }
-}
-
-static Object *CSOM_GenerateOverrideData(SOMGenerator *gen) {
- SOMAncestor *ancestor;
- Object *object;
- short ancestorIndex;
-
- name_mangle_list.size = 0;
- for (ancestor = gen->ancestors, ancestorIndex = 0; ancestor; ancestor = ancestor->next, ancestorIndex++) {
- if (ancestor->overrides) {
- SOMOverride *override;
- short overrideCount;
-
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(ancestorIndex));
-
- override = ancestor->overrides;
- overrideCount = 0;
- while (override) {
- overrideCount++;
- override = override->next;
- }
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(overrideCount));
-
- for (override = ancestor->overrides; override; override = override->next) {
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(CSOM_GetTokenTableIndex(override->b)));
- }
- }
- }
-
- COS_LockHandle(name_mangle_list.data);
- object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0);
- COS_UnlockHandle(name_mangle_list.data);
- return object;
-}
-
-static Object *CSOM_GenerateMigrateData(SOMGenerator *gen) {
- SOMMethod *method;
- Object *object;
- int index;
-
- name_mangle_list.size = 0;
- for (method = gen->methods, index = 0; method; method = method->next, index++) {
- if (method->state == SOMMS_Migrated) {
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(method->u.pair.a));
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(method->u.pair.b));
- AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(index));
- }
- }
-
- COS_LockHandle(name_mangle_list.data);
- object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0);
- COS_UnlockHandle(name_mangle_list.data);
- return object;
-}
-
-static void CSOM_GenerateDLLDFunc(SOMGenerator *gen, TypeClass *tclass) {
- TypeFunc *tfunc;
- Object *object;
-
- tfunc = galloc(sizeof(TypeFunc));
- memclrw(tfunc, sizeof(TypeFunc));
- tfunc->type = TYPEFUNC;
- tfunc->functype = &stvoid;
-
- object = CParser_NewCompilerDefFunctionObject();
- object->type = TYPE(tfunc);
- object->sclass = TK_STATIC;
- object->name = CParser_NameConcat(tclass->classname->name, "DLLD");
-
- if (CScope_GetLocalObject(cscope_root, object->name))
- CError_Error(CErrorStr333, object);
-
- gen->dlldFunc = object;
- CFunc_GenerateDummyFunction(object);
-}
-
-static void CSOM_GenerateSpecialProcs(SOMGenerator *gen, TypeClass *tclass) {
- Object *newFunc;
- Object *deleteFunc;
- Object *object;
- OLinkList *relocs;
- SInt32 size;
- CScopeObjectIterator iter;
- char buf[16];
-
- newFunc = deleteFunc = NULL;
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (IS_TYPE_FUNC(object->type)) {
- if (object->name == CMangler_OperatorName(TK_NEW)) {
- newFunc = object;
- gen->hasNew = 1;
- } else if (object->name == CMangler_OperatorName(TK_DELETE)) {
- deleteFunc = object;
- gen->hasDelete = 1;
- }
- }
- }
-
- if (newFunc || deleteFunc) {
- object = CSOM_MakeObject(tclass->classname->name, "SpecialProcs", 4);
- object->sclass = TK_STATIC;
-
- relocs = NULL;
- size = 0;
-
- if (newFunc) {
- OLinkList *reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = newFunc;
- reloc->offset = size;
- reloc->somevalue = 0;
- size += 4;
- }
-
- if (deleteFunc) {
- OLinkList *reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = deleteFunc;
- reloc->offset = size;
- reloc->somevalue = 0;
- size += 4;
- }
-
- memclrw(buf, sizeof(buf));
- object->type->size = size;
- CInit_DeclareData(object, buf, relocs, object->type->size);
- gen->specialProcsObj = object;
- }
-}
-
-static Object *CSOM_GenerateParentVersion(SOMGenerator *gen) {
- SInt32 size;
- UInt32 *buf;
- SOMAncestor *ancestor;
- SInt32 offset;
-
- size = 8 * (gen->counts.numDirectParents + gen->counts.numMetaClasses);
- buf = lalloc(size);
-
- for (ancestor = gen->ancestors, offset = 0; ancestor; ancestor = ancestor->next) {
- if (ancestor->xC || ancestor->xD) {
- buf[offset++] = CTool_EndianConvertWord32(ancestor->tclass->sominfo->majorversion);
- buf[offset++] = CTool_EndianConvertWord32(ancestor->tclass->sominfo->minorversion);
- }
- }
-
- return CInit_DeclareString((char *) buf, size, 0, 0);
-}
-
-static void CSOM_SetNibble(char *buf, int offset, UInt8 value) {
- int i = offset >> 1;
- if (offset & 1) {
- int left = buf[i] & 0xF0;
- int right = value & 0xF;
- buf[i] = left | right;
- } else {
- int left = value << 4;
- int right = buf[i] & 0xF;
- buf[i] = left | right;
- }
-}
-
-static Object *CSOM_GenerateSlotUsage(SOMGenerator *gen) {
- SInt32 size;
- SOMMethod *method;
- char *buf;
- int offset;
-
- size = (gen->counts.classTokenCount + 1) / 2;
- buf = lalloc(size);
- memclrw(buf, size);
-
- for (method = gen->methods, offset = 0; method; method = method->next, offset++) {
- switch (method->state) {
- case SOMMS_Deleted:
- case SOMMS_Migrated:
- CSOM_SetNibble(buf, offset, mtEmpty);
- break;
- case SOMMS_Method:
- CSOM_SetNibble(buf, offset, mtVirtualMethod);
- break;
- default:
- CError_FATAL(1048);
- }
- }
-
- return CInit_DeclareString(buf, size, 0, 0);
-}
-
-static Object *CSOM_GenerateSignature(SOMGenerator *gen) {
- Object *object;
- SOMMethod *method;
-
- name_mangle_list.size = 0;
-
- for (method = gen->methods; method; method = method->next) {
- if (method->state == SOMMS_Method)
- CSOM_GetFuncSig(TYPE_FUNC(method->u.object->type), 1);
- }
-
- COS_LockHandle(name_mangle_list.data);
- object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0);
- COS_UnlockHandle(name_mangle_list.data);
- return object;
-}
-
-static Object *CSOM_GenerateMethodNames(SOMGenerator *gen) {
- Object *object;
- SOMMethod *method;
- HashNameNode *name;
-
- name_mangle_list.size = 0;
-
- for (method = gen->methods; method; method = method->next) {
- if (method->name) {
- name = CSOM_NameTranslate(method->name);
- AppendGListID(&name_mangle_list, name->name);
- }
- }
-
- COS_LockHandle(name_mangle_list.data);
- object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0);
- COS_UnlockHandle(name_mangle_list.data);
- return object;
-}
-
-static void CSOM_SetupClassCounts(SOMGenerator *gen, TypeClass *tclass, somStaticClassCounts *counts) {
- gen->counts.majorVersion = tclass->sominfo->majorversion;
- gen->counts.minorVersion = tclass->sominfo->minorversion;
- gen->counts.flags = cfSharedStrings;
- if (gen->hasNew)
- gen->counts.flags |= cfClassAllocate;
- if (gen->hasDelete)
- gen->counts.flags |= cfClassDeallocate;
-
- switch (tclass->align) {
- case 1:
- gen->counts.dataAlignment = 0;
- break;
- case 2:
- gen->counts.dataAlignment = 1;
- break;
- case 4:
- gen->counts.dataAlignment = 2;
- break;
- case 8:
- gen->counts.dataAlignment = 3;
- break;
- default:
- gen->counts.dataAlignment = 4;
- break;
- }
-
- gen->counts.numSelectInherited = 0;
-
- memclrw(counts, sizeof(somStaticClassCounts));
- counts->majorVersion = CTool_EndianConvertWord32(gen->counts.majorVersion);
- counts->minorVersion = CTool_EndianConvertWord32(gen->counts.minorVersion);
- counts->flags = CTool_EndianConvertWord32(gen->counts.flags);
- counts->dataAlignment = CTool_EndianConvertWord16(gen->counts.dataAlignment);
- counts->classTokenCount = CTool_EndianConvertWord16(gen->counts.classTokenCount);
- counts->numDirectParents = CTool_EndianConvertWord16(gen->counts.numDirectParents);
- counts->numMetaClasses = CTool_EndianConvertWord16(gen->counts.numMetaClasses);
- counts->numOverriddenAncestors = CTool_EndianConvertWord16(gen->counts.numOverriddenAncestors);
- counts->numMigratedMethods = CTool_EndianConvertWord16(gen->counts.numMigratedMethods);
- counts->numSelectInherited = CTool_EndianConvertWord16(gen->counts.numSelectInherited);
-}
-
-static void CSOM_GenerateSCIObject(SOMGenerator *gen, TypeClass *tclass) {
- Object *object;
- OLinkList *relocs;
- OLinkList *reloc;
- somStaticClassInfo sci;
- somStaticClassCounts classCounts;
-
- object = CSOM_MakeObject(tclass->classname->name, "SCI", sizeof(sci));
- object->sclass = TK_STATIC;
-
- memclrw(&sci, sizeof(sci));
- sci.layoutVersion = CTool_EndianConvertWord32(70);
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = NULL;
- relocs = reloc;
- reloc->obj = tclass->sominfo->classdataobject;
- reloc->offset = 4;
- reloc->somevalue = 0;
-
- if (gen->overrideProcsObj) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = gen->overrideProcsObj;
- reloc->offset = 8;
- reloc->somevalue = 0;
- }
-
- if (gen->classAncestorsObj) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = gen->classAncestorsObj;
- reloc->offset = 12;
- reloc->somevalue = 0;
- }
-
- if (gen->dlldFunc) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = gen->dlldFunc;
- reloc->offset = 16;
- reloc->somevalue = 0;
- }
-
- if (gen->specialProcsObj) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = gen->specialProcsObj;
- reloc->offset = 20;
- reloc->somevalue = 0;
- }
-
- CSOM_SetupClassCounts(gen, tclass, &classCounts);
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CInit_DeclareString((char *) &classCounts, sizeof(classCounts), 0, 0);
- reloc->offset = 52;
- reloc->somevalue = 0;
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CInit_DeclareString(tclass->classname->name, strlen(tclass->classname->name) + 1, 0, 0);
- reloc->offset = 56;
- reloc->somevalue = 0;
-
- sci.classDescription.instanceDataSize = CTool_EndianConvertWord32(tclass->size);
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateParentVersion(gen);
- reloc->offset = 64;
- reloc->somevalue = 0;
-
- if (gen->methods) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateSlotUsage(gen);
- reloc->offset = 68;
- reloc->somevalue = 0;
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateSignature(gen);
- reloc->offset = 72;
- reloc->somevalue = 0;
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateMethodNames(gen);
- reloc->offset = 76;
- reloc->somevalue = 0;
- }
-
- if (gen->overrideProcsObj) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateOverrideData(gen);
- reloc->offset = 80;
- reloc->somevalue = 0;
- }
-
- if (gen->counts.numMigratedMethods) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = CSOM_GenerateMigrateData(gen);
- reloc->offset = 84;
- reloc->somevalue = 0;
- }
-
- sci.classDescription.selectedInherited = 0;
-
- CInit_DeclareData(object, &sci, relocs, object->type->size);
- gen->sciObj = object;
-}
-
-static void CSOM_GenerateClassDataObject(SOMGenerator *gen, TypeClass *tclass) {
- void *buf;
- OLinkList *relocs;
- OLinkList *reloc;
- SInt32 size;
- SOMMethod *method;
-
- relocs = NULL;
- for (size = 24, method = gen->methods; method; method = method->next) {
- if (method->state == SOMMS_Method) {
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = method->u.object;
- reloc->offset = size;
- reloc->somevalue = 0;
- }
- size += 4;
- }
-
- buf = lalloc(size);
- memclrw(buf, size);
-
- reloc = lalloc(sizeof(OLinkList));
- reloc->next = relocs;
- relocs = reloc;
- reloc->obj = gen->sciObj;
- reloc->offset = 4;
- reloc->somevalue = 0;
-
- tclass->sominfo->classdataobject->type->size = size;
- CInit_DeclareData(tclass->sominfo->classdataobject, buf, relocs, tclass->sominfo->classdataobject->type->size);
-}
-
-void CSOM_GenerateClassStructures(TypeClass *tclass) {
- SOMGenerator gen;
-
- memclrw(&gen, sizeof(gen));
- CSOM_GenerateOverrideIntroLists(&gen, tclass);
- CSOM_GenerateClassAncestors(&gen, tclass);
- CSOM_GenerateOverrideProcs(&gen, tclass);
- CSOM_GenerateDLLDFunc(&gen, tclass);
- CSOM_GenerateSpecialProcs(&gen, tclass);
- CSOM_GenerateSCIObject(&gen, tclass);
- CSOM_GenerateClassDataObject(&gen, tclass);
-}
-
-static TypeClass *CSOM_GetCurrentSOMClass(void) {
- if (cscope_current->theclass && cscope_current->theclass->sominfo)
- return cscope_current->theclass;
-
- CError_Error(CErrorStr277);
- return NULL;
-}
-
-void CSOM_PragmaReleaseOrder(void) {
- TypeClass *tclass;
- SOMReleaseOrder *firstOrder;
- SOMReleaseOrder *order;
- SOMReleaseOrder **ptr;
- Boolean flag;
- short token;
-
- if (!(tclass = CSOM_GetCurrentSOMClass()))
- return;
-
- token = CPrep_PragmaLex(0);
- if (token != '(') {
- if (token != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr114);
- return;
- }
-
- if (!strcmp(tkidentifier->name, "list")) {
- token = CPrep_PragmaLex(0);
- if (token != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
- }
-
- flag = 1;
- } else {
- flag = 0;
- token = CPrep_PragmaLex(0);
- }
-
- firstOrder = NULL;
- if (flag || token != ')') {
- ptr = &firstOrder;
- while (1) {
- if (token != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
-
- for (order = firstOrder; order; order = order->next) {
- if (order->name == tkidentifier) {
- CError_Error(CErrorStr122, tkidentifier->name);
- return;
- }
- }
-
- order = galloc(sizeof(SOMReleaseOrder));
- *ptr = order;
- ptr = &order->next;
-
- order->next = NULL;
- order->name = tkidentifier;
- order->state = SOMMS_Deleted;
-
- if (flag) {
- token = CPrep_PragmaLex(1);
- if (!token)
- break;
- } else {
- token = CPrep_PragmaLex(0);
- if (token == ')')
- break;
- }
-
- if (token != ',') {
- CPrep_Error(CErrorStr116);
- return;
- }
-
- token = CPrep_PragmaLex(flag);
- }
- }
-
- tclass->sominfo->order = firstOrder;
-}
-
-void CSOM_PragmaClassVersion(void) {
- Type *type;
-
- if (CPrep_PragmaLex(0) != '(') {
- CPrep_Error(CErrorStr114);
- return;
- }
-
- if (CPrep_PragmaLex(0) != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
-
- type = CScope_GetTagType(cscope_current, tkidentifier);
- if (!(type && IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)) {
- CPrep_ErrorName(CErrorStr276, tkidentifier->name);
- return;
- }
-
- if (CPrep_PragmaLex(0) != ',') {
- CPrep_Error(CErrorStr116);
- return;
- }
-
- if (CPrep_PragmaLex(0) != TK_INTCONST) {
- CPrep_Error(CErrorStr186);
- return;
- }
-
- TYPE_CLASS(type)->sominfo->majorversion = CInt64_GetULong(&tkintconst);
-
- if (CPrep_PragmaLex(0) != ',') {
- CPrep_Error(CErrorStr116);
- return;
- }
-
- if (CPrep_PragmaLex(0) != TK_INTCONST) {
- CPrep_Error(CErrorStr186);
- return;
- }
-
- TYPE_CLASS(type)->sominfo->minorversion = CInt64_GetULong(&tkintconst);
-
- if (CPrep_PragmaLex(0) != ')') {
- CPrep_Error(CErrorStr115);
- return;
- }
-}
-
-void CSOM_PragmaMetaClass(void) {
- Type *type;
- Type *type2;
-
- if (CPrep_PragmaLex(0) != '(') {
- CPrep_Error(CErrorStr114);
- return;
- }
-
- if (CPrep_PragmaLex(0) != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
-
- type = CScope_GetTagType(cscope_current, tkidentifier);
- if (!(type && IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)) {
- CPrep_ErrorName(CErrorStr276, tkidentifier->name);
- return;
- }
-
- if (CPrep_PragmaLex(0) != ',') {
- CPrep_Error(CErrorStr116);
- return;
- }
-
- if (CPrep_PragmaLex(0) != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
-
- type2 = CScope_GetTagType(cscope_current, tkidentifier);
- if (!(type2 && IS_TYPE_CLASS(type2) && TYPE_CLASS(type2)->sominfo)) {
- CPrep_ErrorName(CErrorStr276, tkidentifier->name);
- return;
- }
-
- TYPE_CLASS(type)->sominfo->metaclass = TYPE_CLASS(type2);
-
- if (CPrep_PragmaLex(0) != ')') {
- CPrep_Error(CErrorStr115);
- return;
- }
-}
-
-void CSOM_PragmaCallStyle(void) {
- TypeClass *tclass;
-
- if (!(tclass = CSOM_GetCurrentSOMClass()))
- return;
-
- if (CPrep_PragmaLex(0) != TK_IDENTIFIER) {
- CPrep_Error(CErrorStr107);
- return;
- }
-
- if (!strcmp(tkidentifier->name, "IDL")) {
- tclass->sominfo->oidl_callstyle = 0;
- return;
- }
-
- if (!strcmp(tkidentifier->name, "OIDL")) {
- tclass->sominfo->oidl_callstyle = 1;
- return;
- }
-
- CPrep_Error(CErrorStr186);
-}
-
-void CSOM_FixNewDeleteFunctype(TypeFunc *tfunc) {
- FuncArg *arg = CParser_NewFuncArg();
- arg->name = GetHashNameNodeExport("__theclass");
- arg->type = CDecl_NewPointerType(CSOM_FindClassType(GetHashNameNodeExport("SOMClass")));
- arg->next = tfunc->args;
- tfunc->args = arg;
-}
-
-static Object *CSOM_FindRTFunc(char *namestr, char *sig) {
- NameSpaceObjectList *nsol;
- Object *object;
- FuncArg *arg;
-
- if (
- (nsol = CScope_GetLocalObject(cscope_root, GetHashNameNodeExport(namestr))) &&
- nsol->object->otype == OT_OBJECT
- )
- {
- object = OBJECT(nsol->object);
- if (
- IS_TYPE_FUNC(object->type) &&
- *(sig++) == 'p' &&
- IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->functype)
- )
- {
- for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) {
- switch (*(sig++)) {
- case 'p':
- if (IS_TYPE_POINTER_ONLY(arg->type))
- continue;
- break;
- case 'i':
- if (arg->type == TYPE(&stsignedint))
- continue;
- break;
- case 'I':
- if (arg->type == TYPE(&stunsignedint))
- continue;
- break;
- case 'l':
- if (arg->type == TYPE(&stsignedlong))
- continue;
- break;
- case 'L':
- if (arg->type == TYPE(&stunsignedlong))
- continue;
- break;
- }
- break;
- }
-
- if (arg == NULL && *sig == 0)
- return object;
- }
-
- CError_Error(CErrorStr275, namestr);
- } else {
- CError_Error(CErrorStr274, namestr);
- }
-
- return NULL;
-}
-
-static ENode *CSOM_MakeTempCondition(ENode *left, ENode *cond, ENode *expr1, ENode *right) {
- ENode *expr;
-
- expr = lalloc(sizeof(ENode));
- expr->type = ECOND;
- expr->cost = 0;
- expr->flags = 0;
- expr->rtype = &stvoid;
- expr->data.cond.cond = cond;
- expr->data.cond.expr1 = expr1;
- expr->data.cond.expr2 = nullnode();
- expr->data.cond.expr2->rtype = &stvoid;
-
- if (left)
- expr = makediadicnode(left, expr, ECOMMA);
-
- if (right) {
- expr = makediadicnode(expr, right, ECOMMA);
- expr->rtype = right->rtype;
- }
-
- return expr;
-}
-
-ENode *CSOM_New(TypeClass *tclass) {
- Object *newFunc;
- ENode *expr;
-
- if (tk == '(') {
- if ((tk = lex()) == ')') {
- tk = lex();
- } else {
- CError_Error(CErrorStr272);
- }
- }
-
- if (!copts.som_env_check || !copts.som_call_optimize) {
- newFunc = CSOM_FindRTFunc("somNewObjectInstance", "ppll");
- if (!newFunc)
- return nullnode();
- } else {
- newFunc = rt_som_new;
- }
-
- expr = funccallexpr(
- newFunc,
- create_objectrefnode(tclass->sominfo->classdataobject),
- intconstnode(TYPE(&stunsignedlong), tclass->sominfo->majorversion),
- intconstnode(TYPE(&stunsignedlong), tclass->sominfo->minorversion),
- NULL
- );
- expr->rtype = CDecl_NewPointerType(TYPE(tclass));
-
- if (copts.som_env_check && !copts.som_call_optimize) {
- ENode *tempExpr;
- ENode *checkExpr;
- ENode *notExpr;
- tempExpr = CExpr_GetETEMPCopy(expr);
- checkExpr = funccallexpr(rt_som_newcheck, nullnode(), NULL, NULL, NULL);
- notExpr = makemonadicnode(tempExpr, ELOGNOT);
- notExpr->rtype = CParser_GetBoolType();
- expr = CSOM_MakeTempCondition(NULL, notExpr, checkExpr, tempExpr);
- }
-
- return expr;
-}
-
-ENode *CSOM_Delete(TypeClass *tclass, ENode *objExpr) {
- Object *func;
-
- if ((func = CSOM_FindRTFunc("somReleaseObjectReference", "pp")))
- return funccallexpr(func, objExpr, NULL, NULL, NULL);
-
- return nullnode();
-}
-
-void CSOM_InitAutoClass(Object *object) {
- Type *type;
- Statement *stmt;
- Object *func;
-
- if ((func = CSOM_FindRTFunc("somReleaseObjectReference", "pp"))) {
- type = object->type;
- object->type = CDecl_NewPointerType(type);
- TPTR_QUAL(object->type) = Q_REFERENCE;
-
- stmt = CFunc_AppendStatement(ST_EXPRESSION);
- stmt->expr = makediadicnode(create_objectnode2(object), CSOM_New(TYPE_CLASS(type)), EASS);
- CExcept_RegisterDeleteObject(stmt, object, func);
- }
-}
-
-static void CSOM_FindIntroClassOffset(TypeClass *tclass, Object *func, TypeClass **resultClass, SInt32 *resultOffset) {
- Object *scan;
- VClassList *vbase;
- CScopeObjectIterator iter;
-
- if (!(TYPE_FUNC(func->type)->flags & FUNC_FLAGS_20)) {
- CScope_InitObjectIterator(&iter, tclass->nspace);
- while (1) {
- if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (scan == func) {
- *resultClass = tclass;
- *resultOffset = CSOM_GetTokenOffset(scan);
- return;
- }
- }
-
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- CScope_InitObjectIterator(&iter, vbase->base->nspace);
- while (1) {
- if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (scan == func) {
- *resultClass = vbase->base;
- *resultOffset = CSOM_GetTokenOffset(scan);
- return;
- }
- }
- }
- } else {
- for (vbase = tclass->vbases; vbase; vbase = vbase->next) {
- CScope_InitObjectIterator(&iter, vbase->base->nspace);
- while (1) {
- if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- break;
-
- if (scan->name == func->name) {
- if (
- IS_TYPE_FUNC(scan->type) &&
- scan->datatype == DVFUNC &&
- !(TYPE_FUNC(scan->type)->flags & FUNC_FLAGS_20) &&
- CClass_GetOverrideKind(TYPE_FUNC(func->type), TYPE_FUNC(scan->type), 0)
- )
- {
- *resultClass = vbase->base;
- *resultOffset = CSOM_GetTokenOffset(scan);
- return;
- }
- break;
- }
- }
- }
- }
-
- CError_FATAL(1731);
-}
-
-static ENode *CSOM_ComputeSOMSelf(TypeClass *tclass, ENode *selfExpr) {
- ENode *expr;
- Object obj;
-
- expr = create_objectrefnode(tclass->sominfo->classdataobject);
- expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), 8), EADD);
- expr->rtype = CDecl_NewPointerType(TYPE(&SOMIDT_type));
- expr = makemonadicnode(expr, EINDIRECT);
-
- memclrw(&obj, sizeof(Object));
- obj.otype = OT_OBJECT;
- obj.type = TYPE(&SOMIDT_type);
- obj.name = no_name_node;
- obj.datatype = DFUNC;
- selfExpr = funccallexpr(&obj, selfExpr, NULL, NULL, NULL);
-
- CError_ASSERT(1761, ENODE_IS(selfExpr, EFUNCCALL));
-
- selfExpr->data.funccall.funcref = expr;
-
- return selfExpr;
-}
-
-ENode *CSOM_SOMSelfObjectExpr(TypeClass *tclass) {
- ObjectList *list;
- Object *obj;
-
- for (list = locals; list; list = list->next) {
- if (list->object->name == csom_selfname)
- return create_objectnode(list->object);
- }
-
- obj = CParser_NewLocalDataObject(NULL, 1);
- obj->name = csom_selfname;
- obj->type = CDecl_NewPointerType(TYPE(tclass));
- CFunc_SetupLocalVarInfo(obj);
- return create_objectnode(obj);
-}
-
-void CSOM_InitSOMSelf(TypeClass *tclass, Statement *stmt) {
- ObjectList *list;
- HashNameNode *name;
- ENode *selfExpr;
-
- name = GetHashNameNodeExport("__somself");
- for (list = locals; list; list = list->next) {
- if (list->object->name == name) {
- selfExpr = CClass_CreateThisSelfExpr();
- CError_ASSERT(1811, selfExpr);
-
- selfExpr = CSOM_ComputeSOMSelf(tclass, selfExpr);
-
- stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt);
- stmt->expr = makediadicnode(create_objectnode(list->object), selfExpr, EASS);
- break;
- }
- }
-}
-
-ENode *CSOM_EnvCheck(ENode *funccall, ENodeList *checkArg) {
- ENodeList *arg; // r26
- ENodeList *arg2; // r28
- ENode *expr26; // r26
- ENode *expr27; // r27
- ENode *expr28; // r28
- Type *returnType; // r31
-
- returnType = funccall->rtype;
- CError_ASSERT(1842, arg = funccall->data.funccall.args);
-
- if (arg == checkArg)
- CError_ASSERT(1845, arg = arg->next);
-
- CError_ASSERT(1847, arg2 = arg->next);
-
- if (arg2 == checkArg)
- CError_ASSERT(1850, arg2 = arg2->next);
-
- CError_ASSERT(1852, IS_TYPE_POINTER_ONLY(arg2->node->rtype));
-
- if (!IS_TYPE_VOID(funccall->data.funccall.functype->functype)) {
- if (checkArg) {
- if (ENODE_IS(checkArg->node, ETEMP)) {
- if (checkArg->node->data.temp.uniqueid == 0)
- checkArg->node->data.temp.uniqueid = CParser_GetUniqueID();
-
- expr26 = lalloc(sizeof(ENode));
- *expr26 = *checkArg->node;
- expr26->data.temp.needs_dtor = 0;
- } else {
- expr26 = CExpr_GetETEMPCopy(checkArg->node);
- }
- } else {
- expr26 = CExpr_GetETEMPCopy(funccall);
- }
- } else {
- expr26 = NULL;
- }
-
- if (!ENODE_IS(arg2->node, EOBJREF)) {
- if (ENODE_IS_INDIRECT_TO(arg2->node, EOBJREF) && arg2->node->data.monadic->data.objref->datatype == DLOCAL) {
- expr27 = lalloc(sizeof(ENode));
- *expr27 = *arg2->node;
- } else {
- expr27 = CExpr_GetETEMPCopy(arg2->node);
- }
- } else {
- expr27 = lalloc(sizeof(ENode));
- *expr27 = *arg2->node;
- }
-
- if (copts.som_call_optimize) {
- funccall = makediadicnode(funccall, funccallexpr(rt_som_check, expr27, NULL, NULL, NULL), ECOMMA);
- if (expr26)
- funccall = makediadicnode(funccall, expr26, ECOMMA);
- } else {
- expr28 = lalloc(sizeof(ENode));
- *expr28 = *expr27;
- expr28 = makemonadicnode(expr28, EINDIRECT);
- expr28->rtype = TYPE(&stsignedlong);
-
- funccall = CSOM_MakeTempCondition(
- funccall,
- expr28,
- funccallexpr(rt_som_check, expr27, NULL, NULL, NULL),
- expr26);
- }
-
- funccall->rtype = returnType;
- return funccall;
-}
-
-static Boolean CSOM_CanUseGlueCall(TypeFunc *tfunc) {
- int gprCounter;
- int fprCounter;
- FuncArg *arg;
-
- gprCounter = 8;
- fprCounter = 13;
- if (CMach_GetFunctionResultClass(tfunc) != 0)
- gprCounter = 7;
-
- for (arg = tfunc->args; arg; arg = arg->next) {
- if (arg == &elipsis || arg == &oldstyle)
- return 0;
-
- switch (arg->type->type) {
- case TYPEINT:
- case TYPEENUM:
- case TYPEPOINTER:
- if (--gprCounter < 0)
- return 0;
- break;
- case TYPEFLOAT:
- if (--fprCounter < 0)
- return 0;
- break;
- default:
- return 0;
- }
- }
-
- return 1;
-}
-
-static char *CSOM_AppendString(char *dst, char *src) {
- int ch;
- while ((ch = *(src++)))
- *(dst++) = ch;
- return dst;
-}
-
-static ENode *CSOM_SOMGlueCall(TypeClass *tclass, SInt32 offset, Object *object) {
- UInt8 funcResultClass;
- UInt32 bufsize;
- char *buf;
- char *ptr;
- Object *stubObj;
- CSOMStub *stub;
- ENode *expr;
- char mybuf[256];
- char numberbuf[16];
-
- for (stub = csom_stubs; stub; stub = stub->next) {
- if (stub->tclass == tclass && stub->offset == offset)
- break;
- }
-
- if (!stub) {
- funcResultClass = CMach_GetFunctionResultClass(TYPE_FUNC(object->type));
-
- bufsize = strlen(tclass->sominfo->classdataobject->name->name) + 32;
- buf = (bufsize > sizeof(mybuf)) ? lalloc(bufsize) : mybuf;
-
- ptr = CSOM_AppendString(buf, "___glue_");
- if (tclass->sominfo->oidl_callstyle == 0) {
- if (funcResultClass == 0) {
- *(ptr++) = '4';
- } else {
- *(ptr++) = '5';
- }
- } else {
- *(ptr++) = '_';
- }
- *(ptr++) = '_';
-
- sprintf(numberbuf, "%ld", strlen(tclass->sominfo->classdataobject->name->name));
- ptr = CSOM_AppendString(ptr, numberbuf);
- ptr = CSOM_AppendString(ptr, tclass->sominfo->classdataobject->name->name);
- *(ptr++) = '_';
- sprintf(numberbuf, "%" PRId32, offset);
- ptr = CSOM_AppendString(ptr, numberbuf);
- *ptr = 0;
-
- stubObj = CParser_NewCompilerDefFunctionObject();
- stubObj->nspace = cscope_root;
- stubObj->name = GetHashNameNodeExport(buf);
- stubObj->u.func.linkname = stubObj->name;
- stubObj->type = object->type;
- stubObj->qual = object->qual | Q_20000;
- stubObj->flags = OBJECT_INTERNAL;
- CScope_AddObject(stubObj->nspace, stubObj->name, OBJ_BASE(stubObj));
-
- stub = galloc(sizeof(CSOMStub));
- stub->next = csom_stubs;
- stub->object = stubObj;
- stub->tclass = tclass;
- stub->offset = offset;
- csom_stubs = stub;
-
- if (tclass->sominfo->oidl_callstyle == 0) {
- if (funcResultClass == 0)
- stub->x10 = 0;
- else
- stub->x10 = 1;
- } else {
- stub->x10 = 2;
- }
- }
-
- expr = create_objectrefnode(stub->object);
- expr->rtype = CDecl_NewPointerType(object->type);
- return expr;
-}
-
-ENode *CSOM_MemberVarAccess(BClassList *path, ObjMemberVar *ivar, ENode *thisExpr) {
- if (!thisExpr) {
- if (
- !cscope_currentfunc ||
- !cscope_currentclass ||
- !cscope_is_member_func ||
- !(thisExpr = CClass_CreateThisSelfExpr())
- )
- {
- CError_Error(CErrorStr221);
- return NULL;
- }
- }
-
- CError_ASSERT(2069, ENODE_IS(thisExpr, EINDIRECT));
-
- thisExpr = thisExpr->data.monadic;
-
- if (
- path->next == NULL &&
- cscope_currentclass == TYPE_CLASS(path->type) &&
- ENODE_IS(thisExpr, EOBJREF) &&
- thisExpr->data.objref->name == this_name_node
- )
- {
- thisExpr = CSOM_SOMSelfObjectExpr(cscope_currentclass);
- }
- else
- {
- CClass_CheckPathAccess(path, NULL, ivar->access);
- if (ivar->has_path)
- path = OBJ_MEMBER_VAR_PATH(ivar)->path;
- while (path->next)
- path = path->next;
- thisExpr = CSOM_ComputeSOMSelf(TYPE_CLASS(path->type), thisExpr);
- }
-
- thisExpr = makemonadicnode(thisExpr, EINDIRECT);
- thisExpr->rtype = path->type;
- return CClass_AccessMember(thisExpr, ivar->type, ivar->qual, ivar->offset);
-}
-
-ENode *CSOM_MethodAccess(BClassList *path, Object *func, Boolean flag) {
- TypeClass *tclass;
- TypeClass *tclass2;
- TypeClass *tclass3;
- ENode *expr;
- SInt32 offset;
- ClassList *base;
-
- CError_ASSERT(2107, path != NULL);
-
- tclass = TYPE_CLASS(path->type);
- if (path->next)
- path = path->next;
- tclass2 = TYPE_CLASS(path->type);
-
- if (flag) {
- SInt32 counter;
- ENode *indirectExpr;
- Object *resolveFunc;
-
- counter = 0;
- if (tclass != tclass2) {
- for (base = tclass->bases; base; base = base->next) {
- counter++;
- if (base->base == tclass2)
- break;
- }
-
- if (!base)
- CError_Error(CErrorStr279);
- }
-
- CSOM_FindIntroClassOffset(tclass2, func, &tclass3, &offset);
- expr = create_objectrefnode(tclass3->sominfo->classdataobject);
- expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), offset), EADD);
- indirectExpr = makemonadicnode(expr, EINDIRECT);
- indirectExpr->rtype = CDecl_NewPointerType(func->type);
-
- resolveFunc = CSOM_FindRTFunc("somParentNumResolve", "ppip");
- if (!resolveFunc)
- return nullnode();
-
- expr = funccallexpr(
- resolveFunc,
- create_objectrefnode(tclass->sominfo->classdataobject),
- intconstnode(TYPE(&stsignedint), counter),
- indirectExpr,
- NULL);
- expr->rtype = indirectExpr->rtype;
- if (copts.som_env_check && tclass3->sominfo->oidl_callstyle == 0)
- expr->flags = expr->flags | ENODE_FLAG_10;
- } else {
- CSOM_FindIntroClassOffset(tclass2, func, &tclass3, &offset);
- if (copts.som_call_optimize && CSOM_CanUseGlueCall(TYPE_FUNC(func->type)))
- return CSOM_SOMGlueCall(tclass3, offset, func);
-
- expr = create_objectrefnode(tclass3->sominfo->classdataobject);
- expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), offset), EADD);
- expr = makemonadicnode(expr, EINDIRECT);
- expr->rtype = CDecl_NewPointerType(func->type);
- if (copts.som_env_check && tclass3->sominfo->oidl_callstyle == 0)
- expr->flags = expr->flags | ENODE_FLAG_10;
- }
-
- return expr;
-}
diff --git a/compiler_and_linker/unsorted/CTemplateClass.c b/compiler_and_linker/unsorted/CTemplateClass.c
deleted file mode 100644
index 8b3b889..0000000
--- a/compiler_and_linker/unsorted/CTemplateClass.c
+++ /dev/null
@@ -1,1632 +0,0 @@
-#include "compiler/CTemplateClass.h"
-#include "compiler/CABI.h"
-#include "compiler/CBrowse.h"
-#include "compiler/CClass.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CTemplateFunc.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-TemplClass *CTemplClass_GetMasterTemplate(TemplClass *tmclass) {
- if (tmclass->inst_parent) {
- tmclass = TEMPL_CLASS(tmclass->theclass.nspace->theclass);
- CError_ASSERT(42, tmclass->theclass.flags & CLASS_IS_TEMPL);
- }
-
- return tmclass;
-}
-
-static void CTemplClass_SetupActionErrorRef(TemplateAction *action, TStreamElement **saved) {
- CError_ResetErrorSkip();
- CError_LockErrorPos(&action->source_ref, saved);
-}
-
-static void CTemplClass_RestoreActionErrorRef(TStreamElement **saved) {
- CError_ResetErrorSkip();
- CError_UnlockErrorPos(saved);
-}
-
-static void CTemplClass_AppendTemplateAction(TemplClass *tmclass, TemplateAction *action) {
- TemplateAction *last;
-
- action->source_ref = *CPrep_CurStreamElement();
-
- if ((last = tmclass->actions)) {
- while (last->next)
- last = last->next;
- last->next = action;
- } else {
- tmclass->actions = action;
- }
-}
-
-static DefAction *CTemplClass_NewDefAction(TypeDeduce *deduce, TemplateAction *action) {
- DefAction *defAction = lalloc(sizeof(DefAction));
- defAction->next = deduce->defActions;
- defAction->action = action;
- deduce->defActions = defAction;
- return defAction;
-}
-
-static void CTemplClass_InsertTemplateAction(TemplClass *tmclass, TemplateAction *action) {
- action->source_ref = *CPrep_CurStreamElement();
- action->next = tmclass->actions;
- tmclass->actions = action;
-}
-
-void CTemplClass_RegisterUsingDecl(TemplClass *tmclass, TypeTemplDep *type, AccessType access) {
- TemplateAction *action;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_USINGDECL;
- action->u.usingdecl.type = type;
- action->u.usingdecl.access = access;
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterFriend(TemplClass *tmclass, DeclInfo *di) {
- TemplateFriend *tfriend;
- TemplateAction *action;
-
- tfriend = galloc(sizeof(TemplateFriend));
- memclrw(tfriend, sizeof(TemplateFriend));
-
- if (tk == '{' && IS_TYPE_FUNC(di->thetype)) {
- di->qual |= Q_INLINE;
- TYPE_FUNC(di->thetype)->flags |= FUNC_DEFINED | FUNC_IS_TEMPL_INSTANCE;
- tfriend->fileoffset = cparser_fileoffset;
-
- CPrep_StreamGetBlock(&tfriend->stream, NULL, 1);
-
- if (lookahead() == ';')
- tk = lex();
- else
- tk = ';';
- }
-
- CDecl_PackDeclInfo(&tfriend->decl, di);
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_FRIEND;
- action->u.tfriend = tfriend;
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterBaseClass(TemplClass *tmclass, Type *type, AccessType access, Boolean is_virtual) {
- TemplateAction *action;
- ClassList *insert_after;
-
- if ((insert_after = tmclass->theclass.bases)) {
- while (insert_after->next)
- insert_after = insert_after->next;
- }
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_BASE;
- action->u.base.type = type;
- action->u.base.insert_after = insert_after;
- action->u.base.access = access;
- action->u.base.is_virtual = is_virtual;
-
- CTemplClass_InsertTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *enumtype) {
- TemplateAction *action;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_ENUMTYPE;
- action->u.enumtype = enumtype;
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *objenumconst, ENode *initexpr) {
- TemplateAction *action;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_ENUMERATOR;
- action->u.enumerator.objenumconst = objenumconst;
- action->u.enumerator.initexpr = initexpr ? CInline_CopyExpression(initexpr, CopyMode1) : NULL;
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterObjectInit(TemplClass *tmclass, Object *object, ENode *initexpr) {
- TemplateAction *action;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_OBJECTINIT;
- action->u.objectinit.object = object;
- action->u.objectinit.initexpr = CInline_CopyExpression(initexpr, CopyMode1);
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *refobj) {
- TemplateAction *action;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_OBJECTDEF;
- action->u.refobj = refobj;
-
- CTemplClass_AppendTemplateAction(tmclass, action);
-}
-
-void CTemplClass_CompleteClass(TemplClass *templ, ClassLayout *de) {
- templ->lex_order_count = de->lex_order_count;
- if (de->has_vtable)
- templ->flags |= TEMPLCLASS_HAS_VTABLE;
- templ->theclass.flags |= CLASS_COMPLETED;
-}
-
-static TemplClassInst *CTemplClass_NewInstance(TemplClass *templ, TemplArg *inst_args, TemplArg *oargs) {
- TemplClassInst *inst;
- ObjTypeTag *tag;
- NameSpace *nspace;
- HashNameNode *name;
-
- CError_ASSERT(288, !templ->pspec_owner);
-
- inst = galloc(sizeof(TemplClassInst));
- memclrw(inst, sizeof(TemplClassInst));
-
- inst->next = templ->instances;
- templ->instances = inst;
-
- if (templ->templ__params)
- name = CMangler_TemplateInstanceName(templ->theclass.classname, oargs ? oargs : inst_args);
- else
- name = templ->theclass.classname;
-
- inst->inst_args = inst_args;
- inst->oargs = oargs;
- inst->parent = templ->inst_parent;
-
- nspace = CScope_NewListNameSpace(name, 1);
- nspace->theclass = TYPE_CLASS(inst);
- if (templ->templ_parent && templ->inst_parent) {
- nspace->parent = TYPE_CLASS(templ->inst_parent)->nspace;
- } else {
- NameSpace *scan = templ->theclass.nspace->parent;
- while (scan->is_templ)
- scan = scan->parent;
- nspace->parent = scan;
- }
-
- inst->theclass.type = TYPECLASS;
- inst->theclass.flags = CLASS_IS_TEMPL_INST;
- inst->theclass.nspace = nspace;
- inst->theclass.classname = templ->theclass.classname;
- inst->theclass.mode = templ->theclass.mode;
- inst->theclass.eflags = templ->theclass.eflags;
- inst->templ = templ;
-
- tag = galloc(sizeof(ObjTypeTag));
- memclrw(tag, sizeof(ObjTypeTag));
-
- tag->otype = OT_TYPETAG;
- tag->access = ACCESSPUBLIC;
- tag->type = TYPE(inst);
- CScope_AddObject(nspace, templ->theclass.classname, OBJ_BASE(tag));
-
- return inst;
-}
-
-TemplClassInst *CTemplClass_GetInstance(TemplClass *tmclass, TemplArg *inst_args, TemplArg *oargs) {
- TemplClassInst *inst;
-
- for (inst = tmclass->instances; inst; inst = inst->next) {
- CError_ASSERT(353, !oargs);
-
- if (CTemplTool_EqualArgs(inst_args, inst->oargs ? inst->oargs : inst->inst_args))
- return inst;
- }
-
- return CTemplClass_NewInstance(tmclass, inst_args, oargs);
-}
-
-TemplateMember *CTemplClass_DefineMember(TemplClass *tmclass, Object *object, FileOffsetInfo *foi, TokenStream *stream) {
- TemplateMember *member;
-
- for (member = tmclass->members; member; member = member->next) {
- if (member->object == object) {
- CError_Error(CErrorStr333, object);
- return member;
- }
- }
-
- member = galloc(sizeof(TemplateMember));
- memclrw(member, sizeof(TemplateMember));
- member->next = tmclass->members;
- tmclass->members = member;
-
- member->params = NULL;
- member->object = object;
- member->fileoffset = *foi;
- member->stream = *stream;
-
- return member;
-}
-
-static void CTemplClass_ParseBody(TemplClass *templ, short mode, SInt32 *offset) {
- DeclInfo di;
-
- templ->align = copts.structalignment;
-
- memclrw(&di, sizeof(di));
- di.file = CPrep_BrowserCurrentFile();
- CPrep_BrowserFilePosition(&di.file2, &di.sourceoffset);
- di.sourceoffset = *offset;
- di.x28 = templ;
-
- CDecl_ParseClass(&di, mode, 1, 0);
-
- if (tk == TK_UU_ATTRIBUTE_UU)
- CParser_ParseAttribute(di.thetype, NULL);
- if (tk != ';')
- CError_Error(CErrorStr123);
-
- CBrowse_NewTemplateClass(templ, di.file2, di.sourceoffset, CPrep_BrowserFileOffset() + 1);
-}
-
-void CTemplClass_ParsePartialSpecialization(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset) {
- Type *type;
- NameSpace *nspace;
- TemplArg *args;
- TemplPartialSpec *pspec;
- TemplClass *templ;
- TemplArg *arg;
- TemplParam *param;
-
- nspace = what_is_this->nspace;
-
- if ((tk = lex()) != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return;
- }
-
- if (!(type = CScope_GetLocalTagType(nspace, tkidentifier))) {
- CError_Error(CErrorStr140, tkidentifier->name);
- return;
- }
-
- if (!IS_TEMPL_CLASS(type)) {
- CError_Error(CErrorStr132, tkidentifier->name);
- return;
- }
-
- if ((tk = lex()) != '<')
- CError_FATAL(469);
-
- for (param = params; param; param = param->next) {
- switch (param->pid.type) {
- case TPT_TYPE:
- if (!param->data.typeparam.type)
- continue;
- CError_Error(CErrorStr344);
- break;
-
- case TPT_NONTYPE:
- if (!param->data.paramdecl.defaultarg)
- continue;
- CError_Error(CErrorStr344);
- break;
-
- case TPT_TEMPLATE:
- if (!param->data.templparam.defaultarg)
- continue;
- CError_Error(CErrorStr344);
- break;
-
- default:
- CError_FATAL(501);
- }
-
- break;
- }
-
- args = CTempl_ParseUncheckTemplArgs(TEMPL_CLASS(type)->templ__params, 0);
- tk = lex();
-
- arg = args;
- param = TEMPL_CLASS(type)->templ__params;
- while (1) {
- if (!arg) {
- if (!param)
- break;
- CError_Error(CErrorStr344);
- return;
- }
- if (!param) {
- CError_Error(CErrorStr344);
- return;
- }
- if (param->pid.type != arg->pid.type) {
- CError_Error(CErrorStr344);
- return;
- }
- arg = arg->next;
- param = param->next;
- }
-
- if (CTemplTool_IsSameTemplate(TEMPL_CLASS(type)->templ__params, args))
- CError_Error(CErrorStr344);
-
- for (pspec = TEMPL_CLASS(type)->pspecs; pspec; pspec = pspec->next) {
- if (CTemplTool_EqualParams(pspec->templ->templ__params, params, 0) && CTemplTool_EqualArgs(pspec->args, args))
- break;
- }
-
- if (!pspec) {
- templ = galloc(sizeof(TemplClass));
- memclrw(templ, sizeof(TemplClass));
-
- templ->templ__params = params;
- CDecl_DefineClass(nspace, TEMPL_CLASS(type)->theclass.classname, TYPE_CLASS(templ), mode, 0, 0);
-
- templ->theclass.flags = CLASS_IS_TEMPL;
- templ->pspec_owner = TEMPL_CLASS(type);
-
- pspec = galloc(sizeof(TemplPartialSpec));
- memclrw(pspec, sizeof(TemplPartialSpec));
-
- pspec->templ = templ;
- pspec->args = CTemplTool_MakeGlobalTemplArgCopy(args);
- pspec->next = TEMPL_CLASS(type)->pspecs;
- TEMPL_CLASS(type)->pspecs = pspec;
- } else {
- if ((pspec->templ->theclass.flags & CLASS_COMPLETED) && tk != ';') {
- CError_Error(CErrorStr132, TEMPL_CLASS(type)->theclass.classname->name);
- return;
- }
-
- if (tk == ':' || tk == '{')
- CTemplTool_EqualParams(pspec->templ->templ__params, params, 1);
- }
-
- switch (tk) {
- case ':':
- case '{':
- CTemplClass_ParseBody(pspec->templ, mode, offset);
- break;
- case ';':
- break;
- default:
- CError_Error(CErrorStr121);
- }
-}
-
-void CTemplClass_ParseClass(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset) {
- TemplClass *templ;
- NameSpace *nspace;
- Type *type;
- UInt8 classDeclSpec = 0;
-
- nspace = what_is_this->nspace;
- if ((tk = lex()) == TK_UU_DECLSPEC)
- CDecl_ParseClassDeclSpec(&classDeclSpec);
-
- if (tk != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- return;
- }
-
- type = CScope_GetLocalTagType(nspace, tkidentifier);
- if (!type) {
- templ = galloc(sizeof(TemplClass));
- memclrw(templ, sizeof(TemplClass));
-
- templ->next = ctempl_templates;
- ctempl_templates = templ;
-
- templ->templ__params = params;
- CDecl_DefineClass(nspace, tkidentifier, TYPE_CLASS(templ), mode, 0, 1);
- templ->theclass.flags = CLASS_IS_TEMPL;
- templ->theclass.eflags = classDeclSpec;
-
- tk = lex();
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) {
- TemplateAction *action;
-
- templ->templ_parent = TEMPL_CLASS(nspace->theclass);
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_NESTEDCLASS;
- action->u.tclasstype = templ;
- CTemplClass_AppendTemplateAction(templ->templ_parent, action);
- }
- } else {
- if (!IS_TEMPL_CLASS(type)) {
- CError_Error(CErrorStr132, tkidentifier->name);
- return;
- }
-
- templ = TEMPL_CLASS(type);
- if (!CTemplTool_EqualParams(templ->templ__params, params, 0)) {
- CError_Error(CErrorStr132, templ->theclass.classname->name);
- return;
- }
-
- CTemplTool_MergeDefaultArgs(templ->templ__params, params);
- templ->theclass.eflags |= classDeclSpec;
-
- tk = lex();
-
- if ((templ->theclass.flags & CLASS_COMPLETED) && tk != ';') {
- CError_Error(CErrorStr132, templ->theclass.classname->name);
- return;
- }
-
- if (tk != ';')
- CTemplTool_EqualParams(templ->templ__params, params, 1);
- }
-
- switch (tk) {
- case ':':
- case '{':
- CTemplClass_ParseBody(templ, mode, offset);
- break;
- case ';':
- break;
- default:
- CError_Error(CErrorStr121);
- }
-}
-
-static Boolean CTemplClass_TypeParamCompare(TemplArg *arg, Type *type, UInt32 qual) {
- return is_typesame(type, arg->data.typeparam.type) && arg->data.typeparam.qual == qual;
-}
-
-static TemplArg *CTemplClass_PartialTemplateArgMatch(TemplPartialSpec *pspec, TemplArg *args, Boolean flag) {
- TemplArg *argA;
- TemplArg *argB;
- int i;
- DeduceInfo info;
-
- if (!CTemplTool_InitDeduceInfo(&info, pspec->templ->templ__params, NULL, 1))
- return NULL;
-
- argA = pspec->args;
- argB = args;
- while (1) {
- if (!argA) {
- if (argB)
- return NULL;
-
- for (i = 0; i < info.maxCount; i++) {
- if (!info.args[i].is_deduced)
- return NULL;
- }
-
- if (flag)
- return CTemplTool_MakeTemplArgList(&info);
- else
- return args;
- }
-
- if (!argB)
- return NULL;
-
- if (argA->pid.type != argB->pid.type)
- return NULL;
-
- switch (argA->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(argA->data.typeparam.type)) {
- if (!CTempl_DeduceType(
- argA->data.typeparam.type, argA->data.typeparam.qual,
- argB->data.typeparam.type, argB->data.typeparam.qual,
- info.args, 0, 0
- ))
- return NULL;
- } else {
- if (
- !is_typesame(argA->data.typeparam.type, argB->data.typeparam.type) ||
- argA->data.typeparam.qual != argB->data.typeparam.qual
- )
- return NULL;
- }
- break;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(argA->data.paramdecl.expr)) {
- i = CTempl_GetTemplateArgumentExpressionIndex(argA);
- CError_ASSERT(789, i >= 0);
-
- if (info.args[i].is_deduced) {
- if (!CTemplTool_EqualExprTypes(argB->data.paramdecl.expr, info.args[i].data.paramdecl.expr))
- return NULL;
- } else {
- info.args[i].data.paramdecl.expr = argB->data.paramdecl.expr;
- info.args[i].pid.type = TPT_NONTYPE;
- info.args[i].is_deduced = 1;
- }
- } else {
- if (!CTemplTool_EqualExprTypes(argB->data.paramdecl.expr, argA->data.paramdecl.expr))
- return NULL;
- }
- break;
-
- case TPT_TEMPLATE:
- if (CTemplTool_IsTemplateArgumentDependentType(argA->data.ttargtype)) {
- if (!CTempl_DeduceType(
- argA->data.ttargtype, 0,
- argB->data.ttargtype, 0,
- info.args, 0, 0
- ))
- return NULL;
- } else {
- if (!is_typesame(argA->data.ttargtype, argB->data.ttargtype))
- return NULL;
- }
- break;
-
- default:
- CError_FATAL(830);
- }
-
- argA = argA->next;
- argB = argB->next;
- }
-}
-
-static Boolean CTemplClass_PartialClassIsAtLeastAsSpecialized(TemplPartialSpec *pspec1, TemplPartialSpec *pspec2) {
- TemplArg *argA;
- TemplArg *argB;
- int i;
- DeduceInfo info;
-
- if (!CTemplTool_InitDeduceInfo(&info, pspec2->templ->templ__params, NULL, 1))
- return 0;
-
- argA = pspec1->args;
- argB = pspec2->args;
-
- while (1) {
- if (!argA) {
- CError_ASSERT(856, !argB);
-
- for (i = 0; i < info.maxCount; i++) {
- if (!info.args[i].is_deduced)
- return 0;
- }
-
- return 1;
- }
-
- CError_ASSERT(865, argB);
- CError_ASSERT(866, argA->pid.type == argB->pid.type);
-
- switch (argA->pid.type) {
- case TPT_TYPE:
- if (!CTempl_DeduceType(
- argB->data.typeparam.type, argB->data.typeparam.qual,
- argA->data.typeparam.type, argA->data.typeparam.qual,
- info.args, 0, 0
- ))
- return 0;
- break;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(argB->data.paramdecl.expr)) {
- i = CTempl_GetTemplateArgumentExpressionIndex(argB);
- CError_ASSERT(907, i >= 0);
-
- if (info.args[i].is_deduced) {
- if (argA->data.paramdecl.expr) {
- if (!info.args[i].data.paramdecl.expr || !CTemplTool_EqualExprTypes(argA->data.paramdecl.expr, info.args[i].data.paramdecl.expr))
- return 0;
- } else {
- if (info.args[i].data.paramdecl.expr || argA->pid.index != info.args[i].pid.index)
- return 0;
- }
- } else {
- info.args[i].data.paramdecl.expr = argA->data.paramdecl.expr;
- info.args[i].pid.index = argA->pid.index;
- info.args[i].pid.type = TPT_NONTYPE;
- info.args[i].is_deduced = 1;
- }
- } else {
- if (
- !argA->data.paramdecl.expr ||
- !CTemplTool_EqualExprTypes(argA->data.paramdecl.expr, argB->data.paramdecl.expr)
- )
- return 0;
- }
- break;
-
- case TPT_TEMPLATE:
- if (!CTempl_DeduceType(
- argB->data.ttargtype, 0,
- argA->data.ttargtype, 0,
- info.args, 0, 0
- ))
- return 0;
- break;
-
- default:
- CError_FATAL(955);
- }
-
- argA = argA->next;
- argB = argB->next;
- }
-}
-
-static Boolean CTemplClass_PartialClassIsMoreSpecialized(TemplPartialSpec *pspec1, TemplPartialSpec *pspec2) {
- return CTemplClass_PartialClassIsAtLeastAsSpecialized(pspec1, pspec2) &&
- !CTemplClass_PartialClassIsAtLeastAsSpecialized(pspec2, pspec1);
-}
-
-typedef struct PSpecList {
- struct PSpecList *next;
- TemplPartialSpec *pspec;
-} PSpecList;
-
-static PSpecList *CTemplClass_FindMostSpecializedPartialSpecializations(PSpecList *list) {
- PSpecList **array;
- PSpecList *scan;
- int i;
- int j;
- int count;
-
- scan = list;
- count = 0;
- while (scan) {
- scan = scan->next;
- count++;
- }
-
- array = lalloc(sizeof(PSpecList *) * count);
- for (i = 0, scan = list; scan; scan = scan->next)
- array[i++] = scan;
-
- for (i = 0; i < count; i++) {
- if (array[i]) {
- for (j = 0; j < count; j++) {
- if (array[j] && i != j && CTemplClass_PartialClassIsMoreSpecialized(array[i]->pspec, array[j]->pspec))
- array[j] = NULL;
- }
- }
- }
-
- for (i = 0, list = NULL; i < count; i++) {
- if (array[i]) {
- if (!list)
- list = array[i];
- else
- array[j]->next = array[i];
- array[i]->next = NULL;
- j = i;
- }
- }
-
- return list;
-}
-
-Boolean CTemplClass_FindPartialTemplate(TemplArg *args, TemplClass **resultTempl, TemplArg **resultArgs) {
- TemplPartialSpec *pspec;
- PSpecList *list;
- TemplClassInst *inst;
-
- for (inst = (*resultTempl)->instances; inst; inst = inst->next) {
- if (inst->is_instantiated || inst->is_specialized) {
- if (CTemplTool_EqualArgs(args, inst->oargs ? inst->oargs : inst->inst_args))
- return 0;
- }
- }
-
- list = NULL;
- for (pspec = (*resultTempl)->pspecs; pspec; pspec = pspec->next) {
- if (CTemplClass_PartialTemplateArgMatch(pspec, args, 0)) {
- PSpecList *entry = lalloc(sizeof(PSpecList));
- entry->next = list;
- entry->pspec = pspec;
- list = entry;
- }
- }
-
- if (list) {
- if (list->next) {
- list = CTemplClass_FindMostSpecializedPartialSpecializations(list);
- if (list->next)
- CError_Error(CErrorStr346);
- }
-
- if (!list->pspec->templ->templ__params) {
- *resultTempl = list->pspec->templ;
- *resultArgs = NULL;
- return 1;
- }
-
- *resultTempl = list->pspec->templ;
- *resultArgs = CTemplClass_PartialTemplateArgMatch(list->pspec, args, 1);
- return *resultArgs != NULL;
- } else {
- return 0;
- }
-}
-
-TemplClass *CTemplClass_DefineNestedClass(TemplClass *parent, HashNameNode *name, short mode) {
- TemplateAction *action;
- TemplClass *templ;
-
- templ = galloc(sizeof(TemplClass));
- memclrw(templ, sizeof(TemplClass));
-
- templ->next = ctempl_templates;
- ctempl_templates = templ;
-
- templ->templ_parent = parent;
- templ->templ__params = NULL;
- CDecl_DefineClass(parent->theclass.nspace, name, TYPE_CLASS(templ), mode, 0, 1);
-
- templ->theclass.flags = CLASS_IS_TEMPL;
- templ->align = copts.structalignment;
-
- action = galloc(sizeof(TemplateAction));
- memclrw(action, sizeof(TemplateAction));
-
- action->type = TAT_NESTEDCLASS;
- action->u.tclasstype = templ;
- CTemplClass_AppendTemplateAction(parent, action);
-
- return templ;
-}
-
-static void CTemplClass_CopyNestedClass(TypeDeduce *deduce, TemplClass *templ) {
- ObjTypeTag *tag;
-
- tag = galloc(sizeof(ObjTypeTag));
- memclrw(tag, sizeof(ObjTypeTag));
-
- tag->otype = OT_TYPETAG;
- tag->access = ACCESSPUBLIC;
-
- if (!templ->templ__params) {
- TemplClassInst *inst = CTemplClass_NewInstance(templ, NULL, NULL);
- inst->parent = deduce->inst;
- inst->theclass.nspace->parent = deduce->inst->theclass.nspace;
-
- tag->type = TYPE(inst);
- } else {
- TemplClass *copy = galloc(sizeof(TemplClass));
- memclrw(copy, sizeof(TemplClass));
-
- copy->next = ctempl_templates;
- ctempl_templates = copy;
-
- copy->theclass = templ->theclass;
- copy->templ_parent = deduce->tmclass;
- copy->inst_parent = deduce->inst;
- copy->templ__params = templ->templ__params;
- copy->members = NULL;
- copy->instances = NULL;
- copy->pspecs = NULL;
- copy->actions = templ->actions;
- copy->lex_order_count = templ->lex_order_count;
- copy->align = templ->align;
- copy->flags = templ->flags;
-
- tag->type = TYPE(copy);
- }
-
- CScope_AddObject(deduce->inst->theclass.nspace, templ->theclass.classname, OBJ_BASE(tag));
-}
-
-static void CTemplClass_CopyBaseClasses(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) {
- TemplateAction *action;
- ClassList *newBase;
- ClassList *templbase;
- ClassList *instbase;
- ClassList *base;
- UInt32 qual = 0;
-
- for (base = templ->theclass.bases; base; base = base->next) {
- ClassList *scan;
- newBase = galloc(sizeof(ClassList));
- *newBase = *base;
- newBase->next = NULL;
-
- if ((scan = inst->theclass.bases)) {
- while (1) {
- if (scan->base == newBase->base) {
- CError_Error(CErrorStr131);
- break;
- }
- if (!scan->next) {
- scan->next = newBase;
- break;
- }
- scan = scan->next;
- }
- } else {
- inst->theclass.bases = newBase;
- }
- }
-
- for (action = deduce->tmclass->actions; action; action = action->next) {
- if (action->type == TAT_BASE) {
- TStreamElement *save;
-
- CTemplClass_SetupActionErrorRef(action, &save);
-
- newBase = galloc(sizeof(ClassList));
- memclrw(newBase, sizeof(ClassList));
-
- newBase->base = TYPE_CLASS(CTemplTool_DeduceTypeCopy(deduce, action->u.base.type, &qual));
- newBase->access = action->u.base.access;
- newBase->is_virtual = action->u.base.is_virtual;
-
- if (IS_TYPE_CLASS(newBase->base)) {
- if (newBase->base->size == 0) {
- CDecl_CompleteType(TYPE(newBase->base));
- IsCompleteType(TYPE(newBase->base));
- }
-
- if (CDecl_CheckNewBase(TYPE_CLASS(inst), newBase->base, newBase->is_virtual)) {
- if (action->u.base.insert_after) {
- templbase = templ->theclass.bases;
- instbase = inst->theclass.bases;
- while (1) {
- CError_ASSERT(1222, templbase && instbase);
-
- if (templbase == action->u.base.insert_after) {
- newBase->next = instbase->next;
- instbase->next = newBase;
- break;
- }
-
- templbase = templbase->next;
- instbase = instbase->next;
- }
- } else {
- newBase->next = inst->theclass.bases;
- inst->theclass.bases = newBase;
- }
- }
- } else {
- CError_Error(CErrorStr131);
- }
-
- CTemplClass_RestoreActionErrorRef(&save);
- }
- }
-
- if (inst->theclass.flags & CLASS_HAS_VBASES)
- CDecl_MakeVBaseList(TYPE_CLASS(inst));
-}
-
-static void CTemplClass_CopyEnum(TypeDeduce *deduce, TemplateAction *action) {
- TypeEnum *destenum;
- TypeEnum *srcenum;
- ObjEnumConst **destptr;
- ObjEnumConst *src;
- TemplateAction *scanaction;
-
- srcenum = action->u.enumtype;
- destenum = galloc(sizeof(TypeEnum));
- memclrw(destenum, sizeof(TypeEnum));
-
- destenum->type = TYPEENUM;
- destenum->size = srcenum->size;
- destenum->nspace = deduce->inst->theclass.nspace;
- destenum->enumtype = srcenum->enumtype;
- destenum->enumname = srcenum->enumname;
-
- if (destenum->enumname)
- CScope_DefineTypeTag(destenum->nspace, destenum->enumname, TYPE(destenum));
-
- src = srcenum->enumlist;
- destptr = &destenum->enumlist;
- while (src) {
- ObjEnumConst *dest;
-
- dest = galloc(sizeof(ObjEnumConst));
- *dest = *src;
-
- *destptr = dest;
- dest->next = NULL;
- dest->type = TYPE(destenum);
- CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest));
-
- src = src->next;
- destptr = &(*destptr)->next;
- }
-
- for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) {
- if (scanaction->type == TAT_ENUMERATOR && scanaction->u.enumerator.objenumconst->type == TYPE(srcenum)) {
- CTemplClass_NewDefAction(deduce, action)->enumtype = destenum;
- return;
- }
- }
-}
-
-static void CTemplClass_CompleteEnumType(TypeDeduce *deduce, TemplateAction *action, TypeEnum *destenum) {
- TypeEnum *srcenum;
- ObjEnumConst *dest;
- TemplateAction *scanaction;
- ENode *expr;
- ObjEnumConst *src;
-
- srcenum = action->u.enumtype;
-
- for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) {
- if (scanaction->type == TAT_ENUMERATOR) {
- src = scanaction->u.enumerator.objenumconst;
- if (src->type == TYPE(srcenum)) {
- TStreamElement *save;
-
- CTemplClass_SetupActionErrorRef(scanaction, &save);
-
- dest = destenum->enumlist;
- while (dest) {
- if (dest->name == src->name)
- break;
- dest = dest->next;
- }
-
- CError_ASSERT(1332, dest);
-
- if (scanaction->u.enumerator.initexpr) {
- expr = CTemplTool_DeduceExpr(deduce, scanaction->u.enumerator.initexpr);
- if (!ENODE_IS(expr, EINTCONST)) {
- CError_Error(CErrorStr124);
- CTemplClass_RestoreActionErrorRef(&save);
- break;
- }
- } else {
- CError_ASSERT(1347, expr);
- expr->data.intval = CInt64_Add(expr->data.intval, cint64_one);
- }
-
- dest->val = expr->data.intval;
- dest->type = expr->rtype;
- CTemplClass_RestoreActionErrorRef(&save);
- }
- }
- }
-
- CDecl_ComputeUnderlyingEnumType(destenum);
-}
-
-static void CTemplClass_CopyObjMemberVarPath(TypeDeduce *deduce, ObjMemberVarPath *ivar) {
- ObjMemberVarPath *copy;
-
- copy = galloc(sizeof(ObjMemberVarPath));
- *copy = *ivar;
-
- if (copy->path && copy->path->type == TYPE(deduce->tmclass)) {
- copy->path = CClass_GetPathCopy(copy->path, 1);
- copy->path->type = TYPE(deduce->inst);
- }
-
- CScope_AddObject(deduce->inst->theclass.nspace, copy->name, OBJ_BASE(copy));
-}
-
-static void CTemplClass_CopyIVars(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) {
- ObjMemberVar *src;
- ObjMemberVar *dest;
- ObjMemberVar **destptr;
- TemplateAction *scanaction;
-
- src = templ->theclass.ivars;
- destptr = &inst->theclass.ivars;
-
- while (src) {
- CError_ASSERT(1397, !src->has_path);
-
- dest = galloc(sizeof(ObjMemberVar));
- *dest = *src;
-
- for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) {
- if (scanaction->type == TAT_OBJECTDEF && scanaction->u.refobj == OBJ_BASE(src)) {
- CTemplClass_NewDefAction(deduce, scanaction)->refobj = OBJ_BASE(dest);
- break;
- }
- }
-
- if (!scanaction) {
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual);
- if (dest->type->size == 0) {
- CDecl_CompleteType(dest->type);
- IsCompleteType(dest->type);
- }
- }
-
- if (dest->name && dest->name != no_name_node)
- CScope_AddObject(inst->theclass.nspace, dest->name, OBJ_BASE(dest));
-
- *destptr = dest;
- destptr = &dest->next;
- src = src->next;
- }
-}
-
-static void CTemplClass_CopyObjType(TypeDeduce *deduce, ObjType *src, HashNameNode *name) {
- TemplateAction *scanaction;
- NameSpaceObjectList *list;
- NameSpaceObjectList *newlist;
- ObjType *dest;
-
- for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) {
- if (scanaction->type == TAT_OBJECTDEF && scanaction->u.refobj == OBJ_BASE(src))
- break;
- }
-
- dest = galloc(sizeof(ObjType));
- *dest = *src;
-
- if (scanaction)
- CTemplClass_NewDefAction(deduce, scanaction)->refobj = OBJ_BASE(dest);
- else
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual);
-
- if ((list = CScope_FindName(deduce->inst->theclass.nspace, name)) && list->object->otype == OT_TYPETAG) {
- CError_ASSERT(1470, list->next == NULL);
-
- newlist = galloc(sizeof(NameSpaceObjectList));
- newlist->object = list->object;
- newlist->next = NULL;
-
- list->object = OBJ_BASE(dest);
- list->next = newlist;
- } else {
- CScope_AddObject(deduce->inst->theclass.nspace, name, OBJ_BASE(dest));
- }
-}
-
-static void CTemplClass_CopyObjTypeTag(TypeDeduce *deduce, ObjTypeTag *src, HashNameNode *name) {
- UInt32 qual = 0;
- ObjTypeTag *dest = galloc(sizeof(ObjTypeTag));
-
- *dest = *src;
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &qual);
-
- CScope_AddObject(deduce->inst->theclass.nspace, name, OBJ_BASE(dest));
-}
-
-static void CTemplClass_CopyMemberTemplate(TypeDeduce *deduce, Object *src) {
- TemplateFunction *desttempl;
- Object *dest;
- TemplateFunction *srctempl;
- TemplateAction *action;
-
- srctempl = src->u.func.u.templ;
- CError_ASSERT(1516, srctempl && srctempl->params);
-
- for (action = deduce->tmclass->actions; action; action = action->next) {
- if (action->type == TAT_OBJECTDEF && action->u.refobj == OBJ_BASE(src))
- break;
- }
-
- desttempl = galloc(sizeof(TemplateFunction));
- *desttempl = *srctempl;
-
- desttempl->next = ctempl_templatefuncs;
- ctempl_templatefuncs = desttempl;
-
- desttempl->unk4 = srctempl;
-
- dest = galloc(sizeof(Object));
- *dest = *src;
-
- dest->u.func.u.templ = desttempl;
- dest->nspace = deduce->inst->theclass.nspace;
-
- CError_ASSERT(1541, !deduce->x15);
- deduce->x15 = 1;
- deduce->nindex = srctempl->params->pid.nindex;
-
- if (action)
- CTemplClass_NewDefAction(deduce, action)->refobj = OBJ_BASE(dest);
- else
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual);
-
- deduce->x15 = 0;
-
- CError_ASSERT(1553, IS_TYPE_FUNC(dest->type));
-
- TYPE_FUNC(dest->type)->flags |= FUNC_IS_TEMPL;
-
- if (
- (TYPE_FUNC(dest->type)->flags & FUNC_IS_CTOR) &&
- deduce->x17 &&
- !action
- )
- {
- FuncArg *arg;
- CError_ASSERT(1560, TYPE_FUNC(dest->type)->args);
- arg = CParser_NewFuncArg();
- arg->type = TYPE(&stsignedshort);
- arg->next = TYPE_FUNC(dest->type)->args->next;
- TYPE_FUNC(dest->type)->args->next = arg;
- }
-
- CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest));
-}
-
-static void CTemplClass_CopyObject(TypeDeduce *deduce, Object *src) {
- ObjectTemplated *dest;
- TemplateAction *action;
- TemplateAction *action2;
- Boolean flag;
-
- flag = 1;
- if (src->nspace != deduce->tmclass->theclass.nspace) {
- CError_ASSERT(1587, src->datatype == DALIAS);
- flag = 0;
- }
-
- if (IS_TEMPL_FUNC(src->type)) {
- CTemplClass_CopyMemberTemplate(deduce, src);
- return;
- }
-
- for (action = deduce->tmclass->actions; action; action = action->next) {
- if (action->type == TAT_OBJECTDEF && action->u.refobj == OBJ_BASE(src))
- break;
- }
-
- dest = galloc(sizeof(ObjectTemplated));
- dest->object = *src;
-
- if (action)
- CTemplClass_NewDefAction(deduce, action)->refobj = OBJ_BASE(dest);
- else
- dest->object.type = CTemplTool_DeduceTypeCopy(deduce, dest->object.type, &dest->object.qual);
-
- if (flag)
- dest->object.nspace = deduce->inst->theclass.nspace;
-
- dest->object.qual |= Q_IS_TEMPLATED;
- dest->parent = src;
-
- if (IS_TYPE_FUNC(dest->object.type))
- TYPE_FUNC(dest->object.type)->flags &= ~FUNC_DEFINED;
-
- switch (dest->object.datatype) {
- case DDATA:
- dest->object.u.data.linkname = NULL;
- for (action2 = deduce->tmclass->actions; action2; action2 = action2->next) {
- if (action2->type == TAT_OBJECTINIT && action2->u.objectinit.object == src) {
- CTemplClass_NewDefAction(deduce, action2)->refobj = OBJ_BASE(dest);
- break;
- }
- }
- break;
-
- case DABSOLUTE:
- break;
-
- case DFUNC:
- case DVFUNC:
- dest->object.u.func.linkname = NULL;
- CError_ASSERT(1650, IS_TYPE_FUNC(dest->object.type));
- CError_ASSERT(1651, !dest->object.u.func.u.templ && !dest->object.u.func.defargdata);
-
- if (
- (TYPE_FUNC(dest->object.type)->flags & FUNC_IS_CTOR) &&
- deduce->x17 &&
- !action
- )
- {
- FuncArg *arg;
- CError_ASSERT(1657, TYPE_FUNC(dest->object.type)->args);
- arg = CParser_NewFuncArg();
- arg->type = TYPE(&stsignedshort);
- arg->next = TYPE_FUNC(dest->object.type)->args->next;
- TYPE_FUNC(dest->object.type)->args->next = arg;
- }
-
- if (TYPE_FUNC(dest->object.type)->flags & FUNC_CONVERSION) {
- CError_ASSERT(1665, IS_TYPE_FUNC(src->type));
- if (CTemplTool_IsTemplateArgumentDependentType(TYPE_FUNC(src->type)->functype)) {
- CError_ASSERT(1668, action);
- return;
- }
- }
-
- break;
-
- case DINLINEFUNC:
- break;
-
- case DALIAS:
- if (dest->object.u.alias.member && dest->object.u.alias.member->type == TYPE(deduce->tmclass)) {
- dest->object.u.alias.member = CClass_GetPathCopy(dest->object.u.alias.member, 1);
- dest->object.u.alias.member->type = TYPE(deduce->inst);
- }
- break;
-
- case DLOCAL:
- case DEXPR:
- CError_FATAL(1688);
-
- default:
- CError_FATAL(1691);
- }
-
- CScope_AddObject(deduce->inst->theclass.nspace, dest->object.name, OBJ_BASE(dest));
-}
-
-static void CTemplClass_CompleteObject(TypeDeduce *deduce, TemplateAction *action, ObjBase *refobj) {
- if (refobj->otype == OT_MEMBERVAR) {
- ObjMemberVar *ivar = OBJ_MEMBER_VAR(refobj);
- ivar->type = CTemplTool_DeduceTypeCopy(deduce, ivar->type, &ivar->qual);
-
- if (ivar->type->size == 0) {
- CDecl_CompleteType(ivar->type);
- if (copts.experimental) {
- if (ivar->next || ivar->type->size != 0 || !IS_TYPE_ARRAY(ivar->type))
- IsCompleteType(ivar->type);
- } else {
- IsCompleteType(ivar->type);
- }
- }
- } else if (refobj->otype == OT_TYPE) {
- ObjType *obj = OBJ_TYPE(refobj);
- obj->type = CTemplTool_DeduceTypeCopy(deduce, obj->type, &obj->qual);
- } else {
- Object *dest;
- Object *src;
-
- CError_ASSERT(1737, refobj->otype == OT_OBJECT);
-
- dest = OBJECT(refobj);
- src = OBJECT(action->u.refobj);
-
- if (IS_TEMPL_FUNC(src->type)) {
- TemplateFunction *templ = src->u.func.u.templ;
- CError_ASSERT(1747, templ);
- CError_ASSERT(1748, !deduce->x15);
-
- deduce->x15 = 1;
- deduce->nindex = templ->params->pid.nindex;
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual);
- deduce->x15 = 0;
-
- CError_ASSERT(1753, IS_TYPE_FUNC(dest->type));
- TYPE_FUNC(dest->type)->flags |= FUNC_IS_TEMPL;
- } else {
- dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual);
- dest->qual |= Q_IS_TEMPLATED;
-
- if (IS_TYPE_FUNC(dest->type))
- TYPE_FUNC(dest->type)->flags &= ~FUNC_DEFINED;
-
- switch (dest->datatype) {
- case DFUNC:
- case DVFUNC:
- CError_ASSERT(1769, IS_TYPE_FUNC(dest->type));
- if (TYPE_FUNC(dest->type)->flags & FUNC_CONVERSION) {
- CError_ASSERT(1772, IS_TYPE_FUNC(dest->type));
- if (CTemplTool_IsTemplateArgumentDependentType(TYPE_FUNC(src->type)->functype)) {
- dest->name = CMangler_ConversionFuncName(
- TYPE_FUNC(dest->type)->functype, TYPE_FUNC(dest->type)->qual);
- CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest));
- }
- }
-
- if ((TYPE_FUNC(dest->type)->flags & FUNC_IS_CTOR) && deduce->x17) {
- FuncArg *arg;
- CError_ASSERT(1786, TYPE_FUNC(dest->type)->args);
- arg = CParser_NewFuncArg();
- arg->type = TYPE(&stsignedshort);
- arg->next = TYPE_FUNC(dest->type)->args->next;
- TYPE_FUNC(dest->type)->args->next = arg;
- }
-
- break;
- }
- }
- }
-}
-
-static void CTemplClass_CompleteObjectInit(TypeDeduce *deduce, TemplateAction *action, Object *object) {
- ENode *expr = CTemplTool_DeduceExpr(deduce, action->u.objectinit.initexpr);
-
- if (ENODE_IS(expr, EINTCONST) && (object->qual & Q_CONST) && IS_TYPE_INT_OR_ENUM(object->type)) {
- object->u.data.u.intconst = expr->data.intval;
- object->qual |= Q_INLINE_DATA | Q_20000;
- } else {
- CError_Error(CErrorStr354, object->name->name);
- }
-}
-
-static void CTemplClass_CopyNameSpace(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) {
- NameSpaceName *nsname;
- NameSpaceObjectList *list;
-
- CError_ASSERT(1830, !templ->theclass.nspace->is_hash);
-
- for (nsname = templ->theclass.nspace->data.list; nsname; nsname = nsname->next) {
- for (list = &nsname->first; list; list = list->next) {
- switch (list->object->otype) {
- case OT_ENUMCONST:
- break;
- case OT_MEMBERVAR:
- if (OBJ_MEMBER_VAR(list->object)->has_path)
- CTemplClass_CopyObjMemberVarPath(deduce, OBJ_MEMBER_VAR_PATH(list->object));
- break;
- case OT_TYPE:
- CTemplClass_CopyObjType(deduce, OBJ_TYPE(list->object), nsname->name);
- break;
- case OT_TYPETAG:
- break;
- case OT_NAMESPACE:
- CError_FATAL(1854);
- case OT_OBJECT:
- CTemplClass_CopyObject(deduce, OBJECT(list->object));
- break;
- default:
- CError_FATAL(1861);
- }
- }
- }
-}
-
-static void CTemplClass_CopyUsingDecl(TypeDeduce *deduce, TypeTemplDep *type, AccessType access) {
- TypeClass *tclass;
- UInt32 qual = 0;
-
- CError_ASSERT(1878, IS_TYPE_TEMPLATE(type) && type->dtype == TEMPLDEP_QUALNAME);
-
- tclass = TYPE_CLASS(CTemplTool_DeduceTypeCopy(deduce, TYPE(type->u.qual.type), &qual));
- if (!IS_TYPE_CLASS(tclass)) {
- CError_Error(CErrorStr340, type->u.qual.name->name);
- return;
- }
-
- CDecl_CompleteType(TYPE(tclass));
- CScope_AddClassUsingDeclaration(TYPE_CLASS(deduce->inst), tclass, type->u.qual.name, access);
-}
-
-static void CTemplClass_CopyFriend(TypeDeduce *deduce, TemplateFriend *tfriend) {
- TemplArg *arg;
- Object *funcobj;
- Boolean flag;
- CScopeSave saveScope;
- DeclInfo di;
-
- CDecl_UnpackDeclInfo(&di, &tfriend->decl);
-
- if (CTemplTool_IsTemplateArgumentDependentType(di.thetype))
- di.thetype = CTemplTool_DeduceTypeCopy(deduce, di.thetype, &di.qual);
-
- if (di.expltargs) {
- di.expltargs = CTemplTool_MakeGlobalTemplArgCopy(di.expltargs);
- for (arg = di.expltargs; arg; arg = arg->next) {
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- break;
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- arg->data.paramdecl.expr = CTemplTool_DeduceExpr(deduce, arg->data.paramdecl.expr);
- break;
- case TPT_TEMPLATE:
- default:
- CError_FATAL(1930);
- }
- }
- }
-
- if (IS_TYPE_FUNC(di.thetype)) {
- CScope_SetNameSpaceScope(CScope_FindGlobalNS(deduce->inst->theclass.nspace), &saveScope);
- funcobj = CDecl_GetFunctionObject(&di, NULL, &flag, 0);
- CScope_RestoreScope(&saveScope);
-
- if (funcobj) {
- CDecl_AddFriend(TYPE_CLASS(deduce->inst), funcobj, NULL);
- if (tfriend->stream.tokens)
- CInline_AddInlineFunctionAction(funcobj, TYPE_CLASS(deduce->inst), &tfriend->fileoffset, &tfriend->stream, 0);
- } else {
- CError_Error(CErrorStr201);
- }
- } else {
- CError_ASSERT(1963, IS_TYPE_CLASS(di.thetype));
- CDecl_AddFriend(TYPE_CLASS(deduce->inst), NULL, TYPE_CLASS(di.thetype));
- }
-}
-
-Boolean CTempl_InstantiateTemplateClass(TypeClass *tclass) {
- TemplClassInst *inst;
- ParserTryBlock *tryBlock;
- TemplateAction *action;
- DefAction *defAction;
- UInt8 saveAlignMode;
-
- TypeDeduce deduce;
- TemplStack stack;
- CScopeSave saveScope;
- ClassLayout layout;
- TemplClass *templ;
- TStreamElement *saveErrorRef;
- TemplArg *inst_args;
-
- CError_ASSERT(1989, tclass->flags & CLASS_IS_TEMPL_INST);
-
- if (tclass->flags & CLASS_COMPLETED)
- return 1;
-
- inst = TEMPL_CLASS_INST(tclass);
- if (inst->is_specialized)
- return 0;
-
- templ = inst->templ;
- if (!(templ->flags & TEMPLCLASS_FLAGS_2))
- templ = CTemplClass_GetMasterTemplate(templ);
-
- if (templ->pspecs && CTemplClass_FindPartialTemplate(inst->inst_args, &templ, &inst_args)) {
- CError_ASSERT(2013, !inst->oargs);
- inst->templ = templ;
- inst->oargs = inst->inst_args;
- inst->inst_args = inst_args;
- }
-
- if (!(templ->theclass.flags & CLASS_COMPLETED))
- return 0;
-
- if (inst->is_instantiated)
- return 0;
-
- inst->is_instantiated = 1;
- CScope_SetClassScope(tclass, &saveScope);
- CTemplTool_PushInstance(&stack, tclass, NULL);
-
- tryBlock = trychain;
- trychain = NULL;
-
- memclrw(&deduce, sizeof(deduce));
- deduce.tmclass = templ;
- deduce.inst = inst;
- deduce.params = templ->templ__params;
- deduce.args = inst->inst_args;
-
- CError_ASSERT(2045, !templ->theclass.sominfo);
- CError_ASSERT(2047, !templ->theclass.objcinfo);
- CError_ASSERT(2049, !templ->theclass.vtable);
-
- inst->theclass.flags |= templ->theclass.flags &
- (CLASS_ABSTRACT | CLASS_SINGLE_OBJECT | CLASS_HAS_VBASES | CLASS_IS_CONVERTIBLE | CLASS_COM_OBJECT);
-
- CTemplClass_CopyBaseClasses(&deduce, inst, templ);
-
- deduce.x17 = (inst->theclass.flags & CLASS_HAS_VBASES) && !(templ->theclass.flags & CLASS_HAS_VBASES);
-
- for (action = templ->actions; action; action = action->next) {
- switch (action->type) {
- case TAT_NESTEDCLASS:
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CopyNestedClass(&deduce, action->u.tclasstype);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- case TAT_ENUMTYPE:
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CopyEnum(&deduce, action);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- case TAT_FRIEND:
- case TAT_ENUMERATOR:
- case TAT_BASE:
- case TAT_OBJECTINIT:
- case TAT_USINGDECL:
- case TAT_OBJECTDEF:
- break;
- default:
- CError_FATAL(2094);
- }
- }
-
- CTemplClass_CopyIVars(&deduce, inst, templ);
- CTemplClass_CopyNameSpace(&deduce, inst, templ);
-
- CError_ASSERT(2105, !templ->theclass.friends);
-
- for (action = templ->actions; action; action = action->next) {
- switch (action->type) {
- case TAT_NESTEDCLASS:
- break;
- case TAT_ENUMTYPE:
- for (defAction = deduce.defActions; defAction; defAction = defAction->next) {
- if (defAction->action == action) {
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CompleteEnumType(&deduce, action, defAction->enumtype);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- }
- }
- break;
- case TAT_FRIEND:
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CopyFriend(&deduce, action->u.tfriend);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- case TAT_ENUMERATOR:
- break;
- case TAT_BASE:
- break;
- case TAT_OBJECTINIT:
- for (defAction = deduce.defActions; ; defAction = defAction->next) {
- CError_ASSERT(2136, defAction);
- if (defAction->action == action) {
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CompleteObjectInit(&deduce, action, OBJECT(defAction->refobj));
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- }
- }
- break;
- case TAT_USINGDECL:
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CopyUsingDecl(&deduce, action->u.usingdecl.type, action->u.usingdecl.access);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- case TAT_OBJECTDEF:
- for (defAction = deduce.defActions; ; defAction = defAction->next) {
- CError_ASSERT(2156, defAction);
- if (defAction->action == action) {
- CTemplClass_SetupActionErrorRef(action, &saveErrorRef);
- CTemplClass_CompleteObject(&deduce, action, defAction->refobj);
- CTemplClass_RestoreActionErrorRef(&saveErrorRef);
- break;
- }
- }
- break;
- }
- }
-
- memclrw(&layout, sizeof(layout));
- layout.lex_order_count = templ->lex_order_count;
- layout.has_vtable = templ->flags & TEMPLCLASS_HAS_VTABLE;
-
- saveAlignMode = copts.structalignment;
- copts.structalignment = templ->align;
- CDecl_CompleteClass(&layout, TYPE_CLASS(inst));
- copts.structalignment = saveAlignMode;
-
- if (templ->theclass.align > inst->theclass.align) {
- inst->theclass.align = templ->theclass.align;
- inst->theclass.size += CABI_StructSizeAlignValue(TYPE(inst), inst->theclass.size);
- }
-
- CTemplTool_PopInstance(&stack);
- CScope_RestoreScope(&saveScope);
- trychain = tryBlock;
-
- return 1;
-}
diff --git a/compiler_and_linker/unsorted/CTemplateFunc.c b/compiler_and_linker/unsorted/CTemplateFunc.c
deleted file mode 100644
index 3c5de98..0000000
--- a/compiler_and_linker/unsorted/CTemplateFunc.c
+++ /dev/null
@@ -1,1383 +0,0 @@
-#include "compiler/CTemplateFunc.h"
-#include "compiler/CABI.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/types.h"
-
-static Boolean ctempl_conversion_deduction;
-static UInt8 ctempl_explicitargs_nindex;
-static int ctempl_explicitargs_num;
-static Boolean ctempl_explicitargs_all;
-
-// forward decls
-static Boolean CTempl_DeduceTypeTemplDep(TypeTemplDep *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag);
-static Boolean CTempl_DeduceType1(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag);
-
-static void CTemplFunc_SetupTypeDeduce(TypeDeduce *deduce, TemplateFunction *templ, TemplArg *args) {
- memclrw(deduce, sizeof(TypeDeduce));
- if (templ->tfunc->nspace->theclass && (templ->tfunc->nspace->theclass->flags & CLASS_IS_TEMPL))
- deduce->tmclass = TEMPL_CLASS(templ->tfunc->nspace->theclass);
- deduce->params = templ->params;
- deduce->args = args;
-}
-
-Boolean CTempl_CanDeduceFunc(Object *object, TypeFunc *tfunc, TemplArg *args) {
- DeduceInfo info;
- int i;
-
- if (CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(object)->params, args, 0)) {
- if (CTempl_DeduceType(object->type, 0, TYPE(tfunc), 0, info.args, 0, 0)) {
- for (i = 0; i < info.maxCount; i++) {
- if (!info.args[i].is_deduced)
- return 0;
- }
- return 1;
- }
- }
-
- return 0;
-}
-
-static TemplFuncInstance *CTempl_GetCreateFuncInstance(Object *funcobj, TemplArg *args, Object *object2) {
- TemplFuncInstance *inst;
- TemplateFunction *templ;
- Object *instobj;
- TemplParam *param;
- TemplArg *arg;
- TemplArg *last;
- short paramCount;
- short i;
- TypeDeduce deduce;
-
- templ = CTemplTool_GetFuncTempl(funcobj);
-
- paramCount = 0;
- param = templ->params;
- while (param) {
- param = param->next;
- paramCount++;
- }
-
- for (i = 1, arg = args; i < paramCount; i++, arg++)
- arg->next = arg + 1;
- arg->next = NULL;
-
- for (inst = templ->instances; inst; inst = inst->next) {
- if (CTemplTool_EqualArgs(inst->args, args)) {
- if (object2)
- inst->object = object2;
- return inst;
- }
- }
-
- inst = galloc(sizeof(TemplFuncInstance));
- memclrw(inst, sizeof(TemplFuncInstance));
-
- for (i = 0, arg = NULL; i < paramCount; i++) {
- if (arg) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- last = galloc(sizeof(TemplArg));
- arg = last;
- }
-
- *last = *args;
- last->next = NULL;
- args++;
-
- if (last->pid.type == TPT_NONTYPE) {
- CError_ASSERT(114, last->data.paramdecl.expr);
- last->data.paramdecl.expr = CInline_CopyExpression(last->data.paramdecl.expr, CopyMode1);
- }
- }
-
- inst->args = arg;
- inst->next = templ->instances;
- templ->instances = inst;
-
- if (!object2) {
- instobj = CParser_NewFunctionObject(NULL);
- instobj->access = funcobj->access;
- instobj->nspace = funcobj->nspace;
- instobj->sclass = funcobj->sclass;
- instobj->qual = funcobj->qual | Q_MANGLE_NAME;
- instobj->name = templ->name;
- instobj->u.func.inst = inst;
-
- CTemplFunc_SetupTypeDeduce(&deduce, templ, inst->args);
- if (funcobj->nspace->theclass && (funcobj->nspace->theclass->flags & CLASS_IS_TEMPL_INST)) {
- deduce.tmclass = TEMPL_CLASS_INST(funcobj->nspace->theclass)->templ;
- deduce.inst = TEMPL_CLASS_INST(funcobj->nspace->theclass);
- }
-
- instobj->type = CTemplTool_DeduceTypeCopy(&deduce, funcobj->type, &instobj->qual);
- inst->object = instobj;
-
- if (IS_TYPE_FUNC(instobj->type)) {
- TYPE_FUNC(instobj->type)->flags &= ~FUNC_DEFINED;
- if (TYPE_FUNC(instobj->type)->flags & FUNC_IS_CTOR) {
- FuncArg *funcarg;
- CError_ASSERT(152, TYPE_FUNC(instobj->type)->flags & FUNC_METHOD);
- CError_ASSERT(153, funcarg = TYPE_FUNC(instobj->type)->args);
-
- if (TYPE_METHOD(instobj->type)->theclass->flags & CLASS_HAS_VBASES)
- CError_ASSERT(156, funcarg = funcarg->next);
-
- if (funcarg->next)
- CDecl_CheckCtorIntegrity(funcarg->next, TYPE_METHOD(instobj->type)->theclass);
- }
- }
-
- if ((instobj->qual & Q_INLINE) && templ->stream.tokens)
- CInline_AddTemplateFunctionAction(instobj, templ, inst);
-
- } else {
- inst->object = object2;
- }
-
- return inst;
-}
-
-TemplFuncInstance *CTempl_CheckFuncInstance(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2) {
- DeduceInfo info;
- int i;
-
- if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(object1)->params, args, 1))
- return NULL;
-
- if (!CTempl_DeduceType(object1->type, 0, TYPE(tfunc), 0, info.args, 0, 0))
- return NULL;
-
- i = 0;
- while (i < info.maxCount) {
- if (!info.args[i++].is_deduced)
- return NULL;
- }
-
- return CTempl_GetCreateFuncInstance(object1, info.args, object2);
-}
-
-TemplFuncInstance *CTempl_DeduceFunc(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2, Boolean flag) {
- return CTempl_CheckFuncInstance(object1, tfunc, args, object2);
-}
-
-static Boolean CTempl_FuncIsAtLeastAsSpecialized(Object *func1, Object *func2) {
- int i;
- FuncArg *arg1;
- FuncArg *arg2;
- Type *type1;
- Type *type2;
- UInt32 qual1;
- UInt32 qual2;
- DeduceInfo info;
-
- arg1 = TYPE_FUNC(func2->type)->args;
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func2->type)))
- arg1 = arg1->next;
-
- i = 0;
- while (1) {
- if (!arg1)
- break;
- CError_ASSERT(231, arg1->type != &stvoid);
- if (arg1 == &elipsis)
- break;
- if (arg1 == &oldstyle)
- break;
- arg1 = arg1->next;
- i++;
- }
-
- if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(func2)->params, NULL, 0))
- return 0;
-
- arg1 = TYPE_FUNC(func1->type)->args;
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func1->type)))
- arg1 = arg1->next;
-
- arg2 = TYPE_FUNC(func2->type)->args;
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func2->type)))
- arg2 = arg2->next;
-
- while (i > 0) {
- if (!arg1)
- break;
- if (arg1 == &elipsis)
- break;
- if (arg1 == &oldstyle)
- break;
-
- CError_ASSERT(255, arg2);
-
- type1 = arg1->type;
- qual1 = arg1->qual & (Q_CONST | Q_VOLATILE);
- qual2 = arg2->qual & (Q_CONST | Q_VOLATILE);
- type2 = arg2->type;
-
- if (!CTemplTool_IsTemplateArgumentDependentType(type2)) {
- if (IS_TYPE_REFERENCE(type1))
- type1 = TPTR_TARGET(type1);
- type1 = CParser_RemoveTopMostQualifiers(type1, &qual1);
-
- if (IS_TYPE_REFERENCE(type2))
- type2 = TPTR_TARGET(type2);
- type2 = CParser_RemoveTopMostQualifiers(type2, &qual2);
-
- if (!is_typesame(type1, type2) || qual1 != qual2)
- return 0;
- } else {
- if (!CTempl_DeduceType(type2, qual2, type1, qual1, info.args, 0, 0))
- return 0;
- }
-
- arg1 = arg1->next;
- arg2 = arg2->next;
- i--;
- }
-
- return 1;
-}
-
-Boolean CTempl_FuncIsMoreSpecialized(Object *object1, Object *object2) {
- return CTempl_FuncIsAtLeastAsSpecialized(object1, object2) && !CTempl_FuncIsAtLeastAsSpecialized(object2, object1);
-}
-
-Object *CTempl_PartialOrdering(Object *object, ObjectList *list, int count) {
- int i;
- int j;
- Object **array;
- ObjectList *scan;
- Object *arrayBuffer[16];
-
- for (count = 1, scan = list; scan; scan = scan->next) {
- if (IS_TEMPL_FUNC(scan->object->type))
- count++;
- }
-
- if (count > 16)
- array = lalloc(sizeof(Object *) * count);
- else
- array = arrayBuffer;
-
- array[0] = object;
- for (i = 1, scan = list; scan; scan = scan->next) {
- if (IS_TEMPL_FUNC(scan->object->type))
- array[i++] = scan->object;
- }
-
- for (i = 0; i < count; i++) {
- if (array[i]) {
- for (j = 0; j < count; j++) {
- if (array[j] && i != j && CTempl_FuncIsMoreSpecialized(array[i], array[j]))
- array[j] = NULL;
- }
- }
- }
-
- object = NULL;
-
- for (i = 0; i < count; i++) {
- if (array[i]) {
- if (object)
- return NULL;
- object = array[i];
- }
- }
-
- return object;
-}
-
-int CTempl_GetTemplateArgumentExpressionIndex(TemplArg *arg) {
- CError_ASSERT(529, arg->data.paramdecl.expr);
-
- if (ENODE_IS(arg->data.paramdecl.expr, ETEMPLDEP) && arg->data.paramdecl.expr->data.templdep.subtype == TDE_PARAM)
- return arg->data.paramdecl.expr->data.templdep.u.pid.index;
-
- return -1;
-}
-
-static Type *CTempl_GetSpecifiedType(TemplateFunction *templ, Type *type, UInt32 qual, TemplArg *args, UInt32 *resultQual) {
- TypeDeduce deduce;
-
- CTemplFunc_SetupTypeDeduce(&deduce, templ, args);
- *resultQual = qual;
- return CTemplTool_DeduceTypeCopy(&deduce, type, resultQual);
-}
-
-static Boolean CTempl_DeduceTemplateArgs(TemplArg *args1, TemplArg *args2, TemplArg *argArray) {
- int index;
-
- while (1) {
- if (!args1)
- return !args2;
- if (!args2)
- return 0;
-
- if (args1->pid.type != args2->pid.type)
- return 0;
-
- switch (args1->pid.type) {
- case TPT_TYPE:
- if (!CTempl_DeduceType1(
- args1->data.typeparam.type, args1->data.typeparam.qual,
- args2->data.typeparam.type, args2->data.typeparam.qual,
- argArray, 1
- ))
- return 0;
- break;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(args1->data.paramdecl.expr)) {
- index = CTempl_GetTemplateArgumentExpressionIndex(args1);
- if (index < 0)
- return 1;
-
- if (argArray[index].is_deduced) {
- if (!CTemplTool_EqualExprTypes(args2->data.paramdecl.expr, argArray[index].data.paramdecl.expr))
- return 0;
- } else {
- argArray[index].data.paramdecl.expr = args2->data.paramdecl.expr;
- argArray[index].pid.type = TPT_NONTYPE;
- argArray[index].is_deduced = 1;
- }
- } else {
- if (!CTemplTool_EqualExprTypes(args2->data.paramdecl.expr, args1->data.paramdecl.expr))
- return 0;
- }
- break;
-
- case TPT_TEMPLATE:
- if (!IS_TEMPL_CLASS(args2->data.ttargtype))
- return 0;
-
- index = args1->pid.index;
- if (argArray[index].is_deduced) {
- if (args2->data.ttargtype != argArray[index].data.ttargtype)
- return 0;
- } else {
- argArray[index].data.ttargtype = args2->data.ttargtype;
- argArray[index].pid.type = TPT_TEMPLATE;
- argArray[index].is_deduced = 1;
- }
- break;
-
- default:
- CError_FATAL(640);
- }
-
- args1 = args1->next;
- args2 = args2->next;
- }
-}
-
-static Boolean CTempl_DeduceTemplDepTemplate(TemplClass *templ1, TemplArg *args1, TemplClass *templ2, TemplArg *args2, TemplArg *argArray) {
- if (templ1 != templ2)
- return 0;
-
- return CTempl_DeduceTemplateArgs(args2, args1, argArray);
-}
-
-static Boolean CTempl_DeduceTemplateType(TemplClass *templ, TemplArg *args, TemplClassInst *inst, TemplArg *argArray) {
- TemplClassInst *scan;
-
- for (scan = templ->instances; scan; scan = scan->next) {
- if (scan == inst)
- return CTempl_DeduceTemplateArgs(args, scan->oargs ? scan->oargs : scan->inst_args, argArray);
- }
-
- return 0;
-}
-
-static Boolean CTempl_DeduceTemplateTypeBase(TemplClass *templ, TemplArg *args, TemplClassInst *inst, TemplArg *argArray, Boolean flag) {
- ClassList *base;
-
- if (CTempl_DeduceTemplateType(templ, args, inst, argArray))
- return 1;
-
- if (flag) {
- for (base = inst->theclass.bases; base; base = base->next) {
- if (CTempl_DeduceTemplateType(templ, args, TEMPL_CLASS_INST(base->base), argArray)) {
- ctempl_conversion_deduction = 1;
- return 1;
- }
- }
-
- for (base = inst->theclass.bases; base; base = base->next) {
- if (CTempl_DeduceTemplateTypeBase(templ, args, TEMPL_CLASS_INST(base->base), argArray, 1)) {
- ctempl_conversion_deduction = 1;
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static Boolean CTempl_DeduceQualTemplate(TypeTemplDep *type1, TemplArg *args1, Type *type2, TemplArg *argArray) {
- int index;
-
- if (type1->dtype == TEMPLDEP_ARGUMENT && type1->u.pid.type == TPT_TEMPLATE) {
- index = type1->u.pid.index;
- if (IS_TEMPL_CLASS_INST(type2)) {
- if (argArray[index].is_deduced) {
- if (argArray[index].data.ttargtype != TYPE(TEMPL_CLASS_INST(type2)->templ))
- return 0;
- } else {
- argArray[index].data.ttargtype = TYPE(TEMPL_CLASS_INST(type2)->templ);
- argArray[index].pid.type = TPT_TEMPLATE;
- argArray[index].is_deduced = 1;
- }
-
- return CTempl_DeduceTemplateArgs(args1, TEMPL_CLASS_INST(type2)->inst_args, argArray);
- }
-
- if (IS_TYPE_TEMPLATE(type2)) {
- if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_TEMPLATE) {
- if (argArray[index].is_deduced) {
- if (argArray[index].data.ttargtype != TYPE(TYPE_TEMPLATE(type2)->u.templ.templ))
- return 0;
- } else {
- argArray[index].data.ttargtype = TYPE(TYPE_TEMPLATE(type2)->u.templ.templ);
- argArray[index].pid.type = TPT_TEMPLATE;
- argArray[index].is_deduced = 1;
- }
-
- return CTempl_DeduceTemplateArgs(args1, TYPE_TEMPLATE(type2)->u.templ.args, argArray);
- }
-
- if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_QUALTEMPL) {
- return
- CTempl_DeduceTypeTemplDep(type1, 0, TYPE(TYPE_TEMPLATE(type2)->u.qualtempl.type), 0, argArray, 1) &&
- CTempl_DeduceTemplateArgs(args1, TYPE_TEMPLATE(type2)->u.qualtempl.args, argArray);
- }
- }
- }
-
- return 0;
-}
-
-static Boolean CTempl_DeduceTypeTemplDep(TypeTemplDep *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag) {
- Type *tmptype;
- UInt32 tmpqual;
- short index;
- Boolean f;
- UInt32 modqual;
-
- switch (type1->dtype) {
- case TEMPLDEP_ARGUMENT:
- index = type1->u.pid.index;
- tmptype = type2;
- if (type1->u.pid.type == TPT_TEMPLATE) {
- if (argArray[index].is_deduced) {
- if (!is_typesame(tmptype, argArray[index].data.ttargtype))
- return 0;
- } else {
- argArray[index].data.ttargtype = type2;
- argArray[index].pid.type = TPT_TEMPLATE;
- argArray[index].is_deduced = 1;
- }
- return 1;
- }
-
- switch (type2->type) {
- case TYPEPOINTER:
- tmpqual = qual2;
- f = 0;
- qual2 = TPTR_QUAL(type2);
- modqual = qual2;
-
- if ((modqual & Q_CONST) && (qual1 & Q_CONST)) {
- modqual &= ~Q_CONST;
- f = 1;
- }
- if ((modqual & Q_VOLATILE) && (qual1 & Q_VOLATILE)) {
- modqual &= ~Q_VOLATILE;
- f = 1;
- }
-
- if (f) {
- tmptype = galloc(sizeof(TypePointer));
- *TYPE_POINTER(tmptype) = *TYPE_POINTER(type2);
- TPTR_QUAL(tmptype) = modqual;
- }
-
- if (flag && (qual2 | modqual) != (qual1 | modqual))
- return 0;
-
- break;
-
- case TYPEMEMBERPOINTER:
- tmpqual = qual2;
- f = 0;
- qual2 = TYPE_MEMBER_POINTER(type2)->qual;
- modqual = qual2;
-
- if ((modqual & Q_CONST) && (qual1 & Q_CONST)) {
- modqual &= ~Q_CONST;
- f = 1;
- }
- if ((modqual & Q_VOLATILE) && (qual1 & Q_VOLATILE)) {
- modqual &= ~Q_VOLATILE;
- f = 1;
- }
-
- if (f) {
- tmptype = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(tmptype) = *TYPE_MEMBER_POINTER(type2);
- TYPE_MEMBER_POINTER(tmptype)->qual = modqual;
- }
-
- if (flag && (qual2 | modqual) != (qual1 | modqual))
- return 0;
-
- break;
-
- default:
- tmpqual = 0;
- if ((qual2 & Q_CONST) && !(qual1 & Q_CONST))
- tmpqual |= Q_CONST;
- if ((qual2 & Q_VOLATILE) && !(qual1 & Q_VOLATILE))
- tmpqual |= Q_VOLATILE;
-
- if (flag && (qual2 | tmpqual) != (qual1 | tmpqual))
- return 0;
- }
-
- if (argArray[index].is_deduced) {
- if (!is_typesame(tmptype, argArray[index].data.typeparam.type) || tmpqual != argArray[index].data.typeparam.qual)
- return 0;
- } else {
- argArray[index].data.typeparam.type = tmptype;
- argArray[index].data.typeparam.qual = tmpqual;
- argArray[index].pid.type = TPT_TYPE;
- argArray[index].is_deduced = 1;
- }
- return 1;
-
- case TEMPLDEP_QUALNAME:
- return 1;
-
- case TEMPLDEP_TEMPLATE:
- if (IS_TYPE_CLASS(type2))
- return CTempl_DeduceTemplateTypeBase(
- type1->u.templ.templ, type1->u.templ.args,
- TEMPL_CLASS_INST(type2), argArray, 0);
-
- if (IS_TYPE_TEMPLATE(type2) && TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_TEMPLATE)
- return CTempl_DeduceTemplDepTemplate(
- TYPE_TEMPLATE(type2)->u.templ.templ, TYPE_TEMPLATE(type2)->u.templ.args,
- type1->u.templ.templ, type1->u.templ.args,
- argArray
- );
-
- return 0;
-
- case TEMPLDEP_ARRAY:
- if (IS_TYPE_ARRAY(type2)) {
- SInt32 elements;
-
- if (!CTempl_DeduceType1(type1->u.array.type, qual1, TPTR_TARGET(type2), qual2, argArray, flag))
- return 0;
-
- if (ENODE_IS(type1->u.array.index, EINTCONST)) {
- CError_ASSERT(961, TPTR_TARGET(type2)->size);
- return (type2->size / TPTR_TARGET(type2)->size) == CInt64_GetULong(&type1->u.array.index->data.intval);
- }
-
- if (!ENODE_IS(type1->u.array.index, ETEMPLDEP) || type1->u.array.index->data.templdep.subtype != TDE_PARAM)
- return 1;
-
- CError_ASSERT(970, TPTR_TARGET(type2)->size);
-
- elements = type2->size / TPTR_TARGET(type2)->size;
- index = type1->u.array.index->data.templdep.u.pid.index;
- if (argArray[index].is_deduced) {
- CError_ASSERT(976, ENODE_IS(argArray[index].data.paramdecl.expr, EINTCONST));
- return elements == CInt64_GetULong(&argArray[index].data.paramdecl.expr->data.intval);
- } else {
- argArray[index].data.paramdecl.expr = intconstnode(CABI_GetPtrDiffTType(), elements);
- argArray[index].pid.type = TPT_NONTYPE;
- argArray[index].is_deduced = 1;
- return 1;
- }
- } else if (IS_TYPE_TEMPLATE(type2) && TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_ARRAY) {
- if (!CTempl_DeduceType1(type1->u.array.type, qual1, TYPE_TEMPLATE(type2)->u.array.type, qual2, argArray, flag))
- return 0;
-
- if (ENODE_IS(type1->u.array.index, EINTCONST)) {
- return ENODE_IS(TYPE_TEMPLATE(type2)->u.array.index, EINTCONST) &&
- CInt64_Equal(type1->u.array.index->data.intval, TYPE_TEMPLATE(type2)->u.array.index->data.intval);
- }
-
- if (!ENODE_IS(type1->u.array.index, ETEMPLDEP) || type1->u.array.index->data.templdep.subtype != TDE_PARAM)
- return 1;
-
- index = type1->u.array.index->data.templdep.u.pid.index;
- if (argArray[index].is_deduced) {
- return CTemplTool_EqualExprTypes(TYPE_TEMPLATE(type2)->u.array.index, argArray[index].data.paramdecl.expr);
- } else {
- argArray[index].data.paramdecl.expr = TYPE_TEMPLATE(type2)->u.array.index;
- argArray[index].pid.type = TPT_NONTYPE;
- argArray[index].is_deduced = 1;
- return 1;
- }
- }
-
- return 0;
-
- case TEMPLDEP_QUALTEMPL:
- return CTempl_DeduceQualTemplate(type1->u.qualtempl.type, type1->u.qualtempl.args, type2, argArray);
-
- case TEMPLDEP_BITFIELD:
- default:
- CError_FATAL(1022);
- return 1;
- }
-}
-
-static Boolean CTempl_DeduceFuncType(TypeFunc *tfunc1, TypeFunc *tfunc2, TemplArg *argArray) {
- FuncArg *arg1;
- FuncArg *arg2;
- Type *type2;
- Type *type1;
- UInt32 qual2;
- UInt32 qual1;
-
- arg1 = tfunc1->args;
- arg2 = tfunc2->args;
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(tfunc1) && !IS_TYPEFUNC_METHOD(tfunc2)) {
- CError_ASSERT(1045, arg1);
- arg1 = arg1->next;
- }
-
- while (1) {
- if (arg1 == NULL)
- return !arg2;
- if (arg1 == &oldstyle)
- return arg2 == &oldstyle;
- if (arg1 == &elipsis)
- return arg2 == &elipsis;
-
- if (arg2 == NULL || arg2 == &oldstyle || arg2 == &elipsis)
- return 0;
-
- qual2 = arg2->qual;
- type2 = CParser_RemoveTopMostQualifiers(arg2->type, &qual2);
-
- qual1 = arg1->qual;
- type1 = CParser_RemoveTopMostQualifiers(arg1->type, &qual1);
-
- if (!CTempl_DeduceType1(type1, qual1, type2, qual2, argArray, 1))
- return 0;
-
- arg1 = arg1->next;
- arg2 = arg2->next;
- }
-}
-
-static Boolean CTempl_DeduceType1(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag) {
- while (1) {
- switch (type1->type) {
- case TYPETEMPLATE:
- return CTempl_DeduceTypeTemplDep(TYPE_TEMPLATE(type1), qual1, type2, qual2, argArray, flag);
-
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- case TYPECLASS:
- return type1 == type2;
-
- case TYPEMEMBERPOINTER:
- if (type1->type != type2->type || TYPE_MEMBER_POINTER(type1)->qual != TYPE_MEMBER_POINTER(type2)->qual)
- return 0;
- if (!CTempl_DeduceType1(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray, flag))
- return 0;
- type1 = TYPE_MEMBER_POINTER(type1)->ty2;
- type2 = TYPE_MEMBER_POINTER(type2)->ty2;
- continue;
-
- case TYPEARRAY:
- if (type2->type != TYPEARRAY)
- return 0;
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- continue;
-
- case TYPEPOINTER:
- if (type2->type != TYPEPOINTER || TPTR_QUAL(type1) != TPTR_QUAL(type2))
- return 0;
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- continue;
-
- case TYPEFUNC:
- if (type1->type != type2->type)
- return 0;
-
- if (CTempl_DeduceType1(TYPE_FUNC(type1)->functype, TYPE_FUNC(type1)->qual, TYPE_FUNC(type2)->functype, TYPE_FUNC(type2)->qual, argArray, flag))
- return CTempl_DeduceFuncType(TYPE_FUNC(type1), TYPE_FUNC(type2), argArray);
-
- return 0;
-
- default:
- CError_FATAL(1124);
- }
- }
-}
-
-static Boolean CTempl_DeduceType2(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) {
- while (1) {
- switch (type1->type) {
- case TYPEPOINTER:
- if (type2->type != TYPEPOINTER)
- return 0;
- if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type2), TPTR_QUAL(type1)))
- return 0;
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- continue;
-
- case TYPEMEMBERPOINTER:
- if (type2->type != TYPEMEMBERPOINTER)
- return 0;
- if (!CParser_IsSameOrMoreCVQualified(TYPE_MEMBER_POINTER(type2)->qual, TYPE_MEMBER_POINTER(type1)->qual))
- return 0;
- if (!CTempl_DeduceType2(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray))
- return 0;
- type1 = TYPE_MEMBER_POINTER(type1)->ty2;
- type2 = TYPE_MEMBER_POINTER(type2)->ty2;
- continue;
-
- default:
- if (CParser_IsSameOrMoreCVQualified(qual2, qual1))
- return CTempl_DeduceType1(type1, qual2, type2, qual2, argArray, 0);
- return 0;
- }
- }
-}
-
-static Boolean CTempl_DeduceType3(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) {
- Boolean flag = 0;
-
- while (1) {
- switch (type1->type) {
- case TYPEPOINTER:
- flag = 1;
- if (type2->type != TYPEPOINTER)
- return 0;
- if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type2), TPTR_QUAL(type1)))
- return 0;
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- continue;
-
- case TYPEMEMBERPOINTER:
- flag = 1;
- if (type2->type != TYPEMEMBERPOINTER)
- return 0;
- if (!CParser_IsSameOrMoreCVQualified(TYPE_MEMBER_POINTER(type2)->qual, TYPE_MEMBER_POINTER(type1)->qual))
- return 0;
- if (!CTempl_DeduceType2(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray))
- return 0;
- type1 = TYPE_MEMBER_POINTER(type1)->ty2;
- type2 = TYPE_MEMBER_POINTER(type2)->ty2;
- continue;
-
- default:
- if (!flag)
- return 0;
- if (CParser_IsSameOrMoreCVQualified(qual2, qual1))
- return CTempl_DeduceType1(type1, qual2, type2, qual2, argArray, 0);
- return 0;
- }
- }
-}
-
-static Boolean CTempl_DeduceType4(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) {
- if (IS_TYPE_POINTER_ONLY(type1)) {
- if (!IS_TYPE_POINTER_ONLY(type2))
- return 0;
-
- if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type1), TPTR_QUAL(type2)))
- return 0;
-
- type1 = TPTR_TARGET(type1);
- type2 = TPTR_TARGET(type2);
- }
-
- if (IS_TYPE_TEMPLATE(type1) && TYPE_TEMPLATE(type1)->dtype == TEMPLDEP_TEMPLATE && IS_TYPE_CLASS(type2)) {
- if (CParser_IsSameOrMoreCVQualified(qual1, qual2))
- return CTempl_DeduceTemplateTypeBase(
- TYPE_TEMPLATE(type1)->u.templ.templ,
- TYPE_TEMPLATE(type1)->u.templ.args,
- TEMPL_CLASS_INST(type2),
- argArray,
- 1);
- else
- return 0;
- }
-
- return 0;
-}
-
-Boolean CTempl_DeduceType(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag1, Boolean flag2) {
- Boolean flag31;
- Boolean flag8;
-
- flag31 = 0;
- flag8 = 1;
-
- if (flag1 || flag2) {
- if (IS_TYPE_REFERENCE(type1)) {
- type1 = TPTR_TARGET(type1);
- flag31 = 1;
- } else {
- switch (type2->type) {
- case TYPEFUNC:
- type2 = CDecl_NewPointerType(type2);
- break;
- case TYPEARRAY:
- type2 = CDecl_NewPointerType(TPTR_TARGET(type2));
- break;
- }
-
- type1 = CParser_RemoveTopMostQualifiers(type1, &qual1);
- type2 = CParser_RemoveTopMostQualifiers(type2, &qual2);
- }
- flag8 = 0;
- }
-
- if (CTempl_DeduceType1(type1, qual1, type2, qual2, argArray, flag8))
- return 1;
-
- if (flag1 || flag2) {
- if (flag31 && CTempl_DeduceType2(type1, qual1, type2, qual2, argArray))
- return 1;
- if (CTempl_DeduceType3(type1, qual1, type2, qual2, argArray))
- return 1;
- if (flag1 && CTempl_DeduceType4(type1, qual1, type2, qual2, argArray))
- return 1;
- }
-
- return 0;
-}
-
-static Boolean CTempl_TypeNeedsDeduction(Type *type) {
- FuncArg *arg;
- Boolean result;
-
- while (1) {
- switch (type->type) {
- case TYPETEMPLATE:
- switch (TYPE_TEMPLATE(type)->dtype) {
- case TEMPLDEP_ARGUMENT:
- if (
- TYPE_TEMPLATE(type)->u.pid.index >= ctempl_explicitargs_num ||
- TYPE_TEMPLATE(type)->u.pid.nindex != ctempl_explicitargs_nindex
- )
- ctempl_explicitargs_all = 0;
- return 1;
-
- case TEMPLDEP_QUALNAME:
- CTempl_TypeNeedsDeduction(TYPE(TYPE_TEMPLATE(type)->u.qual.type));
- return 1;
-
- case TEMPLDEP_TEMPLATE:
- ctempl_explicitargs_all = 0;
- return 1;
-
- case TEMPLDEP_ARRAY:
- CTempl_TypeNeedsDeduction(TYPE_TEMPLATE(type)->u.array.type);
- ctempl_explicitargs_all = 0;
- return 1;
-
- case TEMPLDEP_QUALTEMPL:
- CTempl_TypeNeedsDeduction(TYPE(TYPE_TEMPLATE(type)->u.qualtempl.type));
- ctempl_explicitargs_all = 0;
- return 1;
-
- case TEMPLDEP_BITFIELD:
- default:
- CError_FATAL(1357);
- }
-
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- case TYPECLASS:
- return 0;
-
- case TYPEMEMBERPOINTER:
- result = 0;
- if (CTempl_TypeNeedsDeduction(TYPE_MEMBER_POINTER(type)->ty1))
- result = 1;
- if (CTempl_TypeNeedsDeduction(TYPE_MEMBER_POINTER(type)->ty2))
- result = 1;
- return result;
-
- case TYPEPOINTER:
- case TYPEARRAY:
- type = TPTR_TARGET(type);
- continue;
-
- case TYPEFUNC:
- result = 0;
- for (arg = TYPE_FUNC(type)->args; arg && arg != &elipsis; arg = arg->next) {
- if (CTempl_TypeNeedsDeduction(arg->type))
- result = 1;
- }
-
- if (CTempl_TypeNeedsDeduction(TYPE_FUNC(type)->functype))
- result = 1;
- return result;
-
- default:
- CError_FATAL(1389);
- }
- }
-}
-
-static Boolean CTempl_MatchTemplFunc(Object *object, DeduceInfo *info, FuncArg *args, ENodeList *exprs, Match13 *match13ptr) {
- Match13 match13;
- int i;
-
- memclrw(&match13, sizeof(match13));
-
- while (1) {
- if (!args || args->type == &stvoid) {
- if (!exprs)
- break;
- return 0;
- }
-
- if (args == &elipsis)
- break;
- if (args == &oldstyle)
- break;
-
- if (!exprs) {
- if (args->dexpr)
- break;
- return 0;
- }
-
- ctempl_explicitargs_nindex = info->x12C;
- ctempl_explicitargs_num = info->count;
- ctempl_explicitargs_all = 1;
-
- if (CTempl_TypeNeedsDeduction(args->type)) {
- if (!ctempl_explicitargs_all) {
- UInt32 cv2;
- UInt32 cv1;
- Type *type2;
- Type *type1;
- UInt32 qual2;
- UInt32 qual1;
-
- type1 = args->type;
- qual1 = args->qual & (Q_CONST | Q_VOLATILE);
-
- type2 = exprs->node->rtype;
- qual2 = ENODE_QUALS(exprs->node);
-
- if (IS_TYPE_REFERENCE(type1)) {
- type1 = TPTR_TARGET(type1);
- cv1 = CParser_GetCVTypeQualifiers(type1, qual1);
- cv2 = CParser_GetCVTypeQualifiers(type2, qual2);
- if (
- (!(cv1 & Q_CONST) && (cv2 & Q_CONST)) ||
- (!(cv1 & Q_VOLATILE) && (cv2 & Q_VOLATILE))
- )
- return 0;
-
- if (!(cv1 & Q_CONST) && !CExpr_IsLValue(exprs->node))
- return 0;
- }
-
- type1 = CParser_RemoveTopMostQualifiers(type1, &qual1);
- type2 = CParser_RemoveTopMostQualifiers(type2, &qual2);
-
- if (ENODE_IS(exprs->node, EOBJREF) && IS_TEMPL_FUNC(exprs->node->data.objref->type))
- return 0;
-
- if (ENODE_IS(exprs->node, EOBJLIST)) {
- NameSpaceObjectList *list;
-
- for (list = exprs->node->data.objlist.list; list; list = list->next) {
- if (list->object->otype == OT_OBJECT && IS_TEMPL_FUNC(OBJECT(list->object)->type))
- break;
- }
-
- if (list)
- return 0;
-
- if (IS_TYPE_FUNC(type2))
- type2 = CDecl_NewPointerType(type2);
- }
-
- ctempl_conversion_deduction = 0;
- if (!CTempl_DeduceType(type1, qual1, type2, qual2, info->args, 1, 0))
- return 0;
-
- if (ctempl_conversion_deduction)
- match13.anotherm5.x4++;
- else
- match13.anotherm5.x0++;
-
- if (IS_TYPE_POINTER_ONLY(args->type))
- CExpr_MatchCV(type2, qual2, args->type, args->qual, &match13);
-
- } else {
- Type *type;
- UInt32 qual;
-
- type = CTempl_GetSpecifiedType(CTemplTool_GetFuncTempl(object), args->type, args->qual, info->args, &qual);
- if (type && !CExpr_MatchAssign(type, qual, exprs->node, &match13))
- return 0;
- }
- } else {
- if (copts.old_argmatch && !CExpr_MatchAssign(args->type, args->qual, exprs->node, &match13))
- return 0;
- }
-
- exprs = exprs->next;
- args = args->next;
- }
-
- for (i = 0; i < info->maxCount; i++) {
- if (!info->args[i].is_deduced)
- return 0;
- info->args[i].next = &info->args[i + 1];
- }
- info->args[info->maxCount].next = NULL;
-
- return CExpr_MatchCompare(object, match13ptr, &match13);
-}
-
-void CTempl_FuncMatch(NameSpaceObjectList *list, TemplArg *args, ENodeList *argexprs, Match13 *match13ptr, ENode *expr) {
- Object *obj;
- Object *success;
- Object *object1;
- FuncMatchArgs funcMatchArgs;
- DeduceInfo info;
- DeduceInfo info2;
-
- object1 = match13ptr->obj;
- success = NULL;
- while (list) {
- obj = OBJECT(list->object);
- if (
- obj->otype == OT_OBJECT &&
- IS_TEMPL_FUNC(obj->type) &&
- CExpr_GetFuncMatchArgs(obj, argexprs, expr, &funcMatchArgs) &&
- CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(obj)->params, args, 0) &&
- CTempl_MatchTemplFunc(obj, &info, funcMatchArgs.args, funcMatchArgs.exprs, match13ptr)
- )
- {
- info2 = info;
- if (info.args == info.argBuffer)
- info2.args = info2.argBuffer;
- success = obj;
- }
- list = list->next;
- }
-
- if (success) {
- if (match13ptr->list) {
- ENodeList *argexpr = argexprs;
- int argexprcount = 0;
- while (argexpr) {
- argexpr = argexpr->next;
- argexprcount++;
- }
-
- obj = CTempl_PartialOrdering(match13ptr->obj, match13ptr->list, argexprcount);
- if (!obj) {
- CError_OverloadedFunctionError(match13ptr->obj, match13ptr->list);
- match13ptr->list = NULL;
- if (object1)
- match13ptr->obj = object1;
- else
- match13ptr->obj = CTempl_GetCreateFuncInstance(success, info2.args, NULL)->object;
- } else {
- NameSpaceObjectList mylist;
- mylist.next = NULL;
- mylist.object = OBJ_BASE(obj);
- memclrw(match13ptr, sizeof(Match13));
- CTempl_FuncMatch(&mylist, args, argexprs, match13ptr, expr);
- }
- } else {
- match13ptr->obj = CTempl_GetCreateFuncInstance(success, info2.args, NULL)->object;
- }
- } else {
- match13ptr->obj = object1;
- }
-}
-
-static Boolean CExpr_DeduceFromObjList(FuncArg *arg, NameSpaceObjectList *list, DeduceInfo *info) {
- TemplArg *savebuf;
- NameSpaceObjectList *scan;
- SInt32 size;
-
- for (scan = list; scan; scan = scan->next) {
- if (scan->object->otype == OT_OBJECT && IS_TEMPL_FUNC(OBJECT(scan->object)->type))
- return 0;
- }
-
- size = sizeof(TemplArg) * info->maxCount;
- savebuf = lalloc(size);
-
- for (scan = list; scan; scan = scan->next) {
- if (scan->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(scan->object)->type)) {
- Object *obj;
-
- memcpy(savebuf, info->args, size);
-
- obj = OBJECT(scan->object);
- if (CTempl_DeduceType(
- arg->type, arg->qual & (Q_CONST | Q_VOLATILE),
- obj->type, obj->qual,
- savebuf, 1, 0
- ))
- {
- memcpy(info->args, savebuf, size);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-Object *CTempl_DeduceFromFunctionCall(Object *funcobj, TemplArg *templargs, ENodeList *argexprs) {
- DeduceInfo info;
- FuncArg *arg;
- int i;
-
- CError_ASSERT(1655, IS_TEMPL_FUNC(funcobj->type));
-
- if (CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(funcobj)->params, templargs, 0)) {
- arg = TYPE_FUNC(funcobj->type)->args;
- if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(funcobj->type))) {
- CError_ASSERT(1664, arg);
- arg = arg->next;
- }
-
- while (1) {
- if (!arg || arg->type == &stvoid) {
- if (argexprs)
- return NULL;
- break;
- }
-
- if (arg == &elipsis)
- break;
- if (arg == &oldstyle)
- break;
-
- if (!argexprs) {
- if (arg->dexpr)
- break;
- return NULL;
- }
-
- ctempl_explicitargs_nindex = info.x12C;
- ctempl_explicitargs_num = info.count;
- ctempl_explicitargs_all = 1;
-
- if (CTempl_TypeNeedsDeduction(arg->type) && !ctempl_explicitargs_all) {
- ENode *node = argexprs->node;
-
- if (ENODE_IS(node, EOBJREF) && IS_TEMPL_FUNC(node->data.objref->type))
- return NULL;
-
- if (ENODE_IS(node, EOBJLIST)) {
- if (!CExpr_DeduceFromObjList(arg, node->data.objlist.list, &info))
- return NULL;
- } else {
- if (!CTempl_DeduceType(
- arg->type, arg->qual & (Q_CONST | Q_VOLATILE),
- node->rtype, ENODE_QUALS(node),
- info.args, 1, 0))
- return NULL;
- }
- }
-
- argexprs = argexprs->next;
- arg = arg->next;
- }
-
- for (i = 0; i < info.maxCount; i++) {
- if (!info.args[i].is_deduced)
- return 0;
- info.args[i].next = &info.args[i + 1];
- }
- info.args[info.maxCount].next = NULL;
-
- return CTempl_GetCreateFuncInstance(funcobj, info.args, NULL)->object;
- } else {
- return NULL;
- }
-}
-
-Object *CTempl_DeduceFromConversion(Object *funcobj, Type *type, UInt32 qual) {
- DeduceInfo info;
- int i;
-
- CError_ASSERT(1745, IS_TEMPL_FUNC(funcobj->type));
-
- if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(funcobj)->params, NULL, 0))
- return NULL;
-
- ctempl_explicitargs_nindex = info.x12C;
- ctempl_explicitargs_num = info.count;
- ctempl_explicitargs_all = 1;
-
- if (!CTempl_TypeNeedsDeduction(TYPE_FUNC(funcobj->type)->functype))
- return NULL;
-
- if (!CTempl_DeduceType(TYPE_FUNC(funcobj->type)->functype, TYPE_FUNC(funcobj->type)->qual, type, qual, info.args, 0, 1))
- return NULL;
-
- for (i = 0; i < info.maxCount; i++) {
- if (!info.args[i].is_deduced)
- return 0;
- info.args[i].next = &info.args[i + 1];
- }
- info.args[info.maxCount].next = NULL;
-
- return CTempl_GetCreateFuncInstance(funcobj, info.args, NULL)->object;
-}
-
-static int CTemplFunc_TemplateNestLevel(NameSpace *nspace) {
- int level = 0;
-
- while (nspace) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_ANY))
- level++;
- nspace = nspace->parent;
- }
-
- return level;
-}
-
-static Boolean CTemplFunc_SameFuncType(TypeFunc *a, TypeFunc *b) {
- FuncArg *arg1;
- FuncArg *arg2;
-
- CError_ASSERT(1800, IS_TYPE_FUNC(a) && IS_TYPE_FUNC(b));
-
- if (!is_typesame(a->functype, b->functype))
- return 0;
-
- if (a->qual != b->qual)
- return 0;
-
- if ((a->flags & FUNC_CALL_CONV_MASK) != (b->flags & FUNC_CALL_CONV_MASK))
- return 0;
-
- arg1 = a->args;
- if ((a->flags & FUNC_METHOD) && !TYPE_METHOD(a)->is_static) {
- CError_ASSERT(1808, arg1);
- arg1 = arg1->next;
- }
-
- arg2 = b->args;
- if ((b->flags & FUNC_METHOD) && !TYPE_METHOD(b)->is_static) {
- CError_ASSERT(1814, arg2);
- arg2 = arg2->next;
- }
-
- return is_arglistsame(arg1, arg2);
-}
-
-Object *CTempl_TemplateFunctionCheck(DeclInfo *di, NameSpaceObjectList *nsol) {
- TemplArg *arg;
- TemplFuncInstance *inst;
- Object *object;
-
- for (arg = di->expltargs; arg; arg = arg->next) {
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- break;
- continue;
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- break;
- continue;
- default:
- CError_FATAL(1844);
- }
-
- break;
- }
-
- if (arg) {
- while (nsol) {
- object = OBJECT(nsol->object);
- if (
- object->otype == OT_OBJECT &&
- IS_TEMPL_FUNC(object->type) &&
- CTemplTool_IsSameTemplate(CTemplTool_GetFuncTempl(object)->params, di->expltargs) &&
- CTemplFunc_SameFuncType(TYPE_FUNC(OBJECT(nsol->object)->type), TYPE_FUNC(di->thetype))
- )
- return OBJECT(nsol->object);
-
- nsol = nsol->next;
- }
- } else {
- while (nsol) {
- object = OBJECT(nsol->object);
- if (
- object->otype == OT_OBJECT &&
- IS_TEMPL_FUNC(object->type) &&
- (inst = CTempl_DeduceFunc(object, TYPE_FUNC(di->thetype), di->expltargs, NULL, 1))
- )
- {
- if (di->x3C) {
- if (!(di->qual & Q_INLINE)) {
- if (!inst->is_specialized)
- inst->object->qual &= ~Q_INLINE;
- } else {
- inst->object->qual |= Q_INLINE;
- }
-
- if (!inst->is_specialized && inst->is_instantiated)
- CError_Error(CErrorStr335);
-
- if (di->x3C != (CTemplFunc_TemplateNestLevel(inst->object->nspace) + 1))
- CError_Warning(CErrorStr335);
-
- inst->is_specialized = 1;
- di->x3C = 0;
- }
-
- CTemplTool_MergeArgNames(TYPE_FUNC(di->thetype), TYPE_FUNC(inst->object->type));
- di->x38 = CTemplTool_GetFuncTempl(OBJECT(nsol->object));
- return inst->object;
- }
- nsol = nsol->next;
- }
- }
-
- CError_ResetErrorSkip();
- CError_Error(CErrorStr335);
- di->x3C = 0;
- return NULL;
-}
diff --git a/compiler_and_linker/unsorted/CTemplateNew.c b/compiler_and_linker/unsorted/CTemplateNew.c
deleted file mode 100644
index c33534a..0000000
--- a/compiler_and_linker/unsorted/CTemplateNew.c
+++ /dev/null
@@ -1,1880 +0,0 @@
-#include "compiler/CTemplateNew.h"
-#include "compiler/CBrowse.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/CTemplateClass.h"
-#include "compiler/CTemplateTools.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-
-TemplClass *ctempl_templates;
-TemplateFunction *ctempl_templatefuncs;
-TemplStack *ctempl_curinstance;
-static jmp_buf ctempl_parseparse;
-static Boolean ctempl_scanfuncparams;
-
-// forward decls
-static TemplParam *CTempl_ParseParamList(NameSpace *nspace, UInt8 nindex);
-static Boolean CTempl_GenClassInstance(TemplClassInst *inst, Boolean flag);
-
-void CTempl_Setup(void) {
- ctempl_curinstance = NULL;
- ctempl_templates = NULL;
- ctempl_templatefuncs = NULL;
- ctempl_instdepth = 0;
- ctempl_scanfuncparams = 0;
-}
-
-void CTempl_Cleanup(void) {
-}
-
-static short CTempl_MemberParseLex(void) {
- switch ((tk = lex())) {
- case ';':
- case '=':
- case '{':
- case '}':
- longjmp(ctempl_parseparse, 1);
- }
-
- return tk;
-}
-
-static void CTempl_MemberParseTemplArgList(void) {
- struct {
- char ch;
- char flag;
- } stack[256];
- int pos;
-
- stack[0].ch = '>';
- stack[0].flag = 1;
- pos = 0;
- while (1) {
- switch (CTempl_MemberParseLex()) {
- case '<':
- if (stack[pos].flag) {
- if (pos >= 255)
- longjmp(ctempl_parseparse, 1);
- stack[++pos].ch = '>';
- stack[pos].flag = 1;
- }
- continue;
- case '(':
- if (pos >= 255)
- longjmp(ctempl_parseparse, 1);
- stack[++pos].ch = ')';
- stack[pos].flag = 0;
- continue;
- case '[':
- if (pos >= 255)
- longjmp(ctempl_parseparse, 1);
- stack[++pos].ch = ']';
- stack[pos].flag = 0;
- continue;
- case '>':
- if (!(stack[pos].flag))
- continue;
- case ')':
- case ']':
- break;
- default:
- continue;
- }
-
- if (tk != stack[pos].ch)
- longjmp(ctempl_parseparse, 1);
- if (--pos < 0)
- break;
- }
-}
-
-static Type *CTempl_MemberParseTempl(HashNameNode *name) {
- Type *type;
-
- type = CScope_GetTagType(cscope_current, name);
- if (!type || !IS_TEMPL_CLASS(type))
- longjmp(ctempl_parseparse, 1);
-
- CTempl_MemberParseTemplArgList();
- if (lookahead() != TK_COLON_COLON)
- return NULL;
- CTempl_MemberParseLex();
-
- while (1) {
- switch (CTempl_MemberParseLex()) {
- case TK_IDENTIFIER:
- switch (lookahead()) {
- case '(':
- case ')':
- case ';':
- case '=':
- case '[':
- return type;
- case TK_COLON_COLON:
- CTempl_MemberParseLex();
- continue;
- default:
- return NULL;
- }
- break;
- case '~':
- case TK_OPERATOR:
- return type;
- default:
- return NULL;
- }
- }
-}
-
-static Boolean CTempl_ParseTemplateMember(void) {
- HashNameNode *name;
- SInt32 state;
-
- CPrep_UnLex();
- CPrep_TokenStreamGetState(&state);
-
- if (setjmp(ctempl_parseparse) == 0) {
- while (1) {
- switch (CTempl_MemberParseLex()) {
- case TK_IDENTIFIER:
- name = tkidentifier;
- switch (lookahead()) {
- case '<':
- CTempl_MemberParseLex();
- if (CTempl_MemberParseTempl(name)) {
- CError_FATAL(228);
- return 1;
- }
- break;
- case TK_COLON_COLON:
- CTempl_MemberParseLex();
- while (1) {
- if (CTempl_MemberParseLex() != TK_IDENTIFIER)
- break;
- if (lookahead() != TK_COLON_COLON)
- break;
- CTempl_MemberParseLex();
- }
- break;
- }
- break;
- case 0:
- return 0;
- default:
- continue;
- }
- break;
- }
-
- while (1) {
- switch (CTempl_MemberParseLex()) {
- case TK_IDENTIFIER:
- name = tkidentifier;
- if (CTempl_MemberParseLex() == '<') {
- if (CTempl_MemberParseTempl(name)) {
- CError_FATAL(265);
- return 1;
- }
- }
- break;
- case 0:
- return 0;
- default:
- continue;
- }
- break;
- }
- }
-
- CPrep_TokenStreamSetState(&state);
- tk = lex();
- return 0;
-}
-
-static Type *CTempl_ParseTemplArgType(UInt32 *resultQual) {
- DeclInfo di;
-
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (di.storageclass)
- CError_Error(CErrorStr177);
- if (di.x48)
- CError_Error(CErrorStr121);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_REFERENCE | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
- if (di.name)
- CError_Error(CErrorStr121);
-
- CTemplTool_CheckTemplArgType(di.thetype);
-
- *resultQual = di.qual;
- return di.thetype;
-}
-
-static ENode *CTempl_ParseTemplArgExpr(Type *type, UInt32 qual) {
- ENode *expr;
- ENode *copy;
-
- disallowgreaterthan = 1;
- if (copts.old_argmatch)
- expr = conv_assignment_expression();
- else
- expr = assignment_expression();
- disallowgreaterthan = 0;
-
- if (type && !CTemplTool_IsTemplateArgumentDependentType(type) && !IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
- expr = argumentpromotion(expr, type, qual, 1);
- if (IS_TYPE_POINTER_ONLY(type)) {
- if (ENODE_IS(expr, ETYPCON) && ENODE_IS(expr->data.monadic, EINTCONST))
- expr = expr->data.monadic;
- if (ENODE_IS(expr, EINTCONST))
- expr->rtype = type;
- }
- }
-
- if (!IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
- if (!copts.old_argmatch)
- expr = pointer_generation(expr);
-
- switch (expr->type) {
- case EINTCONST:
- break;
- case EOBJREF:
- if (CParser_HasInternalLinkage2(expr->data.objref))
- CError_Error(CErrorStr357);
- break;
- case EOBJLIST:
- CError_Error(CErrorStr199);
- expr = nullnode();
- break;
- default:
- CError_Error(CErrorStr371);
- expr = nullnode();
- }
-
- copy = galloc(sizeof(ENode));
- *copy = *expr;
- return copy;
- } else {
- return CInline_CopyExpression(expr, CopyMode1);
- }
-}
-
-static Type *CTempl_ParseTemplArgTempl(TemplParam *params) {
- NameResult pr;
-
- if (
- (tk != TK_IDENTIFIER && tk != TK_COLON_COLON) ||
- !CScope_ParseDeclName(&pr) ||
- !pr.type
- )
- {
- CError_Error(CErrorStr121);
- tk = lex();
- return NULL;
- }
-
- if (IS_TEMPL_CLASS(pr.type)) {
- if (params && !CTemplTool_EqualParams(params->data.templparam.plist, TEMPL_CLASS(pr.type)->templ__params, 0)) {
- CError_Error(CErrorStr235);
- tk = lex();
- return NULL;
- }
- } else {
- if (!CTemplTool_IsTemplateArgumentDependentType(pr.type))
- CError_Error(CErrorStr146);
- }
-
- tk = lex();
- return pr.type;
-}
-
-static UInt8 CTempl_GetTemplateNestIndex(NameSpace *nspace) {
- UInt8 count = 0;
-
- while (nspace) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_ANY))
- count++;
- nspace = nspace->parent;
- }
-
- return count;
-}
-
-static TemplParam *CTempl_ParseParam(NameSpace *nspace, TemplParam *param, UInt16 index, UInt8 nindex) {
- DeclInfo di;
- SInt32 savedState;
- short startToken;
-
- param = galloc(sizeof(TemplParam));
- memclrw(param, sizeof(TemplParam));
-
- param->pid.index = index;
- param->pid.nindex = nindex;
-
- CPrep_TokenStreamGetState(&savedState);
-
- switch ((startToken = tk)) {
- case TK_CLASS:
- case TK_TYPENAME:
- if ((tk = lex()) == TK_IDENTIFIER) {
- param->name = tkidentifier;
- tk = lex();
- }
-
- switch (tk) {
- case ',':
- case '>':
- break;
- case '=':
- tk = lex();
- param->data.typeparam.type = CTempl_ParseTemplArgType(&param->data.typeparam.qual);
- break;
- default:
- param->name = NULL;
- CPrep_TokenStreamSetState(&savedState);
- tk = startToken;
- goto defaultProc;
- }
-
- param->pid.type = TPT_TYPE;
- break;
-
- case TK_TEMPLATE:
- if ((tk = lex()) != '<') {
- CError_Error(CErrorStr230);
- return NULL;
- }
-
- tk = lex();
- param->data.templparam.plist = CTempl_ParseParamList(nspace, 0);
-
- if (tk == '>')
- tk = lex();
- else
- CError_Error(CErrorStr231);
-
- if (tk == TK_CLASS)
- tk = lex();
- else
- CError_Error(CErrorStr121);
-
- if (tk == TK_IDENTIFIER) {
- param->name = tkidentifier;
- tk = lex();
- }
-
- if (tk == '=') {
- tk = lex();
- param->data.templparam.defaultarg = CTempl_ParseTemplArgTempl(param);
- }
-
- param->pid.type = TPT_TEMPLATE;
- break;
-
- default:
- defaultProc:
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
-
- if (di.storageclass)
- CError_Error(CErrorStr177);
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_REFERENCE | Q_ALIGNED_MASK));
-
- scandeclarator(&di);
-
- switch (di.thetype->type) {
- case TYPEARRAY:
- di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype));
- break;
- case TYPEFUNC:
- di.thetype = CDecl_NewPointerType(di.thetype);
- break;
- case TYPEMEMBERPOINTER:
- CError_Error(CErrorStr190);
- di.thetype = TYPE(&stsignedint);
- break;
- case TYPEINT:
- case TYPEENUM:
- case TYPETEMPLATE:
- case TYPEPOINTER:
- break;
- default:
- CError_Error(CErrorStr229);
- di.thetype = TYPE(&stsignedint);
- }
-
- di.thetype = CParser_RemoveTopMostQualifiers(di.thetype, &di.qual);
- param->name = di.name;
- param->data.paramdecl.type = di.thetype;
- param->data.paramdecl.qual = di.qual;
- if (tk == '=') {
- tk = lex();
- param->data.paramdecl.defaultarg = CTempl_ParseTemplArgExpr(di.thetype, di.qual);
- }
-
- param->pid.type = TPT_NONTYPE;
- break;
- }
-
- if (param->name)
- CTemplTool_InsertTemplateParameter(nspace, param);
-
- return param;
-}
-
-static TemplParam *CTempl_ParseParamList(NameSpace *nspace, UInt8 nindex) {
- TemplParam *params;
- TemplParam **ptr;
- TemplParam *param;
- TemplParam *scan;
- UInt16 index;
-
- params = NULL;
- index = 0;
- ptr = &params;
-
- while (1) {
- param = CTempl_ParseParam(nspace, params, index, nindex);
- if (!param)
- break;
-
- if (param->name) {
- for (scan = params; scan; scan = scan->next) {
- if (scan->name == param->name)
- CError_Error(CErrorStr122, param->name->name);
- }
- }
-
- *ptr = param;
- ptr = &param->next;
-
- if (tk != ',')
- break;
-
- tk = lex();
- index++;
- }
-
- if (!params)
- CError_Error(CErrorStr229);
-
- return params;
-}
-
-TemplArg *CTempl_ParseUncheckTemplArgs(TemplParam *params, Boolean is_global) {
- TemplArg *args;
- TemplArg *last;
- UInt16 index;
-
- if (tk != '<') {
- CError_Error(CErrorStr230);
- return NULL;
- }
-
- if ((tk = lex()) == '>')
- return NULL;
-
- args = NULL;
- index = 0;
- while (1) {
- if (is_global) {
- if (args) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- last = galloc(sizeof(TemplArg));
- args = last;
- }
- } else {
- if (args) {
- last->next = lalloc(sizeof(TemplArg));
- last = last->next;
- } else {
- last = galloc(sizeof(TemplArg));
- args = last;
- }
- }
-
- last->next = NULL;
-
- if (!params) {
- Type *type;
- UInt32 qual;
- Boolean flag;
-
- last->pid.index = index;
- last->pid.nindex = 0;
-
- if ((type = CParser_ParseTypeID(&qual, &flag))) {
- if (flag) {
- last->data.ttargtype = type;
- last->pid.type = TPT_TEMPLATE;
- } else {
- last->data.typeparam.type = type;
- last->data.typeparam.qual = qual;
- last->pid.type = TPT_TYPE;
- }
- } else {
- last->data.paramdecl.expr = CTempl_ParseTemplArgExpr(NULL, 0);
- last->pid.type = TPT_NONTYPE;
- }
- } else {
- last->pid = params->pid;
- switch (last->pid.type) {
- case TPT_TYPE:
- last->data.typeparam.type = CTempl_ParseTemplArgType(&last->data.typeparam.qual);
- break;
- case TPT_NONTYPE:
- last->data.paramdecl.expr = CTempl_ParseTemplArgExpr(NULL, 0);
- break;
- case TPT_TEMPLATE:
- if (!(last->data.ttargtype = CTempl_ParseTemplArgTempl(params)))
- return NULL;
- break;
- default:
- CError_FATAL(674);
- }
- params = params->next;
- }
-
- if (tk == '>')
- return args;
-
- if (tk != ',') {
- CError_Error(CErrorStr116);
- return NULL;
- }
-
- tk = lex();
- index++;
- }
-}
-
-static TemplArg *CTempl_ParseTemplArgs(TemplClass **resultTempl, TemplArg **resultArgs) {
- TemplParam *param;
- TemplParam *params;
- TemplArg *args;
- TemplArg **ptr;
- TemplArg *arg;
-
- params = (*resultTempl)->templ__params;
- *resultArgs = NULL;
-
- if (tk != '<') {
- CError_Error(CErrorStr230);
- return NULL;
- }
-
- tk = lex();
-
- param = params;
- args = NULL;
- ptr = &args;
-
- while (param) {
- arg = galloc(sizeof(TemplArg));
- memclrw(arg, sizeof(TemplArg));
-
- *ptr = arg;
- ptr = &arg->next;
-
- arg->pid = param->pid;
-
- if (tk != '>') {
- switch (arg->pid.type) {
- case TPT_TYPE:
- arg->data.typeparam.type = CTempl_ParseTemplArgType(&arg->data.typeparam.qual);
- break;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(param->data.paramdecl.type)) {
- Type *type;
- UInt32 qual;
-
- type = CTemplTool_DeduceArgDepType(args, param->data.paramdecl.type, param->data.paramdecl.qual, &qual);
- arg->data.paramdecl.expr = CTempl_ParseTemplArgExpr(type, qual);
- } else {
- arg->data.paramdecl.expr = CTempl_ParseTemplArgExpr(param->data.paramdecl.type, param->data.paramdecl.qual);
- }
- break;
-
- case TPT_TEMPLATE:
- if (!(arg->data.ttargtype = CTempl_ParseTemplArgTempl(param)))
- return NULL;
- break;
-
- default:
- CError_FATAL(742);
- }
-
- if (tk != '>') {
- if (tk != ',') {
- CError_Error(CErrorStr232);
- return NULL;
- }
-
- if ((tk = lex()) == '>') {
- CError_Error(CErrorStr232);
- return NULL;
- }
- }
- } else {
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (!param->data.typeparam.type) {
- CError_Error(CErrorStr232);
- return NULL;
- }
-
- arg->data.typeparam.type = param->data.typeparam.type;
- arg->data.typeparam.qual = param->data.typeparam.qual;
-
- if (CTemplTool_IsTemplateArgumentDependentType(param->data.typeparam.type)) {
- TypeDeduce deduce;
- memclrw(&deduce, sizeof(deduce));
- deduce.tmclass = *resultTempl;
- deduce.inst = NULL;
- deduce.params = params;
- deduce.args = args;
-
- arg->data.typeparam.qual = param->data.typeparam.qual;
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(&deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- }
- break;
-
- case TPT_NONTYPE:
- if (!param->data.paramdecl.defaultarg) {
- CError_Error(CErrorStr232);
- return NULL;
- }
-
- if (IS_TYPE_TEMPLDEPEXPR(param->data.paramdecl.defaultarg->rtype)) {
- TypeDeduce deduce;
- memclrw(&deduce, sizeof(deduce));
- deduce.tmclass = *resultTempl;
- deduce.inst = NULL;
- deduce.params = params;
- deduce.args = args;
-
- arg->data.paramdecl.expr = CInline_CopyExpression(
- CTemplTool_DeduceExpr(&deduce, param->data.paramdecl.defaultarg), CopyMode1);
- } else {
- arg->data.paramdecl.expr = param->data.paramdecl.defaultarg;
- }
- break;
-
- case TPT_TEMPLATE:
- if (!param->data.templparam.defaultarg) {
- CError_Error(CErrorStr232);
- return NULL;
- }
-
- if (IS_TEMPL_CLASS(param->data.templparam.defaultarg)) {
- arg->data.ttargtype = param->data.templparam.defaultarg;
- break;
- }
-
- if (CTemplTool_IsTemplateArgumentDependentType(param->data.templparam.defaultarg)) {
- CError_Error(CErrorStr190);
- return NULL;
- }
-
- CError_FATAL(817);
-
- default:
- CError_FATAL(820);
- }
- }
-
- param = param->next;
- }
-
- if (tk != '>') {
- CError_Error(CErrorStr231);
- return NULL;
- }
-
- if ((*resultTempl)->pspecs)
- return args;
-
- return args;
-}
-
-Type *CTempl_ParseTemplTemplParam(TypeTemplDep *type) {
- TemplArg *args;
- Type *newType;
-
- tk = lex();
- if (!(args = CTempl_ParseUncheckTemplArgs(NULL, 1))) {
- CError_Error(CErrorStr121);
- return TYPE(&stsignedint);
- }
-
- newType = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL);
- TYPE_TEMPLATE(newType)->u.qualtempl.type = type;
- TYPE_TEMPLATE(newType)->u.qualtempl.args = args;
- return newType;
-}
-
-Type *CTempl_ClassGetType(TemplClass *templ) {
- TemplClass *owner;
- TemplArg *ownerArgs;
- TemplArg *args;
- Type *type;
-
- owner = templ;
- if (templ->pspec_owner)
- owner = templ->pspec_owner;
-
- if (!(args = CTempl_ParseTemplArgs(&owner, &ownerArgs)))
- return &stvoid;
-
- if ((type = CTemplTool_IsDependentTemplate(owner, args)))
- return type;
-
- return TYPE(CTemplClass_GetInstance(owner, args, ownerArgs));
-}
-
-static void CTempl_SetupClassParamNameSpace(DeclFucker *what_is_this, TypeClass *tclass) {
- cscope_current = tclass->nspace;
-}
-
-Boolean CTempl_IsQualifiedMember(DeclInfo *di, Type *type, NameSpace **resultnspace) {
- if (
- TYPE_TEMPLATE(type)->dtype == TEMPLDEP_QUALNAME &&
- (type = CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(type)->u.qual.type)))
- )
- {
- *resultnspace = TYPE_CLASS(type)->nspace;
- CError_ASSERT(948, di->fucker34 && (*resultnspace)->theclass);
-
- CTempl_SetupClassParamNameSpace(di->fucker34, (*resultnspace)->theclass);
- di->fucker34 = NULL;
- return 1;
- }
-
- return 0;
-}
-
-static void *CTempl_ParseMemberFunction(int unk1, int unk2, int unk3, Object *func) {
- // no idea what should've been here, it's not called
-
- CError_ASSERT(974, TYPE_FUNC(func->type)->flags & FUNC_METHOD);
-
- return NULL;
-}
-
-static void CTempl_ParseMember(TemplParam *params, TemplClass *templ, DeclInfo *di, SInt32 *startOffset) {
- Object *object;
- NameSpaceObjectList *nsol;
- TokenStream stream;
- CPrepFileInfo *file;
- SInt32 offset;
- Boolean saveForceLoc;
- TemplateMember *member;
-
- if (templ->theclass.flags & CLASS_IS_TEMPL)
- di->thetype = CTemplTool_ResolveMemberSelfRefs(templ, di->thetype, &di->qual);
-
- if (IS_TYPE_FUNC(di->thetype)) {
- Boolean flag;
- if (!(object = CDecl_GetFunctionObject(di, NULL, &flag, 0))) {
- CError_Error(CErrorStr140, di->name->name);
- return;
- }
-
- if (tk != '{' && tk != TK_TRY && tk != ':') {
- if (tk != ';')
- CError_Error(CErrorStr123);
- else
- tk = lex();
- return;
- }
-
- if (
- (TYPE_FUNC(object->type)->flags & FUNC_DEFINED) &&
- (!(TYPE_FUNC(object->type)->flags & FUNC_IS_TEMPL) || object->u.func.u.templ->instances)
- )
- CError_Error(CErrorStr333, object);
-
- TYPE_FUNC(object->type)->flags |= FUNC_IS_TEMPL_INSTANCE | FUNC_DEFINED;
-
- CPrep_StreamGetBlock(&stream, NULL, 1);
- saveForceLoc = gForceSourceLoc;
- gForceSourceLoc = 1;
- CPrep_BrowserFilePosition(&file, &offset);
- gForceSourceLoc = saveForceLoc;
-
- if (file && file->recordbrowseinfo && *startOffset >= 0 && offset > *startOffset)
- CBrowse_NewFunction(object, file, file, *startOffset, offset + 1);
- } else {
- if (!(nsol = CScope_GetLocalObject(templ->theclass.nspace, di->name))) {
- CError_Error(CErrorStr140, di->name->name);
- return;
- }
-
- object = OBJECT(nsol->object);
- if (object->otype != OT_OBJECT) {
- CError_Error(CErrorStr122, di->name->name);
- return;
- }
-
- if (
- !is_typesame(di->thetype, object->type) ||
- (object->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL)) != (di->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL))
- )
- {
- CError_Error(CErrorStr249, CError_GetObjectName(object), object->type, object->qual, di->thetype, di->qual);
- return;
- }
-
- CError_ASSERT(1070, object->datatype == DDATA);
-
- CPrep_StreamGetSemicolon(&stream, NULL);
- }
-
- if (stream.tokens) {
- if (IS_TEMPL_FUNC(object->type) != 0) {
- if (!CTemplTool_EqualParams(object->u.func.u.templ->params, params, 0))
- CError_Error(CErrorStr235);
-
- object->u.func.u.templ->stream = stream;
- } else {
- if (!(templ->theclass.flags & CLASS_IS_TEMPL)) {
- CError_Error(CErrorStr190);
- return;
- }
-
- member = CTemplClass_DefineMember(templ, object, &cparser_fileoffset, &stream);
- if (templ->templ__params) {
- if (!CTemplTool_EqualParams(templ->templ__params, params, 0)) {
- CError_Error(CErrorStr235);
- return;
- }
-
- member->params = params;
- }
- }
- }
-}
-
-static TemplateFunction *CTempl_DeclareTemplateFunction(DeclInfo *di, TemplParam *params, TypeClass *tclass, AccessType access, Boolean flag) {
- TemplateFunction *templ;
- Object *object;
-
- if (tclass) {
- CError_ASSERT(1122, cscope_current->theclass);
- di->thetype = TYPE(CDecl_MakeTypeMemberFunc(TYPE_FUNC(di->thetype), cscope_current->theclass, flag));
- } else {
- access = ACCESSPUBLIC;
- }
-
- templ = galloc(sizeof(TemplateFunction));
- memclrw(templ, sizeof(TemplateFunction));
-
- templ->next = ctempl_templatefuncs;
- ctempl_templatefuncs = templ;
-
- templ->params = params;
- templ->name = di->name;
- templ->deftoken = symdecltoken;
-
- object = CParser_NewFunctionObject(NULL);
- object->access = access;
- object->name = di->name;
- object->u.func.linkname = CParser_GetUniqueName();
- object->type = di->thetype;
- object->qual = di->qual | Q_MANGLE_NAME;
- object->sclass = di->storageclass;
- TYPE_FUNC(object->type)->flags |= FUNC_IS_TEMPL;
- object->u.func.u.templ = templ;
-
- if (di->qual & Q_INLINE)
- object->sclass = TK_STATIC;
-
- templ->tfunc = object;
- CScope_AddObject(cscope_current, di->name, OBJ_BASE(object));
-
- return templ;
-}
-
-static void CTempl_ParseTemplateFunction(TemplateFunction *templ, TypeClass *tclass, SInt32 *startOffset) {
- Object *object;
- CPrepFileInfo *file;
- SInt32 offset;
- Boolean saveForceLoc;
-
- object = templ->tfunc;
-
- if (tk == '{' || tk == ':' || tk == TK_TRY) {
- if (tclass) {
- object->qual |= Q_INLINE;
- object->sclass = TK_STATIC;
- }
-
- if (TYPE_FUNC(object->type)->flags & FUNC_DEFINED)
- CError_Error(CErrorStr333, object);
-
- TYPE_FUNC(object->type)->flags |= FUNC_DEFINED | FUNC_IS_TEMPL_INSTANCE;
-
- CPrep_StreamGetBlock(&templ->stream, NULL, 0);
-
- if (lookahead() == ';')
- tk = lex();
- else
- tk = ';';
-
- saveForceLoc = gForceSourceLoc;
- gForceSourceLoc = 1;
- CPrep_BrowserFilePosition(&file, &offset);
- gForceSourceLoc = saveForceLoc;
-
- if (file && *startOffset >= 0 && offset > *startOffset) {
- templ->srcfile = file;
- templ->startoffset = *startOffset;
- templ->endoffset = offset + 1;
- if (cparamblkptr->browseoptions.recordTemplates && file->recordbrowseinfo)
- CBrowse_NewTemplateFunc(templ);
- }
-
- } else {
- if (tk != ';')
- CError_Error(CErrorStr121);
- }
-}
-
-static HashNameNode *CTempl_FindConversionFuncName(TypeClass *tclass, Type *type, UInt32 qual) {
- Object *object;
- CScopeObjectIterator iter;
-
- CScope_InitObjectIterator(&iter, tclass->nspace);
- do {
- if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter))))
- return NULL;
- } while (
- !IS_TYPE_FUNC(object->type) ||
- !(TYPE_FUNC(object->type)->flags & FUNC_CONVERSION) ||
- (TYPE_FUNC(object->type)->qual & (Q_CONST | Q_VOLATILE)) != (qual & (Q_CONST | Q_VOLATILE)) ||
- !is_typesame(TYPE_FUNC(object->type)->functype, type)
- );
-
- return object->name;
-}
-
-static void CTempl_ParseConversionFunctionTemplate(DeclInfo *di, DeclFucker *what_is_this, TemplParam *params, TypeClass *tclass, SInt32 *startOffset, AccessType access) {
- tk = lex();
- if (!tclass) {
- CError_Error(CErrorStr121);
- return;
- }
-
- tclass->flags = tclass->flags | CLASS_IS_CONVERTIBLE;
- CError_QualifierCheck(di->qual & ~Q_INLINE);
-
- conversion_type_name(di);
- CDecl_NewConvFuncType(di);
-
- if (cscope_current->is_templ) {
- CError_ASSERT(1260, cscope_current == what_is_this->nspace);
- cscope_current = what_is_this->nspace->parent;
- }
-
- CTempl_ParseTemplateFunction(CTempl_DeclareTemplateFunction(di, params, tclass, access, 0), tclass, startOffset);
-}
-
-static void CTempl_ParseFunctionOrMemberTemplate(DeclFucker *what_is_this, TemplParam *params, TypeClass *tclass, SInt32 *startOffset, AccessType access, Boolean mysteryFlag) {
- NameSpaceObjectList *nsol;
- Object *object;
- TemplParam *param;
- TemplateFunction *templfunc;
- Boolean disallowCVFlag;
- TypeClass *tclass2;
- Type *type;
- UInt32 qual;
- DeclInfo di;
-
- for (param = params; param; param = param->next) {
- switch (param->pid.type) {
- case TPT_TYPE:
- if (param->data.typeparam.type) {
- CError_Error(CErrorStr378);
- param->data.typeparam.type = NULL;
- }
- break;
- case TPT_NONTYPE:
- if (param->data.paramdecl.defaultarg) {
- CError_Error(CErrorStr378);
- param->data.paramdecl.defaultarg = NULL;
- }
- break;
- case TPT_TEMPLATE:
- if (param->data.templparam.defaultarg) {
- CError_Error(CErrorStr378);
- param->data.templparam.defaultarg = NULL;
- }
- break;
- default:
- CError_FATAL(1317);
- }
- }
-
- disallowCVFlag = 0;
- ctempl_scanfuncparams = 1;
-
- memclrw(&di, sizeof(di));
- di.x51 = mysteryFlag;
-
- if (tk == TK_OPERATOR) {
- CTempl_ParseConversionFunctionTemplate(&di, what_is_this, params, tclass, startOffset, access);
- return;
- }
-
- CParser_GetDeclSpecs(&di, 1);
- if (tk == ';' && IS_TEMPL_CLASS(di.thetype))
- return;
-
- if (di.x10 || di.x14) {
- TypeFunc *tfunc;
-
- if (di.x14) {
- di.x10 = OBJECT(di.x14->object);
- CError_ASSERT(1342, di.x10->otype == OT_OBJECT);
- }
-
- CError_ASSERT(1344, IS_TYPE_FUNC(di.x10->type));
-
- tfunc = TYPE_FUNC(di.x10->type);
- if (tfunc->flags & FUNC_CONVERSION) {
- di.thetype = tfunc->functype;
- di.qual |= tfunc->qual;
- di.nspace = di.x10->nspace;
- di.name = di.x10->name;
- } else if (tfunc->flags & FUNC_IS_CTOR) {
- di.thetype = TYPE(&void_ptr);
- di.nspace = di.x10->nspace;
- di.name = di.x10->name;
- } else {
- CError_Error(CErrorStr121);
- return;
- }
-
- if ((tk = lex()) == '(') {
- tk = lex();
- CDecl_ParseDirectFuncDecl(&di);
- if (IS_TYPE_FUNC(di.thetype))
- goto skipPastStuff;
- } else {
- CError_Error(CErrorStr114);
- }
- }
-
- if (di.storageclass) {
- if (tclass) {
- if (di.storageclass == TK_STATIC)
- disallowCVFlag = 1;
- else
- CError_Error(CErrorStr177);
- di.storageclass = 0;
- } else {
- if (di.storageclass != TK_STATIC && di.storageclass != TK_EXTERN) {
- CError_Error(CErrorStr177);
- di.storageclass = 0;
- }
- }
- }
-
- CError_QualifierCheck(di.qual & ~(Q_CONST | Q_VOLATILE | Q_ASM | Q_PASCAL | Q_INLINE | Q_EXPLICIT | Q_20000 | Q_WEAK | Q_ALIGNED_MASK));
-
- if (tk == TK_OPERATOR && di.x4A) {
- CTempl_ParseConversionFunctionTemplate(&di, what_is_this, params, tclass, startOffset, access);
- return;
- }
-
- if (!di.x53) {
- if (tclass && IS_TYPE_CLASS(di.thetype) && TYPE_CLASS(di.thetype) == tclass && tk == '(') {
- CError_ASSERT(1418, cscope_current == tclass->nspace);
- CError_QualifierCheck(di.qual & ~(Q_INLINE | Q_EXPLICIT));
-
- di.thetype = TYPE(&void_ptr);
- di.x4B = 1;
-
- tk = lex();
- CDecl_ParseDirectFuncDecl(&di);
-
- if (IS_TYPE_FUNC(di.thetype)) {
- if (TYPE_FUNC(di.thetype)->args && !TYPE_FUNC(di.thetype)->args->next && TYPE_FUNC(di.thetype)->args->type == TYPE(tclass)) {
- CError_Error(CErrorStr239);
- TYPE_FUNC(di.thetype)->args = NULL;
- }
-
- if (tclass->flags & CLASS_HAS_VBASES)
- CDecl_AddArgument(TYPE_FUNC(di.thetype), TYPE(&stsignedshort));
-
- TYPE_FUNC(di.thetype)->flags |= FUNC_IS_CTOR;
- di.name = constructor_name_node;
-
- what_is_this->nspace->tparams = NULL;
-
- CTempl_ParseTemplateFunction(
- CTempl_DeclareTemplateFunction(&di, params, tclass, access, disallowCVFlag),
- tclass, startOffset);
-
- return;
- } else {
- CError_Error(CErrorStr241);
- }
- }
-
- if (IS_TYPE_TEMPLATE(di.thetype)) {
- if (
- tk == '(' &&
- TYPE_TEMPLATE(di.thetype)->dtype == TEMPLDEP_QUALNAME &&
- (tclass2 = TYPE_CLASS(CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(di.thetype)->u.qual.type)))) &&
- TYPE_TEMPLATE(di.thetype)->u.qual.name == tclass2->classname
- )
- {
- if (tclass)
- CError_Error(CErrorStr229);
-
- di.thetype = TYPE(&void_ptr);
- di.x4B = 1;
-
- CTempl_SetupClassParamNameSpace(what_is_this, tclass2);
-
- tk = lex();
- CDecl_ParseDirectFuncDecl(&di);
-
- if (IS_TYPE_FUNC(di.thetype)) {
- di.name = constructor_name_node;
- if (tclass2->flags & CLASS_HAS_VBASES)
- CDecl_AddArgument(TYPE_FUNC(di.thetype), TYPE(&stsignedshort));
-
- TYPE_FUNC(di.thetype)->flags |= FUNC_IS_CTOR;
- CTempl_ParseMember(params, TEMPL_CLASS(tclass2), &di, startOffset);
- } else {
- CError_Error(CErrorStr241);
- }
-
- return;
- }
-
- if (
- tk == TK_COLON_COLON &&
- TYPE_TEMPLATE(di.thetype)->dtype == TEMPLDEP_TEMPLATE &&
- (tclass2 = TYPE_CLASS(CTemplTool_GetSelfRefTemplate(di.thetype)))
- )
- {
- if (tclass)
- CError_Error(CErrorStr229);
-
- if ((tk = lex()) == '~') {
- if (
- (tk = lex()) != TK_IDENTIFIER ||
- tkidentifier != tclass2->classname ||
- (tk = lex()) != '('
- )
- {
- if (tk == '<') {
- DeclInfo di2;
-
- CPrep_UnLex();
- tk = TK_IDENTIFIER;
- tkidentifier = tclass2->classname;
-
- memclrw(&di2, sizeof(di2));
- CParser_GetDeclSpecs(&di2, 0);
- if (tk != '(')
- CError_Error(CErrorStr241);
-
- if (di2.thetype != TYPE(tclass2) && (!IS_TYPE_TEMPLATE(di2.thetype) || CTemplTool_IsTemplate(
- TYPE_TEMPLATE(di2.thetype)) != TEMPL_CLASS(tclass2)))
- {
- CError_Error(CErrorStr241);
- }
- } else {
- CError_Error(CErrorStr241);
- }
- }
-
- di.thetype = TYPE(&void_ptr);
-
- CTempl_SetupClassParamNameSpace(what_is_this, tclass2);
- tk = lex();
- CDecl_ParseDirectFuncDecl(&di);
-
- if (IS_TYPE_FUNC(di.thetype)) {
- if (tclass2->sominfo)
- di.qual |= Q_VIRTUAL;
- else
- CDecl_AddArgument(TYPE_FUNC(di.thetype), TYPE(&stsignedshort));
-
- di.name = destructor_name_node;
- TYPE_FUNC(di.thetype)->flags |= FUNC_IS_DTOR;
- CTempl_ParseMember(params, TEMPL_CLASS(tclass2), &di, startOffset);
- } else {
- CError_Error(CErrorStr241);
- }
- } else if (tk == TK_OPERATOR) {
- CTempl_SetupClassParamNameSpace(what_is_this, tclass2);
- if (CMangler_OperatorName((tk = lex()))) {
- CError_Error(CErrorStr349);
- return;
- }
-
- CError_QualifierCheck(di.qual & ~(Q_INLINE | Q_VIRTUAL));
- conversion_type_name(&di);
-
- type = di.thetype;
- qual = di.qual;
- CDecl_NewConvFuncType(&di);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- di.name = CTempl_FindConversionFuncName(tclass2, type, qual);
- if (!di.name) {
- CError_Error(CErrorStr150, "conversion function");
- return;
- }
- }
- CTempl_ParseMember(params, TEMPL_CLASS(tclass2), &di, startOffset);
- } else {
- CError_Error(CErrorStr121);
- }
-
- return;
- }
-
- if (TYPE_TEMPLATE(di.thetype)->dtype == TEMPLDEP_QUALNAME && !di.x49)
- CError_Warning(CErrorStr355);
- }
- }
-
- di.x30 = params;
- di.fucker34 = what_is_this;
- scandeclarator(&di);
- ctempl_scanfuncparams = 0;
-
-skipPastStuff:
- if (cscope_current->is_templ) {
- CError_ASSERT(1589, cscope_current == what_is_this->nspace);
- what_is_this->nspace->tparams = NULL;
- }
-
- if (!di.name) {
- CError_Error(CErrorStr229);
- return;
- }
-
- if (di.nspace) {
- if (di.nspace->theclass) {
- if (tclass)
- CError_Error(CErrorStr229);
- CTempl_ParseMember(params, TEMPL_CLASS(di.nspace->theclass), &di, startOffset);
- return;
- }
-
- if (!IS_TYPE_FUNC(di.thetype)) {
- CError_Error(CErrorStr229);
- return;
- }
-
- CScope_FindName(di.nspace, di.name);
- } else {
- if (!IS_TYPE_FUNC(di.thetype)) {
- CError_Error(CErrorStr229);
- return;
- }
-
- CScope_FindName(cscope_current, di.name);
- }
-
- nsol = CScope_FindName(di.nspace ? di.nspace : cscope_current, di.name);
- while (nsol) {
- object = OBJECT(nsol->object);
- if (object->otype == OT_OBJECT && IS_TEMPL_FUNC(object->type)) {
- templfunc = CTemplTool_GetFuncTempl(object);
- if (CTemplTool_EqualParams(templfunc->params, params, 0) && is_typesame(object->type, di.thetype)) {
- if (tk != ';' && templfunc->stream.tokens)
- CError_Error(CErrorStr234);
-
- if (tk == '{' || tk == ':' || tk == TK_TRY)
- CError_ASSERT(1654, CTemplTool_EqualParams(templfunc->params, params, 1));
-
- if (di.qual & Q_INLINE)
- object->qual |= Q_INLINE;
- TYPE_FUNC(object->type)->args = TYPE_FUNC(di.thetype)->args;
- break;
- }
- }
- nsol = nsol->next;
- }
-
- if (!nsol) {
- if (di.nspace)
- CError_Error(CErrorStr229);
- templfunc = CTempl_DeclareTemplateFunction(&di, params, tclass, access, disallowCVFlag);
- }
-
- CTempl_ParseTemplateFunction(templfunc, tclass, startOffset);
-}
-
-static void CTempl_ExplicitInstantiation(void) {
- Boolean flag;
- short saveToken;
- Object *object;
- DeclInfo di;
-
- memclrw(&di, sizeof(di));
- di.x51 = 1;
- flag = 1;
-
- if (tk == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__dont_instantiate")) {
- flag = 0;
- tk = lex();
- }
-
- switch (tk) {
- case TK_STRUCT:
- case TK_UNION:
- case TK_CLASS:
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
- if (tk == ';') {
- if (IS_TEMPL_CLASS_INST(di.thetype)) {
- CTempl_InstantiateTemplateClass(TYPE_CLASS(di.thetype));
- if ((TYPE_CLASS(di.thetype)->flags & CLASS_COMPLETED) && !(TYPE_CLASS(di.thetype)->eflags & CLASS_EFLAGS_IMPORT)) {
- if (flag)
- CTempl_GenClassInstance(TEMPL_CLASS_INST(di.thetype), 1);
- else
- TEMPL_CLASS_INST(di.thetype)->is_extern = 1;
- } else {
- CError_Error(CErrorStr136, TYPE_CLASS(di.thetype), 0);
- }
- } else {
- CError_Error(CErrorStr238);
- }
- return;
- }
- break;
- default:
- memclrw(&di, sizeof(di));
- CParser_GetDeclSpecs(&di, 0);
- }
-
- di.x51 = 1;
-
- scandeclarator(&di);
-
- saveToken = tk;
-
- di.x38 = NULL;
- if (
- di.name &&
- IS_TYPE_FUNC(di.thetype) &&
- (object = CDecl_GetFunctionObject(&di, di.nspace, NULL, 1)) &&
- IS_TYPE_FUNC(object->type) &&
- object->u.func.inst &&
- di.x38
- )
- {
- if (!flag)
- object->u.func.inst->is_extern = 1;
- else
- CTempl_GenFuncInstance(di.x38, object->u.func.inst, 1);
- } else {
- CError_Error(CErrorStr238);
- }
-
- if (saveToken != ';')
- CError_Error(CErrorStr123);
-}
-
-static void CTempl_ExplicitSpecialization(void) {
- Boolean flag;
- TemplParam *params;
- int counter;
- DeclFucker what_is_this;
- DeclInfo di;
-
- flag = 0;
- counter = 1;
- while (tk == TK_TEMPLATE) {
- if ((tk = lex()) != '<') {
- CError_Error(CErrorStr230);
- break;
- }
-
- if ((tk = lex()) != '>') {
- if (!flag) {
- what_is_this.nspace = cscope_current;
- what_is_this.mystery4 = NULL;
- cscope_current->tparams = NULL;
- flag = 1;
- }
-
- params = CTempl_ParseParamList(what_is_this.nspace, counter);
- if (tk != '>')
- CError_Error(CErrorStr231);
- } else {
- if (flag)
- CError_Error(CErrorStr335);
- }
-
- counter++;
- tk = lex();
- }
-
- if (flag) {
- SInt32 startOffset = -1;
- CTempl_ParseFunctionOrMemberTemplate(&what_is_this, params, NULL, &startOffset, ACCESSPUBLIC, 1);
- return;
- }
-
- memclrw(&di, sizeof(di));
- di.x3C = counter;
- di.x51 = 1;
- CParser_GetDeclSpecs(&di, 1);
-
- if (tk == ';') {
- if (IS_TEMPL_CLASS_INST(di.thetype))
- TEMPL_CLASS_INST(di.thetype)->is_specialized = 1;
- else
- CError_Error(CErrorStr335);
- } else {
- scandeclaratorlist(&di);
- if ((tk != ';' && tk != '}') || di.x3C)
- CError_Error(CErrorStr335);
- }
-
- if (flag)
- what_is_this.nspace->tparams = NULL;
-}
-
-void CTempl_Parse(TemplClass *templ, AccessType access) {
- TemplParam *params;
- UInt8 i;
- short mode;
- Boolean flag;
- UInt8 classDeclSpec;
- SInt32 startOffset;
- SInt32 savedState;
- CScopeSave savedScope;
- DeclFucker what_is_this;
-
- startOffset = CPrep_BrowserFileOffset();
- CScope_GetScope(&savedScope);
-
- if ((tk = lex()) != '<') {
- if (templ)
- CError_Error(CErrorStr238);
- CTempl_ExplicitInstantiation();
- CScope_RestoreScope(&savedScope);
- return;
- }
-
- if ((tk = lex()) == '>') {
- if (templ)
- CError_Error(CErrorStr335);
- tk = lex();
- CTempl_ExplicitSpecialization();
- CScope_RestoreScope(&savedScope);
- return;
- }
-
- what_is_this.nspace = cscope_current;
- what_is_this.mystery4 = NULL;
- cscope_current->tparams = NULL;
- i = CTempl_GetTemplateNestIndex(what_is_this.nspace);
-
- while (1) {
- params = CTempl_ParseParamList(what_is_this.nspace, i);
- if (tk != '>')
- CError_Error(CErrorStr231);
-
- if ((tk = lex()) != TK_TEMPLATE)
- break;
-
- if (templ)
- CError_Error(CErrorStr121);
-
- if ((tk = lex()) != '<')
- CError_Error(CErrorStr230);
- else
- tk = lex();
-
- i++;
- }
-
- switch (tk) {
- case TK_CLASS:
- mode = CLASS_MODE_CLASS;
- break;
- case TK_UNION:
- mode = CLASS_MODE_UNION;
- break;
- case TK_STRUCT:
- mode = CLASS_MODE_STRUCT;
- break;
- default:
- mode = -1;
- }
-
- if (mode >= 0) {
- classDeclSpec = 0;
- flag = 0;
-
- CPrep_TokenStreamGetState(&savedState);
- if ((tk = lex()) == TK_UU_DECLSPEC)
- CDecl_ParseClassDeclSpec(&classDeclSpec);
-
- if (tk == TK_IDENTIFIER) {
- if ((tk = lex()) == '<') {
- if (setjmp(ctempl_parseparse) == 0) {
- CTempl_MemberParseTemplArgList();
- flag = 1;
- tk = lex();
- }
- }
-
- switch (tk) {
- case ':':
- case ';':
- case '{':
- CPrep_TokenStreamSetCurState(&savedState);
- if (flag)
- CTemplClass_ParsePartialSpecialization(&what_is_this, params, mode, &startOffset);
- else
- CTemplClass_ParseClass(&what_is_this, params, mode, &startOffset);
- goto done;
- }
- }
-
- CPrep_TokenStreamSetCurState(&savedState);
- }
-
- CTempl_ParseFunctionOrMemberTemplate(&what_is_this, params, TYPE_CLASS(templ), &startOffset, access, 0);
-
-done:
- what_is_this.nspace->tparams = NULL;
- CScope_RestoreScope(&savedScope);
-}
-
-void CTempl_ParseInstanceScopeFunction(Object *funcobj, TemplClassInst *inst, TypeClass *tclass) {
- TemplParam *params;
- NameSpace *nspace;
- TemplateMember *member;
- Object *parent;
- DeclInfo di;
- CScopeSave savedScope;
- TemplStack stack;
-
- params = inst->templ->templ__params;
- if (funcobj->qual & Q_IS_TEMPLATED) {
- for (member = CTemplClass_GetMasterTemplate(inst->templ)->members, parent = OBJECT_TEMPL(funcobj)->parent; member; member = member->next) {
- if (member->object == parent) {
- if (member->params)
- params = member->params;
- break;
- }
- }
- }
-
- CTemplTool_PushInstance(&stack, NULL, funcobj);
- nspace = CTemplTool_InsertTemplateArgumentNameSpace(params, inst, &savedScope);
- if (tclass)
- cscope_current = tclass->nspace;
-
- memclrw(&di, sizeof(di));
- CFunc_ParseFuncDef(funcobj, &di, NULL, 0, 0, tclass ? cscope_current : NULL);
-
- CTemplTool_RemoveTemplateArgumentNameSpace(nspace, inst, &savedScope);
- CTemplTool_PopInstance(&stack);
-}
-
-Boolean CTempl_GenFuncInstance(TemplateFunction *templ, TemplFuncInstance *inst, Boolean flag) {
- Boolean saveDebugInfo;
- NameSpace *nspace;
- SInt32 streamState;
- TemplStack stack;
- DeclInfo di;
-
- if (!flag && copts.no_implicit_templates && inst->object->sclass != TK_STATIC)
- return 0;
-
- if (inst->is_extern && !flag)
- return 0;
-
- while (1) {
- if (templ->stream.tokens)
- break;
- if (!templ->unk4)
- break;
- templ = templ->unk4;
- }
-
- if (!templ->stream.tokens) {
- if (flag) {
- CError_SetErrorToken(&templ->deftoken);
- CError_Error(CErrorStr233, inst->object);
- }
- return 0;
- }
-
- inst->is_instantiated = 1;
-
- CPrep_StreamInsert(&templ->stream, &streamState);
-
- saveDebugInfo = copts.filesyminfo;
- if (copts.nosyminline || !templ->deftoken.tokenfile)
- copts.filesyminfo = 0;
-
- CError_ASSERT(2112, (tk = lex()) == '{' || tk == ':' || tk == TK_TRY);
-
- symdecltoken = *CPrep_CurStreamElement();
-
- if (copts.filesyminfo) {
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, &templ->deftoken);
- symdecloffset = cparser_fileoffset.tokenline;
- }
-
- if (inst->object->sclass != TK_STATIC)
- inst->object->qual |= Q_WEAK;
-
- memclrw(&di, sizeof(di));
- di.file2 = templ->srcfile;
- di.file = CPrep_BrowserCurrentFile();
- di.sourceoffset = templ->startoffset;
-
- CTemplTool_PushInstance(&stack, NULL, inst->object);
- CTemplTool_MergeArgNames(TYPE_FUNC(templ->tfunc->type), TYPE_FUNC(inst->object->type));
-
- nspace = CTemplTool_SetupTemplateArgumentNameSpace(templ->params, inst->args, 0);
- nspace->parent = inst->object->nspace;
- inst->object->nspace = nspace;
-
- CTemplTool_SetupOuterTemplateArgumentNameSpace(nspace);
- CFunc_ParseFuncDef(inst->object, &di, NULL, 0, 0, nspace);
- CTemplTool_RemoveOuterTemplateArgumentNameSpace(nspace);
-
- inst->object->nspace = nspace->parent;
-
- CTemplTool_PopInstance(&stack);
-
- CPrep_StreamRemove(&templ->stream, &streamState);
- copts.filesyminfo = saveDebugInfo;
-
- if (di.file->recordbrowseinfo)
- CBrowse_NewFunction(inst->object, di.file, di.file2, di.sourceoffset, templ->endoffset);
-
- return 1;
-}
-
-void CTempl_InstantiateMember(TemplClass *templ, TemplClassInst *inst, TemplateMember *tmemb, Object *object, Boolean flag) {
- Boolean saveDebugInfo;
- NameSpace *nspace;
- Boolean saveSourceLoc;
-
- DeclInfo di;
- CScopeSave savedScope;
- TemplStack stack;
- SInt32 savedState;
-
- if (!flag && copts.no_implicit_templates)
- return;
-
- CTemplTool_PushInstance(&stack, NULL, object);
- nspace = CTemplTool_InsertTemplateArgumentNameSpace(
- tmemb->params ? tmemb->params : templ->templ__params, inst, &savedScope);
- CPrep_StreamInsert(&tmemb->stream, &savedState);
-
- saveSourceLoc = gForceSourceLoc;
- gForceSourceLoc = 1;
- symdecltoken.tokenoffset = tmemb->startoffset;
- tk = lex();
-
- symdecltoken = *CPrep_CurStreamElement();
-
- saveDebugInfo = copts.filesyminfo;
- if (copts.filesyminfo) {
- CPrep_NewFileOffsetInfo(&cparser_fileoffset, &symdecltoken);
- symdecloffset = cparser_fileoffset.tokenline;
- }
-
- if (object->sclass != TK_STATIC)
- object->qual |= Q_WEAK;
-
- memclrw(&di, sizeof(di));
- di.file2 = tmemb->srcfile;
- di.file = CPrep_BrowserCurrentFile();
- di.sourceoffset = tmemb->startoffset;
-
- switch (object->datatype) {
- case DFUNC:
- case DVFUNC:
- CTemplTool_MergeArgNames(TYPE_FUNC(tmemb->object->type), TYPE_FUNC(object->type));
- CFunc_ParseFuncDef(object, &di, TYPE_CLASS(inst), 0, 0, NULL);
- break;
-
- case DDATA:
- CDecl_CompleteType(object->type);
- CInit_InitializeData(object);
- break;
-
- default:
- CError_FATAL(2227);
- }
-
- CTemplTool_PopInstance(&stack);
- CTemplTool_RemoveTemplateArgumentNameSpace(nspace, inst, &savedScope);
- CPrep_StreamRemove(&tmemb->stream, &savedState);
- copts.filesyminfo = saveDebugInfo;
- gForceSourceLoc = saveSourceLoc;
-}
-
-static Boolean CTempl_GenMemberInstance(TemplClassInst *inst, ObjectTemplated *objtempl, Boolean flag) {
- TemplateMember *member;
- Object *parent = objtempl->parent;
-
- for (member = CTemplClass_GetMasterTemplate(inst->templ)->members; member; member = member->next) {
- if (member->object == parent) {
- CTempl_InstantiateMember(inst->templ, inst, member, OBJECT(objtempl), flag);
- return 1;
- }
- }
-
- if (flag)
- CError_Warning(CErrorStr233, objtempl);
- return 0;
-}
-
-static Boolean CTempl_GenClassInstance(TemplClassInst *inst, Boolean flag) {
- Object *object;
- Boolean result;
- CScopeObjectIterator iter;
-
- result = 0;
-
- if (!flag && copts.no_implicit_templates)
- return 0;
- if (!flag && inst->is_extern)
- return 0;
-
- CScope_InitObjectIterator(&iter, inst->theclass.nspace);
- while ((object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) {
- if (IS_TYPE_FUNC(object->type) && object->datatype != DALIAS) {
- if (
- (flag || (object->flags & OBJECT_FLAGS_2)) &&
- !(TYPE_FUNC(object->type)->flags & (FUNC_DEFINED | FUNC_AUTO_GENERATED)) &&
- CTempl_GenMemberInstance(inst, OBJECT_TEMPL(object), flag) &&
- (TYPE_FUNC(object->type)->flags & FUNC_DEFINED)
- )
- result = 1;
- } else {
- if (
- !inst->static_instantiated &&
- object->datatype == DDATA &&
- !(object->qual & Q_INLINE_DATA) &&
- !(object->flags & OBJECT_DEFINED) &&
- CTempl_GenMemberInstance(inst, OBJECT_TEMPL(object), flag)
- )
- result = 1;
- }
- }
-
- inst->static_instantiated = 1;
- return result;
-}
-
-Boolean CTempl_Instantiate(void) {
- Boolean result = 0;
- TemplClass *templ;
- TemplClassInst *inst;
- TemplPartialSpec *pspec;
- TemplFuncInstance *instf;
- TemplateFunction *templf;
-
- for (templ = ctempl_templates; templ; templ = templ->next) {
- for (inst = templ->instances; inst; inst = inst->next) {
- if (
- (inst->theclass.flags & CLASS_IS_TEMPL_INST) &&
- !inst->is_specialized &&
- CTempl_GenClassInstance(inst, 0)
- )
- result = 1;
- }
-
- for (pspec = templ->pspecs; pspec; pspec = pspec->next) {
- for (inst = pspec->templ->instances; inst; inst = inst->next) {
- if (
- (inst->theclass.flags & CLASS_IS_TEMPL_INST) &&
- !inst->is_specialized &&
- CTempl_GenClassInstance(inst, 0)
- )
- result = 1;
- }
- }
- }
-
- for (templf = ctempl_templatefuncs; templf; templf = templf->next) {
- for (instf = templf->instances; instf; instf = instf->next) {
- if (
- !instf->is_instantiated &&
- !instf->is_specialized &&
- (instf->object->flags & OBJECT_FLAGS_2) &&
- !(TYPE_FUNC(instf->object->type)->flags & FUNC_DEFINED)
- )
- {
- instf->is_instantiated = 1;
- if (CTempl_GenFuncInstance(templf, instf, 0))
- result = 1;
- }
- }
- }
-
- return result;
-}
-
-Boolean CTempl_InlineFunctionCheck(Object *funcobj) {
- TemplClassInst *inst;
- TemplateMember *member;
- Object *parent;
-
- CError_ASSERT(2422, IS_TYPE_FUNC(funcobj->type) && (funcobj->qual & Q_IS_TEMPLATED));
-
- if (!(TYPE_FUNC(funcobj->type)->flags & FUNC_DEFINED)) {
- inst = TEMPL_CLASS_INST(TYPE_METHOD(funcobj->type)->theclass);
- if (!inst->is_specialized) {
- parent = OBJECT_TEMPL(funcobj)->parent;
- if (parent->qual & Q_INLINE) {
- for (member = CTemplClass_GetMasterTemplate(inst->templ)->members; member; member = member->next) {
- funcobj->qual |= Q_INLINE;
- if (member->object == parent) {
- CTemplTool_MergeArgNames(TYPE_FUNC(member->object->type), TYPE_FUNC(funcobj->type));
- CInline_AddInlineFunctionAction(funcobj, TYPE_CLASS(inst), &member->fileoffset, &member->stream, 0);
- return 1;
- }
- }
- }
- }
- }
-
- return 0;
-}
diff --git a/compiler_and_linker/unsorted/CTemplateTools.c b/compiler_and_linker/unsorted/CTemplateTools.c
deleted file mode 100644
index 0e77e74..0000000
--- a/compiler_and_linker/unsorted/CTemplateTools.c
+++ /dev/null
@@ -1,1962 +0,0 @@
-#include "compiler/CTemplateTools.h"
-#include "compiler/CABI.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CTemplateClass.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/types.h"
-
-short ctempl_instdepth;
-
-void CTemplTool_PushInstance(TemplStack *stack, TypeClass *tmclass, Object *func) {
- if (tmclass) {
- stack->u.theclass = tmclass;
- stack->is_func = 0;
- } else {
- stack->u.func = func;
- stack->is_func = 1;
- }
- stack->next = ctempl_curinstance;
- ctempl_curinstance = stack;
-
- if (++ctempl_instdepth >= 64)
- CError_ErrorTerm(CErrorStr314);
-}
-
-void CTemplTool_PopInstance(TemplStack *stack) {
- CError_ASSERT(53, ctempl_curinstance == stack);
-
- ctempl_curinstance = stack->next;
- if (--ctempl_instdepth < 0)
- ctempl_instdepth = 0;
-}
-
-ENode *CTempTool_GetPTMTemplArgExpr(ENode *expr, Type *type) {
- NameSpaceObjectList *list;
-
- CError_ASSERT(69, ENODE_IS(expr, EMEMBER));
- CError_ASSERT(70, IS_TYPE_MEMBERPOINTER(type));
-
- if (!copts.cpp_extensions) {
- if (!expr->data.emember->x11 || !expr->data.emember->pr_1D)
- CError_Warning(CErrorStr331);
- }
-
- type = TYPE_MEMBER_POINTER(type)->ty1;
- for (list = expr->data.emember->list; list; list = list->next) {
- if (list->object->otype == OT_MEMBERVAR) {
- if (!is_typeequal(OBJ_MEMBER_VAR(list->object)->type, type))
- CError_Error(CErrorStr146);
- return expr;
- }
-
- if (list->object->otype == OT_OBJECT && is_memberpointerequal(OBJECT(list->object)->type, type)) {
- if (expr->data.emember->list != list || list->next) {
- // rewrite the EMEMBER to contain just one node
- expr->data.emember->list = galloc(sizeof(NameSpaceObjectList));
- *expr->data.emember->list = *list;
- expr->data.emember->list->next = NULL;
- }
- break;
- }
- }
-
- if (!list)
- CError_Error(CErrorStr146);
-
- return expr;
-}
-
-Boolean CTemplTool_InitDeduceInfo(DeduceInfo *info, TemplParam *params, TemplArg *args, Boolean flag) {
- int i;
- TemplArg *buffer;
- TemplParam *param;
-
- if (!params) {
- info->args = info->argBuffer;
- info->maxCount = 0;
- info->x12C = 0xFF;
- return 1;
- }
-
- memclrw(info, sizeof(DeduceInfo));
-
- i = 0;
- param = params;
- while (param) {
- param = param->next;
- i++;
- }
-
- if (i > 16) {
- buffer = lalloc(i * sizeof(TemplArg));
- memclrw(buffer, i * sizeof(TemplArg));
- } else {
- buffer = info->argBuffer;
- }
- info->args = buffer;
- info->maxCount = i;
- info->x12C = params->pid.nindex;
-
- for (param = params, i = 0; param; param = param->next, i++)
- buffer[i].pid = param->pid;
-
- i = 0;
- param = params;
- while (args) {
- if (!param || param->pid.type != args->pid.type)
- return 0;
-
- buffer[i].data = args->data;
- if (i > 0)
- buffer[i - 1].next = &buffer[i];
- buffer[i].next = NULL;
- buffer[i].is_deduced = 1;
- info->count++;
-
- if (param->pid.type == TPT_NONTYPE && !CTemplTool_IsTemplateArgumentDependentType(param->data.paramdecl.type)) {
- if (CExpr_CanImplicitlyConvert(buffer[i].data.paramdecl.expr, param->data.paramdecl.type, param->data.paramdecl.qual)) {
- buffer[i].data.paramdecl.expr = CExpr_AssignmentPromotion(
- buffer[i].data.paramdecl.expr, param->data.paramdecl.type, param->data.paramdecl.qual, 0);
- } else {
- return 0;
- }
- }
-
- args = args->next;
- param = param->next;
- i++;
- }
-
- if (flag) {
- for (param = params, i = 0; param; param = param->next, i++) {
- if (!buffer[i].is_deduced && !param->name) {
- switch (param->pid.type) {
- case TPT_TYPE:
- buffer[i].data.typeparam.type = &stvoid;
- break;
- case TPT_NONTYPE:
- buffer[i].data.paramdecl.expr = nullnode();
- break;
- case TPT_TEMPLATE:
- default:
- CError_FATAL(208);
- }
- buffer[i].is_deduced = 1;
- }
- }
- }
-
- return 1;
-}
-
-void CTemplTool_InsertTemplateParameter(NameSpace *nspace, TemplParam *param) {
- Type *type;
- ObjType *obj;
- NameSpaceName *nsn;
-
- type = CDecl_NewTemplDepType(TEMPLDEP_ARGUMENT);
- TYPE_TEMPLATE(type)->u.pid = param->pid;
-
- obj = galloc(sizeof(ObjType));
- memclrw(obj, sizeof(ObjType));
- obj->otype = OT_TYPE;
- obj->access = ACCESSPUBLIC;
- obj->type = type;
-
- for (nsn = nspace->tparams; nsn; nsn = nsn->next) {
- if (nsn->name == param->name) {
- CError_Error(CErrorStr122, param->name->name);
- return;
- }
- }
-
- nsn = galloc(sizeof(NameSpaceName));
- memclrw(nsn, sizeof(NameSpaceName));
-
- nsn->name = param->name;
- nsn->first.object = OBJ_BASE(obj);
-
- nsn->next = nspace->tparams;
- nspace->tparams = nsn;
-}
-
-TemplArg *CTemplTool_MakeTemplArgList(DeduceInfo *info) {
- TemplArg *args;
- TemplArg *last;
- int i;
-
- for (i = 0; i < info->maxCount; i++) {
- if (i) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- args = last = galloc(sizeof(TemplArg));
- }
-
- *last = info->args[i];
- }
-
- last->next = NULL;
- return args;
-}
-
-Boolean CTemplTool_IsIdenticalTemplArgList(TemplArg *args, TemplParam *params) {
- while (args) {
- if (!params)
- return 0;
-
- CError_ASSERT(297, params->pid.type == args->pid.type);
-
- switch (args->pid.type) {
- case TPT_TYPE:
- if (
- !IS_TYPE_TEMPLATE(args->data.typeparam.type) ||
- TYPE_TEMPLATE(args->data.typeparam.type)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.index != params->pid.index ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (
- !ENODE_IS(args->data.paramdecl.expr, ETEMPLDEP) ||
- args->data.paramdecl.expr->data.templdep.subtype != TDE_PARAM ||
- args->data.paramdecl.expr->data.templdep.u.pid.index != params->pid.index ||
- args->data.paramdecl.expr->data.templdep.u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- if (
- !IS_TYPE_TEMPLATE(args->data.ttargtype) ||
- TYPE_TEMPLATE(args->data.ttargtype)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.ttargtype)->u.pid.index != params->pid.index ||
- TYPE_TEMPLATE(args->data.ttargtype)->u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- default:
- CError_FATAL(331);
- }
-
- args = args->next;
- params = params->next;
- }
-
- return !params;
-}
-
-Type *CTemplTool_GetSelfRefTemplate(Type *type) {
- TemplClass *templ;
- TemplArg *args;
-
- CError_ASSERT(347, IS_TYPE_TEMPLATE(type));
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_TEMPLATE) {
- if (CTemplTool_IsIdenticalTemplArgList(
- TYPE_TEMPLATE(type)->u.templ.args,
- TYPE_TEMPLATE(type)->u.templ.templ->templ__params))
- return TYPE(TYPE_TEMPLATE(type)->u.templ.templ);
-
- if (TYPE_TEMPLATE(type)->u.templ.templ->pspecs) {
- templ = TYPE_TEMPLATE(type)->u.templ.templ;
- if (
- CTemplClass_FindPartialTemplate(TYPE_TEMPLATE(type)->u.templ.args, &templ, &args) &&
- CTemplTool_IsIdenticalTemplArgList(args, templ->templ__params)
- )
- return TYPE(templ);
- }
-
- return NULL;
- }
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_QUALNAME) {
- Type *t = CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(type)->u.qual.type));
- if (
- t &&
- (t = CScope_GetLocalTagType(TYPE_CLASS(t)->nspace, TYPE_TEMPLATE(type)->u.qual.name)) &&
- IS_TEMPL_CLASS(t) &&
- !TEMPL_CLASS(t)->templ__params
- )
- return t;
-
- return NULL;
- }
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_QUALTEMPL) {
- Type *t;
-
- CError_ASSERT(389, TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->dtype == TEMPLDEP_QUALNAME);
-
- t = CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->u.qual.type));
- if (
- t &&
- (t = CScope_GetLocalTagType(TYPE_CLASS(t)->nspace, TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->u.qual.name)) &&
- IS_TEMPL_CLASS(t)
- )
- {
- TemplClass *tm = TEMPL_CLASS(t);
- if (CTemplTool_IsIdenticalTemplArgList(TYPE_TEMPLATE(type)->u.qualtempl.args, tm->templ__params))
- return TYPE(tm);
- }
- }
-
- return NULL;
-}
-
-TemplateFunction *CTemplTool_GetFuncTempl(Object *object) {
- while (object->datatype == DALIAS)
- object = object->u.alias.object;
-
- CError_ASSERT(416, IS_TEMPL_FUNC(object->type));
- return object->u.func.u.templ;
-}
-
-Boolean CTemplTool_ParamHasDefaultArg(TemplParam *param) {
- switch (param->pid.type) {
- case TPT_TYPE:
- return param->data.typeparam.type != NULL;
- case TPT_NONTYPE:
- return param->data.paramdecl.defaultarg != NULL;
- case TPT_TEMPLATE:
- default:
- CError_FATAL(438);
- return 0;
- }
-}
-
-void CTemplTool_MergeDefaultArgs(TemplParam *dest, TemplParam *src) {
- while (1) {
- if (!dest) {
- CError_ASSERT(455, !src);
- return;
- }
-
- CError_ASSERT(458, src);
- CError_ASSERT(459, dest->pid.type == src->pid.type);
-
- switch (dest->pid.type) {
- case TPT_TYPE:
- if (!dest->data.typeparam.type && src->data.typeparam.type)
- dest->data = src->data;
- break;
- case TPT_NONTYPE:
- if (!dest->data.paramdecl.defaultarg && src->data.paramdecl.defaultarg)
- dest->data = src->data;
- break;
- case TPT_TEMPLATE:
- if (!dest->data.templparam.defaultarg && src->data.templparam.defaultarg)
- dest->data = src->data;
- break;
- default:
- CError_FATAL(484);
- }
-
- dest = dest->next;
- src = src->next;
- }
-}
-
-static FuncArg *CTemplTool_GetFirstRealArg(TypeFunc *tfunc) {
- FuncArg *arg = tfunc->args;
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(tfunc)) {
- CError_ASSERT(502, arg);
- arg = arg->next;
- if ((tfunc->flags & FUNC_IS_CTOR) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_HAS_VBASES)) {
- CError_ASSERT(507, arg);
- arg = arg->next;
- }
- }
-
- return arg;
-}
-
-void CTemplTool_MergeArgNames(TypeFunc *src, TypeFunc *dest) {
- FuncArg *destArg;
- FuncArg *srcArg;
-
- CError_ASSERT(524, IS_TYPE_FUNC(dest) && IS_TYPE_FUNC(src));
-
- srcArg = CTemplTool_GetFirstRealArg(src);
- destArg = CTemplTool_GetFirstRealArg(dest);
-
- while (1) {
- if (!srcArg || !destArg || srcArg == &elipsis || destArg == &elipsis) {
- CError_ASSERT(531, srcArg == destArg);
- break;
- }
-
- destArg->name = srcArg->name;
- srcArg = srcArg->next;
- destArg = destArg->next;
- }
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(dest)) {
- CError_ASSERT(538, destArg = dest->args);
- if (!destArg->name)
- destArg->name = this_name_node;
- }
-}
-
-Boolean CTemplTool_EqualParams(TemplParam *a, TemplParam *b, Boolean copyNames) {
- while (1) {
- if (!a)
- return !b;
- if (!b)
- return 0;
-
- if (a->pid.type != b->pid.type)
- return 0;
-
- if (copyNames)
- a->name = b->name;
-
- switch (a->pid.type) {
- case TPT_TYPE:
- break;
- case TPT_NONTYPE:
- if (
- !is_typesame(a->data.paramdecl.type, b->data.paramdecl.type) ||
- a->data.paramdecl.qual != b->data.paramdecl.qual
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- break;
- default:
- CError_FATAL(576);
- }
-
- a = a->next;
- b = b->next;
- }
-}
-
-NameSpace *CTemplTool_SetupTemplateArgumentNameSpace(TemplParam *params, TemplArg *args, Boolean is_global) {
- NameSpace *nspace;
- Boolean clear_global;
- ObjType *objType;
- Object *object;
-
- clear_global = 0;
- if (!is_global && trychain) {
- clear_global = 1;
- is_global = 1;
- }
-
- nspace = CScope_NewListNameSpace(NULL, is_global);
- nspace->is_templ = 1;
-
- if (clear_global)
- nspace->is_global = 0;
-
- if (!params)
- return nspace;
-
- while (params) {
- CError_ASSERT(607, args);
-
- if (params->name) {
- switch (args->pid.type) {
- case TPT_TYPE:
- if (is_global) {
- objType = galloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- } else {
- objType = lalloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- }
- objType->otype = OT_TYPE;
- objType->access = ACCESSPUBLIC;
- objType->type = args->data.typeparam.type;
- objType->qual = args->data.typeparam.qual;
- CScope_AddObject(nspace, params->name, OBJ_BASE(objType));
- break;
- case TPT_NONTYPE:
- if (is_global) {
- object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- } else {
- object = lalloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- }
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->nspace = nspace;
- object->name = params->name;
- object->type = args->data.paramdecl.expr->rtype;
- object->qual = ENODE_QUALS(args->data.paramdecl.expr);
- object->datatype = DEXPR;
- object->u.expr = args->data.paramdecl.expr;
- if (IS_TYPE_REFERENCE(params->data.paramdecl.type)) {
- CError_ASSERT(652, IS_TYPE_POINTER_ONLY(object->u.expr->rtype));
- object->u.expr = makemonadicnode(object->u.expr, EINDIRECT);
- object->u.expr->rtype = TPTR_TARGET(params->data.paramdecl.type);
- }
- if (is_global)
- object->u.expr = CInline_CopyExpression(object->u.expr, CopyMode1);
- CScope_AddObject(nspace, params->name, OBJ_BASE(object));
- break;
- case TPT_TEMPLATE:
- if (is_global) {
- objType = galloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- } else {
- objType = lalloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- }
- objType->otype = OT_TYPE;
- objType->access = ACCESSPUBLIC;
- objType->type = args->data.ttargtype;
- objType->qual = 0;
- CScope_AddObject(nspace, params->name, OBJ_BASE(objType));
- break;
- default:
- CError_FATAL(681);
- }
- }
-
- params = params->next;
- args = args->next;
- }
-
- CError_ASSERT(685, !args);
-
- return nspace;
-}
-
-void CTemplTool_SetupOuterTemplateArgumentNameSpace(NameSpace *nspace) {
- NameSpace *newns;
-
- while (nspace) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_INST)) {
- newns = CTemplTool_SetupTemplateArgumentNameSpace(
- TEMPL_CLASS_INST(nspace->theclass)->templ->templ__params,
- TEMPL_CLASS_INST(nspace->theclass)->inst_args,
- 0);
- newns->parent = nspace->parent;
- nspace->parent = newns;
- }
-
- nspace = nspace->parent;
- }
-}
-
-NameSpace *CTemplTool_InsertTemplateArgumentNameSpace(TemplParam *params, TemplClassInst *inst, CScopeSave *save) {
- NameSpace *nspace = CTemplTool_SetupTemplateArgumentNameSpace(params, inst->inst_args, 0);
-
- nspace->parent = inst->theclass.nspace->parent;
- inst->theclass.nspace->parent = nspace;
-
- CTemplTool_SetupOuterTemplateArgumentNameSpace(nspace);
- CScope_SetNameSpaceScope(inst->theclass.nspace, save);
-
- return nspace;
-}
-
-void CTemplTool_RemoveOuterTemplateArgumentNameSpace(NameSpace *nspace) {
- while (nspace->parent) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_INST) && nspace->parent->is_templ)
- nspace->parent = nspace->parent->parent;
- nspace = nspace->parent;
- }
-}
-
-void CTemplTool_RemoveTemplateArgumentNameSpace(NameSpace *nspace, TemplClassInst *inst, CScopeSave *save) {
- CTemplTool_RemoveOuterTemplateArgumentNameSpace(inst->theclass.nspace);
- CScope_RestoreScope(save);
-}
-
-Boolean CTemplTool_IsTemplateArgumentDependentType(Type *type) {
- FuncArg *arg;
-
- while (1) {
- switch (type->type) {
- case TYPETEMPLATE:
- return 1;
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- return 0;
- case TYPECLASS:
- return (TYPE_CLASS(type)->flags & CLASS_IS_TEMPL) ? 1 : 0;
- case TYPEMEMBERPOINTER:
- if (CTemplTool_IsTemplateArgumentDependentType(TYPE_MEMBER_POINTER(type)->ty1))
- return 1;
- type = TYPE_MEMBER_POINTER(type)->ty2;
- continue;
- case TYPEPOINTER:
- case TYPEARRAY:
- type = TPTR_TARGET(type);
- continue;
- case TYPEFUNC:
- for (arg = TYPE_FUNC(type)->args; arg && arg != &elipsis && arg != &oldstyle; arg = arg->next) {
- if (CTemplTool_IsTemplateArgumentDependentType(arg->type))
- return 1;
- }
- type = TYPE_FUNC(type)->functype;
- continue;
- case TYPEBITFIELD:
- type = TYPE_BITFIELD(type)->bitfieldtype;
- continue;
- case TYPETEMPLDEPEXPR:
- return 1;
- default:
- CError_FATAL(822);
- }
- }
-}
-
-Boolean CTemplTool_IsTemplateArgumentDependentExpression(ENode *expr) {
- if (!expr)
- return 0;
-
- if (IS_TYPE_TEMPLDEPEXPR(expr->rtype))
- return 1;
-
- return 0;
-}
-
-Boolean CTemplTool_IsSameTemplate(TemplParam *params, TemplArg *args) {
- while (1) {
- if (!args) {
- CError_ASSERT(850, !params);
- return 1;
- }
-
- CError_ASSERT(853, params && args->pid.type == params->pid.type);
-
- switch (args->pid.type) {
- case TPT_TYPE:
- if (
- !IS_TYPE_TEMPLATE(args->data.typeparam.type) ||
- TYPE_TEMPLATE(args->data.typeparam.type)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.nindex != params->pid.nindex ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.index != params->pid.index ||
- args->data.typeparam.qual != 0
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (
- !ENODE_IS(args->data.paramdecl.expr, ETEMPLDEP) ||
- args->data.paramdecl.expr->data.templdep.subtype != TDE_PARAM ||
- args->data.paramdecl.expr->data.templdep.u.pid.nindex != params->pid.nindex ||
- args->data.paramdecl.expr->data.templdep.u.pid.index != params->pid.index
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- if (!IS_TYPE_TEMPLATE(args->data.ttargtype))
- return 0;
- break;
- default:
- CError_FATAL(886);
- }
-
- args = args->next;
- params = params->next;
- }
-}
-
-TemplClass *CTemplTool_IsTemplate(TypeTemplDep *ttd) {
- if (ttd->dtype == TEMPLDEP_QUALNAME && ttd->u.qual.type->dtype == TEMPLDEP_TEMPLATE)
- ttd = ttd->u.qual.type;
- else if (ttd->dtype != TEMPLDEP_TEMPLATE)
- return NULL;
-
- if (CTemplTool_IsSameTemplate(ttd->u.templ.templ->templ__params, ttd->u.templ.args))
- return ttd->u.templ.templ;
- else
- return NULL;
-}
-
-Type *CTemplTool_IsDependentTemplate(TemplClass *tmclass, TemplArg *args) {
- TemplParam *param;
- TemplArg *arg;
- Type *type;
-
- if (!tmclass->templ_parent || tmclass->inst_parent) {
- arg = args;
- param = tmclass->templ__params;
- while (1) {
- if (!arg) {
- CError_ASSERT(988, !param);
- return NULL;
- }
-
- CError_ASSERT(991, param && arg->pid.type == param->pid.type);
-
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- goto done;
- break;
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- goto done;
- break;
- case TPT_TEMPLATE:
- if (!IS_TYPE_CLASS(arg->data.ttargtype) && CTemplTool_IsTemplateArgumentDependentType(arg->data.ttargtype))
- goto done;
- break;
- default:
- CError_FATAL(1008);
- goto done;
- }
-
- arg = arg->next;
- param = param->next;
- }
- }
-done:
- if (cscope_current->theclass == TYPE_CLASS(tmclass) && CTemplTool_IsSameTemplate(tmclass->templ__params, args))
- return TYPE(tmclass);
-
- type = CDecl_NewTemplDepType(TEMPLDEP_TEMPLATE);
- TYPE_TEMPLATE(type)->u.templ.templ = tmclass;
- TYPE_TEMPLATE(type)->u.templ.args = args;
- return type;
-}
-
-Boolean CTemplTool_EqualExprTypes(ENode *a, ENode *b) {
- Object *objA;
- Object *objB;
-
- if (!a || !b)
- return 0;
- if (a->type != b->type)
- return 0;
-
- switch (a->type) {
- case EINTCONST:
- return CInt64_Equal(a->data.intval, b->data.intval);
- case EOBJREF:
- objA = a->data.objref;
- while (objA->datatype == DALIAS)
- objA = objA->u.alias.object;
- objB = b->data.objref;
- while (objB->datatype == DALIAS)
- objB = objB->u.alias.object;
- return objA == objB;
- case EMEMBER:
- return a->data.emember->list == b->data.emember->list;
- case ETEMPLDEP:
- if (a->data.templdep.subtype != b->data.templdep.subtype)
- return 0;
-
- switch (a->data.templdep.subtype) {
- case TDE_PARAM:
- return a->data.templdep.u.pid.nindex == b->data.templdep.u.pid.nindex &&
- a->data.templdep.u.pid.index == b->data.templdep.u.pid.index;
- case TDE_SIZEOF:
- case TDE_ALIGNOF:
- return is_typesame(a->data.templdep.u.typeexpr.type, b->data.templdep.u.typeexpr.type);
- case TDE_CAST:
- return is_typesame(a->data.templdep.u.cast.type, b->data.templdep.u.cast.type) &&
- a->data.templdep.u.cast.qual == b->data.templdep.u.cast.qual;
- case TDE_QUALNAME:
- return is_typesame(TYPE(a->data.templdep.u.qual.type), TYPE(b->data.templdep.u.qual.type)) &&
- a->data.templdep.u.qual.name == b->data.templdep.u.qual.name;
- case TDE_OBJ:
- return a->data.templdep.u.obj == b->data.templdep.u.obj;
- case TDE_ADDRESS_OF:
- return CTemplTool_EqualExprTypes(a->data.templdep.u.monadic, b->data.templdep.u.monadic);
- default:
- CError_FATAL(1086);
- }
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EROTL:
- case EROTR:
- return CTemplTool_EqualExprTypes(a->data.diadic.left, b->data.diadic.left) &&
- CTemplTool_EqualExprTypes(a->data.diadic.right, b->data.diadic.right);
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- return CTemplTool_EqualExprTypes(a->data.monadic, b->data.monadic);
- case ECOND:
- return CTemplTool_EqualExprTypes(a->data.cond.cond, b->data.cond.cond) &&
- CTemplTool_EqualExprTypes(a->data.cond.expr1, b->data.cond.expr1) &&
- CTemplTool_EqualExprTypes(a->data.cond.expr2, b->data.cond.expr2);
- default:
- CError_FATAL(1122);
- return 0;
- }
-}
-
-ENode *CTempl_MakeTemplDepExpr(ENode *left, ENodeType nt, ENode *right) {
- if (!IS_TYPE_TEMPLDEPEXPR(right->rtype)) {
- right = pointer_generation(right);
- if (!ENODE_IS(right, EINTCONST)) {
- CError_Error(CErrorStr348);
- right = nullnode();
- }
- }
-
- if (left) {
- if (!IS_TYPE_TEMPLDEPEXPR(left->rtype)) {
- left = pointer_generation(left);
- if (!ENODE_IS(left, EINTCONST)) {
- CError_Error(CErrorStr348);
- left = nullnode();
- }
- }
-
- left = makediadicnode(left, right, nt);
- } else {
- left = makemonadicnode(right, nt);
- }
-
- left->rtype = &sttemplexpr;
- return left;
-}
-
-void CTemplTool_CheckTemplArgType(Type *type) {
- while (IS_TYPE_POINTER_ONLY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type)) {
- if (IsTempName(TYPE_CLASS(type)->classname) || CScope_IsInLocalNameSpace(TYPE_CLASS(type)->nspace))
- CError_Error(CErrorStr232);
- }
-}
-
-Boolean CTemplTool_EqualArgs(TemplArg *a, TemplArg *b) {
- while (a) {
- if (!b || a->pid.type != b->pid.type)
- return 0;
-
- switch (a->pid.type) {
- case TPT_TYPE:
- if (
- !is_typesame(a->data.typeparam.type, b->data.typeparam.type) ||
- a->data.typeparam.qual != b->data.typeparam.qual
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (!CTemplTool_EqualExprTypes(a->data.paramdecl.expr, b->data.paramdecl.expr))
- return 0;
- break;
- case TPT_TEMPLATE:
- if (!is_typesame(a->data.ttargtype, b->data.ttargtype))
- return 0;
- break;
- default:
- CError_FATAL(1215);
- }
-
- a = a->next;
- b = b->next;
- }
-
- if (b)
- return 0;
-
- return 1;
-}
-
-TemplArg *CTemplTool_MakeGlobalTemplArgCopy(TemplArg *args) {
- TemplArg *firstCopy;
- TemplArg *copy;
-
- firstCopy = NULL;
- while (args) {
- if (firstCopy) {
- copy->next = galloc(sizeof(TemplArg));
- copy = copy->next;
- } else {
- copy = galloc(sizeof(TemplArg));
- firstCopy = copy;
- }
-
- *copy = *args;
- if (copy->pid.type == TPT_NONTYPE && copy->data.paramdecl.expr)
- copy->data.paramdecl.expr = CInline_CopyExpression(copy->data.paramdecl.expr, CopyMode1);
-
- args = args->next;
- }
-
- return firstCopy;
-}
-
-Boolean CTemplTool_TemplDepTypeCompare(TypeTemplDep *a, TypeTemplDep *b) {
- if (a == b)
- return 1;
- if (a->dtype != b->dtype)
- return 0;
-
- switch (a->dtype) {
- case TEMPLDEP_ARGUMENT:
- return a->u.pid.nindex == b->u.pid.nindex &&
- a->u.pid.index == b->u.pid.index;
- case TEMPLDEP_QUALNAME:
- return CTemplTool_TemplDepTypeCompare(a->u.qual.type, b->u.qual.type) &&
- a->u.qual.name == b->u.qual.name;
- case TEMPLDEP_TEMPLATE:
- return a->u.templ.templ == b->u.templ.templ &&
- CTemplTool_EqualArgs(a->u.templ.args, b->u.templ.args);
- case TEMPLDEP_ARRAY:
- return is_typesame(a->u.array.type, b->u.array.type) &&
- CTemplTool_EqualExprTypes(a->u.array.index, b->u.array.index);
- case TEMPLDEP_QUALTEMPL:
- return CTemplTool_TemplDepTypeCompare(a->u.qualtempl.type, b->u.qualtempl.type) &&
- CTemplTool_EqualArgs(a->u.qualtempl.args, b->u.qualtempl.args);
- case TEMPLDEP_BITFIELD:
- return is_typesame(a->u.bitfield.type, b->u.bitfield.type) &&
- CTemplTool_EqualExprTypes(a->u.bitfield.size, b->u.bitfield.size);
- default:
- CError_FATAL(1286);
- return 0;
- }
-}
-
-Type *CTemplTool_DeduceArgDepType(TemplArg *args, Type *type, UInt32 qual, UInt32 *resultQual) {
- TemplArg *arg;
-
- *resultQual = qual;
-
- if (IS_TYPE_TEMPLATE(type) && TYPE_TEMPLATE(type)->dtype == TEMPLDEP_ARGUMENT) {
- arg = args;
- while (1) {
- if (!arg)
- return NULL;
-
- if (
- arg->pid.index == TYPE_TEMPLATE(type)->u.pid.index &&
- arg->pid.nindex == TYPE_TEMPLATE(type)->u.pid.nindex
- )
- break;
-
- arg = arg->next;
- }
-
- CError_ASSERT(1314, arg->pid.type == TPT_TYPE);
- *resultQual |= arg->data.typeparam.qual;
- return arg->data.typeparam.type;
- }
-
- return NULL;
-}
-
-static TemplClassInst *CTemplTool_FindNestedClassInstance(TemplClass *a, TemplClass *b, TemplClassInst *c) {
- TemplClass *array[32];
- TemplClassInst *inst;
- int i;
-
- array[0] = a;
- i = 0;
- while (1) {
- CError_ASSERT(1338, i < 32);
- CError_ASSERT(1339, a = a->templ_parent);
-
- if (a == b)
- break;
-
- CError_ASSERT(1341, a->templ__params == NULL);
-
- array[++i] = a;
- }
-
- while (1) {
- inst = array[i--]->instances;
- while (1) {
- CError_ASSERT(1350, inst);
- if (inst->parent == c)
- break;
- inst = inst->next;
- }
-
- c = inst;
- if (i < 0)
- break;
-
- if ((inst->theclass.flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CTempl_InstantiateTemplateClass(TYPE_CLASS(inst));
- }
-
- return inst;
-}
-
-static TemplClassInst *CTemplTool_FindNestedClass(TemplClass *a, TemplClassInst *b, TemplClass *c) {
- TemplClass *scan;
-
- while (1) {
- for (scan = c->templ_parent; scan; scan = scan->templ_parent) {
- if (scan == a)
- return CTemplTool_FindNestedClassInstance(c, a, b);
- }
-
- a = a->templ_parent;
- if (!a)
- break;
-
- b = b->parent;
- CError_ASSERT(1377, b);
- }
-
- return NULL;
-}
-
-static Type *CTemplTool_FindTemplateInstance(TypeDeduce *deduce, TemplClass *templ) {
- TemplClass *scantempl;
- TemplClass *dtempl;
- TemplClassInst *scaninst;
- TemplClassInst *dinst;
-
- dtempl = deduce->tmclass;
- CError_ASSERT(1393, dtempl);
-
- dinst = deduce->inst;
- if (!dinst) {
- if (!dtempl->templ_parent || !dtempl->inst_parent)
- return TYPE(templ);
-
- dtempl = dtempl->templ_parent;
- dinst = deduce->tmclass->inst_parent;
- }
-
- scantempl = dtempl;
- scaninst = dinst;
- while (1) {
- if (scantempl == templ)
- return TYPE(scaninst);
-
- if (!scantempl->templ_parent && scantempl->pspec_owner)
- scantempl = scantempl->pspec_owner;
-
- scantempl = scantempl->templ_parent;
- if (!scantempl)
- break;
-
- CError_ASSERT(1416, scaninst = scaninst->parent);
- }
-
- if (dtempl->flags & TEMPLCLASS_FLAGS_2) {
- scantempl = TEMPL_CLASS(dtempl->theclass.nspace->theclass);
- CError_ASSERT(1422, scantempl->theclass.flags & CLASS_IS_TEMPL);
- scaninst = dinst;
-
- while (1) {
- if (scantempl == templ)
- return TYPE(scaninst);
-
- scantempl = scantempl->templ_parent;
- if (!scantempl)
- break;
-
- CError_ASSERT(1430, scaninst = scaninst->parent);
- }
- }
-
- if (!templ->templ__params && (scaninst = CTemplTool_FindNestedClass(dtempl, dinst, templ)))
- return TYPE(scaninst);
-
- CError_FATAL(1477);
- return NULL;
-}
-
-static ENode *CTemplTool_DeduceExprCheck(ENode *expr) {
- if (expr->type != EINTCONST) {
- CError_Error(CErrorStr348);
- expr = nullnode();
- }
-
- return expr;
-}
-
-static ENodeList *CTemplTool_DeduceExprList(TypeDeduce *deduce, ENodeList *list) {
- ENodeList *resultList;
- ENodeList *last;
-
- resultList = NULL;
- while (list) {
- if (resultList) {
- last->next = lalloc(sizeof(ENodeList));
- last = last->next;
- } else {
- last = lalloc(sizeof(ENodeList));
- resultList = last;
- }
-
- *last = *list;
- last->node = CTemplTool_DeduceExpr(deduce, last->node);
-
- list = list->next;
- }
-
- return resultList;
-}
-
-ENode *CTemplTool_DeduceExpr(TypeDeduce *deduce, ENode *expr) {
- TemplArg *arg;
- TemplClassInst *inst;
- ENode *newExpr;
- NameSpaceObjectList *nsObjectList;
- TStreamElement *saved;
- NameResult pr;
- Type *type;
- UInt32 qual;
-
- if (!CTemplTool_IsTemplateArgumentDependentExpression(expr)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-
- switch (expr->type) {
- case ETEMPLDEP:
- switch (expr->data.templdep.subtype) {
- case TDE_PARAM:
- if (deduce->x15 && expr->data.templdep.u.pid.nindex == deduce->nindex) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-
- for (arg = deduce->args; arg; arg = arg->next) {
- if (
- arg->pid.index == expr->data.templdep.u.pid.index &&
- arg->pid.nindex == expr->data.templdep.u.pid.nindex
- )
- {
- CError_ASSERT(1562, arg->pid.type == TPT_NONTYPE && arg->data.paramdecl.expr);
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *arg->data.paramdecl.expr;
- return newExpr;
- }
- }
-
- for (inst = deduce->inst; inst; inst = inst->parent) {
- for (arg = inst->inst_args; arg; arg = arg->next) {
- if (
- arg->pid.index == expr->data.templdep.u.pid.index &&
- arg->pid.nindex == expr->data.templdep.u.pid.nindex
- )
- {
- CError_ASSERT(1575, arg->pid.type == TPT_NONTYPE && arg->data.paramdecl.expr);
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *arg->data.paramdecl.expr;
- return newExpr;
- }
- }
- }
-
- CError_FATAL(1582);
-
- case TDE_SIZEOF:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.typeexpr.type), &qual);
- CDecl_CompleteType(type);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.typeexpr.type = type;
- return newExpr;
- }
-
- return intconstnode(CABI_GetSizeTType(), type->size);
-
- case TDE_ALIGNOF:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.typeexpr.type), &qual);
- CDecl_CompleteType(type);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.typeexpr.type = type;
- return newExpr;
- }
-
- return intconstnode(CABI_GetSizeTType(), CMach_GetTypeAlign(type));
-
- case TDE_CAST:
- qual = expr->data.templdep.u.cast.qual;
- type = CTemplTool_DeduceTypeCopy(deduce, expr->data.templdep.u.cast.type, &qual);
- return CExpr_DoExplicitConversion(type, qual, CTemplTool_DeduceExprList(deduce, expr->data.templdep.u.cast.args));
-
- case TDE_QUALNAME:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.qual.type), &qual);
-
- if (IS_TYPE_CLASS(type)) {
- CDecl_CompleteType(type);
- if (CScope_FindQualifiedClassMember(&pr, TYPE_CLASS(type), expr->data.templdep.u.qual.name))
- return pointer_generation(CExpr_MakeNameLookupResultExpr(&pr));
-
- CError_Error(CErrorStr150, expr->data.templdep.u.qual.name->name);
- } else if (IS_TYPE_TEMPLATE(type) && !deduce->inst) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.qual.type = TYPE_TEMPLATE(type);
- return newExpr;
- } else {
- CError_Error(CErrorStr340, expr->data.templdep.u.qual.name->name);
- }
-
- return nullnode();
-
- case TDE_OBJ:
- type = CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(expr->data.templdep.u.obj->nspace->theclass));
- CError_ASSERT(1651, type && IS_TYPE_CLASS(type));
-
- nsObjectList = CScope_GetLocalObject(TYPE_CLASS(type)->nspace, expr->data.templdep.u.obj->name);
- CError_ASSERT(1654, nsObjectList);
-
- memclrw(&pr, sizeof(pr));
- pr.obj_10 = nsObjectList->object;
- return pointer_generation(CExpr_MakeNameLookupResultExpr(&pr));
-
- case TDE_SOURCEREF:
- CError_LockErrorPos(expr->data.templdep.u.sourceref.token, &saved);
- newExpr = CTemplTool_DeduceExpr(deduce, expr->data.templdep.u.sourceref.expr);
- CError_UnlockErrorPos(&saved);
- return newExpr;
-
- case TDE_ADDRESS_OF:
- return getnodeaddress(CTemplTool_DeduceExpr(deduce, expr->data.templdep.u.monadic), 1);
-
- default:
- CError_FATAL(1671);
- }
- case EFUNCCALL:
- newExpr = CExpr_PointerGeneration(CTemplTool_DeduceExpr(deduce, expr->data.funccall.funcref));
- return CExpr_MakeFunctionCall(newExpr, CTemplTool_DeduceExprList(deduce, expr->data.funccall.args));
- case ELOGNOT:
- return CExpr_New_ELOGNOT_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EMONMIN:
- return CExpr_New_EMONMIN_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EBINNOT:
- return CExpr_New_EBINNOT_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EMUL:
- case EDIV:
- case EMODULO:
- 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 EROTL:
- case EROTR:
- return CExpr_NewDyadicNode(
- CTemplTool_DeduceExpr(deduce, expr->data.diadic.left),
- expr->type,
- CTemplTool_DeduceExpr(deduce, expr->data.diadic.right));
- case ECOND:
- return CExpr_New_ECOND_Node(
- CTemplTool_DeduceExpr(deduce, expr->data.cond.cond),
- CTemplTool_DeduceExpr(deduce, expr->data.cond.expr1),
- CTemplTool_DeduceExpr(deduce, expr->data.cond.expr2));
- default:
- CError_FATAL(1727);
- case EINTCONST:
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-}
-
-ENode *CTemplTool_DeduceDefaultArg(Object *func, ENode *expr) {
- TypeDeduce deduce;
-
- memclrw(&deduce, sizeof(deduce));
- CError_ASSERT(1747, IS_TYPE_FUNC(func->type));
-
- if (func->u.func.inst)
- deduce.args = func->u.func.inst->args;
-
- if ((TYPE_FUNC(func->type)->flags & FUNC_METHOD) && (TYPE_METHOD(func->type)->theclass->flags & CLASS_IS_TEMPL_INST)) {
- deduce.inst = TEMPL_CLASS_INST(TYPE_METHOD(func->type)->theclass);
- deduce.tmclass = TEMPL_CLASS_INST(TYPE_METHOD(func->type)->theclass)->templ;
- }
-
- return CTemplTool_DeduceExpr(&deduce, expr);
-}
-
-static TemplClass *CTemplTool_FindNestedTemplateInstance(TypeDeduce *deduce, TemplClass *templ) {
- TemplClass *dtempl;
- TemplClassInst *dinst;
- Type *type;
-
- if (templ->inst_parent)
- return templ;
-
- CError_ASSERT(1776, (dtempl = deduce->tmclass) && (dinst = deduce->inst));
-
- while (1) {
- if (
- templ->templ_parent == dtempl &&
- (type = CScope_GetLocalTagType(dinst->theclass.nspace, templ->theclass.classname)) &&
- IS_TEMPL_CLASS(type) &&
- TEMPL_CLASS(type)->templ_parent == templ->templ_parent
- )
- return TEMPL_CLASS(type);
-
- dtempl = dtempl->templ_parent;
- if (!dtempl)
- break;
-
- dinst = dinst->parent;
- CError_ASSERT(1790, dinst);
- }
-
- return templ;
-}
-
-static Type *CTemplTool_DeduceClassInstanceCopy(TypeDeduce *deduce, TemplClass *templ, TemplArg *args) {
- TemplArg *arg;
- TemplArg *deducedArgs;
- TemplArg *last;
- TemplParam *param;
- UInt32 qual;
- Type *type;
-
- if (templ->templ_parent)
- templ = CTemplTool_FindNestedTemplateInstance(deduce, templ);
-
- arg = args;
- deducedArgs = NULL;
- param = templ->templ__params;
-
- while (arg) {
- if (deducedArgs) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- last = galloc(sizeof(TemplArg));
- deducedArgs = last;
- }
-
- *last = *arg;
-
- if (!param || param->pid.type != last->pid.type) {
- CError_Error(CErrorStr374);
- return &stvoid;
- }
-
- last->pid = param->pid;
- param = param->next;
-
- switch (last->pid.type) {
- case TPT_TYPE:
- last->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, last->data.typeparam.type, &last->data.typeparam.qual);
- break;
-
- case TPT_NONTYPE:
- if (!last->data.paramdecl.expr) {
- CError_FATAL(1873);
- } else if (CTemplTool_IsTemplateArgumentDependentExpression(last->data.paramdecl.expr)) {
- last->data.paramdecl.expr = pointer_generation(CTemplTool_DeduceExpr(deduce, last->data.paramdecl.expr));
- last->data.paramdecl.expr = CInline_CopyExpression(last->data.paramdecl.expr, CopyMode1);
- }
- break;
-
- case TPT_TEMPLATE:
- qual = 0;
- last->data.ttargtype = CTemplTool_DeduceTypeCopy(deduce, last->data.ttargtype, &qual);
- break;
-
- default:
- CError_FATAL(1891);
- }
-
- arg = arg->next;
- }
-
- for (arg = deducedArgs; arg; arg = arg->next) {
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- break;
- continue;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- break;
-
- switch (arg->data.paramdecl.expr->type) {
- case EINTCONST:
- case EOBJLIST:
- case EMEMBER:
- break;
- case EOBJREF:
- if (CParser_HasInternalLinkage2(arg->data.paramdecl.expr->data.objref))
- CError_Error(CErrorStr357);
- break;
- default:
- CError_Error(CErrorStr371);
- arg->data.paramdecl.expr = nullnode();
- break;
- }
- continue;
-
- case TPT_TEMPLATE:
- if (!IS_TYPE_CLASS(arg->data.ttargtype) && CTemplTool_IsTemplateArgumentDependentType(arg->data.ttargtype))
- break;
- continue;
-
- default:
- CError_FATAL(1937);
- }
-
- break;
- }
-
- if (arg) {
- type = CDecl_NewTemplDepType(TEMPLDEP_TEMPLATE);
- TYPE_TEMPLATE(type)->u.templ.templ = templ;
- TYPE_TEMPLATE(type)->u.templ.args = deducedArgs;
- return type;
- }
-
- if ((type = CTemplTool_IsDependentTemplate(templ, deducedArgs)))
- return type;
-
- return TYPE(CTemplClass_GetInstance(templ, deducedArgs, NULL));
-}
-
-static TemplArg *CTemplTool_FindTemplArg(TemplArg *args, TemplParamID pid) {
- while (args) {
- if (args->pid.index == pid.index && args->pid.nindex == pid.nindex) {
- CError_ASSERT(1984, pid.type == args->pid.type);
- return args;
- }
- args = args->next;
- }
-
- return NULL;
-}
-
-static TemplArg *CTemplTool_DeduceTemplArg(TypeDeduce *deduce, TemplParamID pid) {
- TemplClass *tmclass;
- TemplClassInst *inst;
- TemplArg *arg;
-
- if ((arg = CTemplTool_FindTemplArg(deduce->args, pid)))
- return arg;
-
- tmclass = deduce->tmclass;
- CError_ASSERT(2008, tmclass);
-
- inst = deduce->inst;
- if (!inst) {
- CError_ASSERT(2011, tmclass->templ_parent && tmclass->inst_parent);
- inst = deduce->tmclass->inst_parent;
- }
-
- while (1) {
- if ((arg = CTemplTool_FindTemplArg(inst->inst_args, pid)))
- return arg;
-
- inst = inst->parent;
- CError_ASSERT(2022, inst);
- }
-}
-
-static Type *CTemplTool_DeduceArrayCopy(TypeDeduce *deduce, Type *type, ENode *index, UInt32 *resultQual) {
- if (CTemplTool_IsTemplateArgumentDependentType(type))
- type = CTemplTool_DeduceTypeCopy(deduce, type, resultQual);
-
- index = CTemplTool_DeduceExpr(deduce, index);
-
- if (ENODE_IS(index, EINTCONST)) {
- if (CInt64_IsNegative(&index->data.intval)) {
- CError_Error(CErrorStr124);
- index->data.intval = cint64_one;
- }
-
- if (!CDecl_CheckArrayIntegr(type))
- type = TYPE(&stsignedchar);
-
- type = CDecl_NewArrayType(type, type->size * CInt64_GetULong(&index->data.intval));
- } else {
- if (!deduce->x16)
- CError_Error(CErrorStr124);
- }
-
- return type;
-}
-
-static Type *CTemplTool_DeduceBitfieldCopy(TypeDeduce *deduce, Type *type, ENode *size, UInt32 *resultQual) {
- TypeBitfield *tbitfield;
- short sizeval;
- short maxsize;
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- UInt32 qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, type, &qual);
- }
-
- if (!IS_TYPE_INT_OR_ENUM(type)) {
- CError_Error(CErrorStr138);
- type = TYPE(&stunsignedint);
- }
-
- switch (type->size) {
- case 1:
- maxsize = 8;
- break;
- case 2:
- maxsize = 16;
- break;
- case 4:
- maxsize = 32;
- break;
- default:
- CError_Error(CErrorStr138);
- return type;
- }
-
- if (!ENODE_IS(size, EINTCONST)) {
- size = CTemplTool_DeduceExpr(deduce, size);
- if (!ENODE_IS(size, EINTCONST)) {
- CError_Error(CErrorStr124);
- return type;
- }
- }
-
- sizeval = CInt64_GetULong(&size->data.intval);
- if (sizeval > maxsize || CInt64_IsNegative(&size->data.intval)) {
- CError_Error(CErrorStr138);
- sizeval = 1;
- }
-
- tbitfield = galloc(sizeof(TypeBitfield));
- memclrw(tbitfield, sizeof(TypeBitfield));
-
- tbitfield->type = TYPEBITFIELD;
- tbitfield->size = type->size;
- tbitfield->bitfieldtype = type;
- tbitfield->bitlength = sizeval;
-
- return TYPE(tbitfield);
-}
-
-static Type *CTemplTool_DeduceTemplDepType(TypeDeduce *deduce, TypeTemplDep *tdt, UInt32 *resultQual) {
- Type *type;
- UInt32 qual;
- TemplArg *arg;
-
- qual = 0;
-
- if (deduce->x14) {
- type = CTemplTool_GetSelfRefTemplate(TYPE(tdt));
- if (type && type == TYPE(deduce->tmclass))
- return type;
-
- switch (tdt->dtype) {
- case TEMPLDEP_ARGUMENT:
- return TYPE(tdt);
-
- case TEMPLDEP_QUALNAME:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qual.type), &qual);
- if (type == TYPE(tdt->u.qual.type))
- return TYPE(tdt);
-
- if (!IS_TYPE_CLASS(type)) {
- TypeTemplDep *tdtCopy;
- CError_ASSERT(2157, IS_TYPE_TEMPLATE(type));
- tdtCopy = galloc(sizeof(TypeTemplDep));
- *tdtCopy = *tdt;
- tdtCopy->u.qual.type = TYPE_TEMPLATE(type);
- return TYPE(tdtCopy);
- } else if ((type = CScope_GetType(TYPE_CLASS(type)->nspace, tdt->u.qual.name, resultQual))) {
- return type;
- } else {
- CError_Error(CErrorStr150, tdt->u.qual.name->name);
- return TYPE(tdt);
- }
-
- case TEMPLDEP_TEMPLATE:
- for (arg = tdt->u.templ.args; arg; arg = arg->next) {
- if (arg->pid.type == TPT_TYPE)
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- }
- return TYPE(tdt);
-
- case TEMPLDEP_ARRAY:
- tdt->u.array.type = CTemplTool_DeduceTypeCopy(deduce, tdt->u.array.type, &qual);
- return TYPE(tdt);
-
- case TEMPLDEP_QUALTEMPL:
- tdt->u.qualtempl.type = TYPE_TEMPLATE(CTemplTool_DeduceTemplDepType(deduce, tdt->u.qualtempl.type, &qual));
- for (arg = tdt->u.qualtempl.args; arg; arg = arg->next) {
- if (arg->pid.type == TPT_TYPE)
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- }
- return TYPE(tdt);
-
- case TEMPLDEP_BITFIELD:
- tdt->u.bitfield.type = CTemplTool_DeduceTypeCopy(deduce, tdt->u.bitfield.type, &qual);
- return TYPE(tdt);
- }
- } else {
- switch (tdt->dtype) {
- case TEMPLDEP_ARGUMENT:
- if (deduce->x15 && tdt->u.pid.nindex == deduce->nindex)
- return TYPE(tdt);
-
- arg = CTemplTool_DeduceTemplArg(deduce, tdt->u.pid);
- if (arg->pid.type == TPT_TEMPLATE) {
- CError_ASSERT(2222, IS_TEMPL_CLASS(arg->data.typeparam.type));
- *resultQual = arg->data.typeparam.qual;
- return arg->data.typeparam.type;
- }
-
- CError_ASSERT(2226, arg->pid.type == TPT_TYPE);
- *resultQual = arg->data.typeparam.qual;
- return arg->data.typeparam.type;
-
- case TEMPLDEP_QUALNAME:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qual.type), &qual);
- if (IS_TYPE_CLASS(type)) {
- CDecl_CompleteType(type);
- if ((type = CScope_GetType(TYPE_CLASS(type)->nspace, tdt->u.qual.name, resultQual))) {
- return type;
- } else {
- CError_Error(CErrorStr150, tdt->u.qual.name->name);
- }
- } else {
- if ((deduce->x15 || !deduce->inst) && IS_TYPE_TEMPLATE(type)) {
- TypeTemplDep *tdtCopy = galloc(sizeof(TypeTemplDep));
- *tdtCopy = *tdt;
- tdtCopy->u.qual.type = TYPE_TEMPLATE(type);
- return TYPE(tdtCopy);
- } else {
- CError_Error(CErrorStr340, tdt->u.qual.name->name);
- }
- }
- return TYPE(&stsignedint);
-
- case TEMPLDEP_TEMPLATE:
- return CTemplTool_DeduceClassInstanceCopy(deduce, tdt->u.templ.templ, tdt->u.templ.args);
-
- case TEMPLDEP_ARRAY:
- return CTemplTool_DeduceArrayCopy(deduce, tdt->u.array.type, tdt->u.array.index, resultQual);
-
- case TEMPLDEP_QUALTEMPL:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qualtempl.type), &qual);
- if (!IS_TEMPL_CLASS(type)) {
- CError_Error(CErrorStr121);
- return TYPE(&stsignedint);
- }
- return CTemplTool_DeduceClassInstanceCopy(deduce, TEMPL_CLASS(type), tdt->u.qualtempl.args);
-
- case TEMPLDEP_BITFIELD:
- return CTemplTool_DeduceBitfieldCopy(deduce, tdt->u.bitfield.type, tdt->u.bitfield.size, resultQual);
- }
- }
-
- CError_FATAL(2275);
- return NULL;
-}
-
-static Type *CTemplTool_DeduceTypeQualCopy(TypeDeduce *deduce, Type *type, UInt32 *resultQual) {
- Type *innerType;
- UInt32 qual;
- UInt32 innerQual;
- TypePointer *newPtr;
-
- qual = *resultQual;
-
- if (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_TEMPLATE(TPTR_TARGET(type))) {
- innerQual = 0;
- innerType = CTemplTool_DeduceTemplDepType(deduce, TYPE_TEMPLATE(TPTR_TARGET(type)), &innerQual);
-
- newPtr = galloc(sizeof(TypePointer));
- *newPtr = *TYPE_POINTER(type);
-
- if (IS_TYPE_POINTER_ONLY(innerType)) {
- newPtr->target = galloc(sizeof(TypePointer));
- *TYPE_POINTER(newPtr->target) = *TYPE_POINTER(innerType);
- *resultQual = innerQual & (Q_CONST | Q_VOLATILE);
- TPTR_QUAL(newPtr->target) |= qual & (Q_CONST | Q_VOLATILE);
- } else if (IS_TYPE_MEMBERPOINTER(innerType)) {
- newPtr->target = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(newPtr->target) = *TYPE_MEMBER_POINTER(innerType);
- *resultQual = innerQual & (Q_CONST | Q_VOLATILE);
- TYPE_MEMBER_POINTER(newPtr->target)->qual |= qual & (Q_CONST | Q_VOLATILE);
- } else {
- newPtr->target = innerType;
- *resultQual = (qual | innerQual) & (Q_CONST | Q_VOLATILE);
- }
-
- return TYPE(newPtr);
- }
-
- return CTemplTool_DeduceTypeCopy(deduce, type, resultQual);
-}
-
-FuncArg *CTemplTool_DeduceArgCopy(TypeDeduce *deduce, FuncArg *args) {
- FuncArg *resultArgs;
- FuncArg *last;
-
- if (args == &oldstyle || args == &elipsis)
- return args;
-
- resultArgs = NULL;
-
- while (args) {
- if (args == &elipsis) {
- last->next = args;
- break;
- }
-
- if (resultArgs) {
- last->next = galloc(sizeof(FuncArg));
- last = last->next;
- } else {
- last = galloc(sizeof(FuncArg));
- resultArgs = last;
- }
-
- *last = *args;
- last->type = CTemplTool_DeduceTypeQualCopy(deduce, last->type, &last->qual);
- CanCreateObject(last->type);
-
- args = args->next;
- }
-
- return resultArgs;
-}
-
-static ExceptSpecList *CTemplTool_DeduceExSpecCopy(TypeDeduce *deduce, ExceptSpecList *exspec) {
- ExceptSpecList *copy;
-
- copy = galloc(sizeof(ExceptSpecList));
- *copy = *exspec;
-
- if (copy->type && CTemplTool_IsTemplateArgumentDependentType(copy->type))
- copy->type = CTemplTool_DeduceTypeCopy(deduce, copy->type, &copy->qual);
-
- if (copy->next)
- copy->next = CTemplTool_DeduceExSpecCopy(deduce, copy->next);
-
- return copy;
-}
-
-Type *CTemplTool_DeduceTypeCopy(TypeDeduce *deduce, Type *type, UInt32 *resultQual) {
- TemplClassInst *inst;
- Type *deduced;
- UInt32 qual2;
- UInt32 qual;
-
- switch (type->type) {
- case TYPETEMPLATE:
- qual = 0;
- deduced = CTemplTool_DeduceTemplDepType(deduce, TYPE_TEMPLATE(type), &qual);
- if (*resultQual & (Q_CONST | Q_VOLATILE)) {
- if (IS_TYPE_POINTER_ONLY(deduced)) {
- TypePointer *newPtr = galloc(sizeof(TypePointer));
- *newPtr = *TYPE_POINTER(deduced);
- newPtr->qual |= *resultQual & (Q_CONST | Q_VOLATILE);
- *resultQual &= ~(Q_CONST | Q_VOLATILE);
- deduced = TYPE(newPtr);
- } else if (IS_TYPE_MEMBERPOINTER(deduced)) {
- TypeMemberPointer *newPtr = galloc(sizeof(TypeMemberPointer));
- *newPtr = *TYPE_MEMBER_POINTER(deduced);
- newPtr->qual |= *resultQual & (Q_CONST | Q_VOLATILE);
- *resultQual &= ~(Q_CONST | Q_VOLATILE);
- deduced = TYPE(newPtr);
- }
- }
- *resultQual |= qual;
- return deduced;
-
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPESTRUCT:
- return type;
-
- case TYPEENUM:
- if (
- TYPE_ENUM(type)->nspace->theclass &&
- (TYPE_ENUM(type)->nspace->theclass->flags & CLASS_IS_TEMPL) &&
- !deduce->x14
- )
- {
- CError_ASSERT(2471, TYPE_ENUM(type)->enumname);
- inst = TEMPL_CLASS_INST(CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(TYPE_ENUM(type)->nspace->theclass)));
- CError_ASSERT(2473, inst && inst->theclass.type == TYPECLASS);
-
- CDecl_CompleteType(TYPE(inst));
- type = CScope_GetLocalTagType(inst->theclass.nspace, TYPE_ENUM(type)->enumname);
- CError_ASSERT(2477, type);
- return type;
- }
- return type;
-
- case TYPECLASS:
- if (!deduce->x14) {
- if (TYPE_CLASS(type)->flags & CLASS_IS_TEMPL)
- return CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(type));
-
- if (TYPE_CLASS(type)->nspace->theclass && (TYPE_CLASS(type)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- CError_ASSERT(2492, deduce->inst);
- CError_ASSERT(2493, TYPE_CLASS(type)->classname);
-
- type = CScope_GetLocalTagType(deduce->inst->theclass.nspace, TYPE_CLASS(type)->classname);
- CError_ASSERT(2496, type);
- return type;
- }
- }
-
- return type;
-
- case TYPEARRAY: {
- SInt32 elements;
-
- elements = TPTR_TARGET(type)->size;
- if (elements > 0)
- elements = type->size / elements;
-
- deduced = galloc(sizeof(TypePointer));
- *TYPE_POINTER(deduced) = *TYPE_POINTER(type);
- TPTR_TARGET(deduced) = CTemplTool_DeduceTypeCopy(deduce, TPTR_TARGET(type), resultQual);
-
- do {
- type = TPTR_TARGET(type);
- } while (IS_TYPE_ARRAY(type));
-
- if (IS_TYPE_TEMPLATE(type)) {
- CDecl_CompleteType(TPTR_TARGET(deduced));
- deduced->size = TPTR_TARGET(deduced)->size * elements;
- }
-
- return deduced;
- }
-
- case TYPEPOINTER:
- deduced = galloc(sizeof(TypePointer));
- *TYPE_POINTER(deduced) = *TYPE_POINTER(type);
- TPTR_TARGET(deduced) = CTemplTool_DeduceTypeCopy(deduce, TPTR_TARGET(type), resultQual);
- return deduced;
-
- case TYPEBITFIELD:
- deduced = galloc(sizeof(TypeBitfield));
- *TYPE_BITFIELD(deduced) = *TYPE_BITFIELD(type);
- TYPE_BITFIELD(deduced)->bitfieldtype = CTemplTool_DeduceTypeCopy(deduce, TYPE_BITFIELD(type)->bitfieldtype, resultQual);
- return deduced;
-
- case TYPEMEMBERPOINTER:
- deduced = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(deduced) = *TYPE_MEMBER_POINTER(type);
- TYPE_MEMBER_POINTER(deduced)->ty1 = CTemplTool_DeduceTypeCopy(deduce, TYPE_MEMBER_POINTER(type)->ty1, resultQual);
- qual2 = 0;
- TYPE_MEMBER_POINTER(deduced)->ty2 = CTemplTool_DeduceTypeCopy(deduce, TYPE_MEMBER_POINTER(type)->ty2, &qual2);
-
- if (
- !IS_TYPE_CLASS(TYPE_MEMBER_POINTER(deduced)->ty2) &&
- !deduce->x14 &&
- !deduce->x15 &&
- !deduce->x16
- )
- {
- CError_Error(CErrorStr232);
- return TYPE_MEMBER_POINTER(deduced)->ty1;
- }
- return deduced;
-
- case TYPEFUNC:
- if (TYPE_FUNC(type)->flags & FUNC_METHOD) {
- qual2 = 0;
- deduced = galloc(sizeof(TypeMemberFunc));
- *TYPE_METHOD(deduced) = *TYPE_METHOD(type);
- TYPE_METHOD(deduced)->funcid = 0;
- TYPE_METHOD(deduced)->theclass = TYPE_CLASS(CTemplTool_DeduceTypeQualCopy(deduce, TYPE(TYPE_METHOD(type)->theclass), &qual2));
- CError_ASSERT(2556, IS_TYPE_CLASS(TYPE_METHOD(deduced)->theclass));
- } else {
- deduced = galloc(sizeof(TypeFunc));
- *TYPE_FUNC(deduced) = *TYPE_FUNC(type);
- }
-
- TYPE_FUNC(deduced)->flags &= ~FUNC_IS_TEMPL;
-
- qual2 = TYPE_FUNC(type)->qual;
- TYPE_FUNC(deduced)->functype = CTemplTool_DeduceTypeQualCopy(deduce, TYPE_FUNC(type)->functype, &qual2);
- TYPE_FUNC(deduced)->qual = qual2;
-
- TYPE_FUNC(deduced)->args = CTemplTool_DeduceArgCopy(deduce, TYPE_FUNC(type)->args);
- if (TYPE_FUNC(type)->exspecs)
- TYPE_FUNC(deduced)->exspecs = CTemplTool_DeduceExSpecCopy(deduce, TYPE_FUNC(type)->exspecs);
-
- CDecl_SetResultReg(TYPE_FUNC(deduced));
- return deduced;
-
- case TYPETEMPLDEPEXPR:
- CError_Error(CErrorStr190);
- return &stvoid;
-
- default:
- CError_FATAL(2580);
- return NULL;
- }
-}
-
-Type *CTemplTool_ResolveMemberSelfRefs(TemplClass *templ, Type *type, UInt32 *resultQual) {
- TypeDeduce deduce;
-
- memclrw(&deduce, sizeof(deduce));
- deduce.tmclass = templ;
- deduce.x14 = 1;
-
- if (IS_TYPE_FUNC(type)) {
- TYPE_FUNC(type)->functype = CTemplTool_DeduceTypeCopy(&deduce, TYPE_FUNC(type)->functype, &TYPE_FUNC(type)->qual);
- TYPE_FUNC(type)->args = CTemplTool_DeduceArgCopy(&deduce, TYPE_FUNC(type)->args);
- CDecl_SetResultReg(TYPE_FUNC(type));
- } else {
- type = CTemplTool_DeduceTypeCopy(&deduce, type, resultQual);
- }
-
- return type;
-}
-
-Boolean CTemplTool_IsSameTemplateType(Type *a, Type *b) {
- return CTemplTool_GetSelfRefTemplate(b) == a;
-}
diff --git a/compiler_and_linker/unsorted/CodeGen.c b/compiler_and_linker/unsorted/CodeGen.c
deleted file mode 100644
index 986bddc..0000000
--- a/compiler_and_linker/unsorted/CodeGen.c
+++ /dev/null
@@ -1,2437 +0,0 @@
-#include "compiler/CodeGen.h"
-#include "compiler/CCompiler.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CMangler.h"
-#include "compiler/COptimizer.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/Coloring.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/uDump.h"
-#include "compiler/Exceptions.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/Intrinsics.h"
-#include "compiler/InstrSelection.h"
-#include "compiler/GlobalOptimizer.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeAssembly.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Peephole.h"
-#include "compiler/PPCError.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/Scheduler.h"
-#include "compiler/StackFrame.h"
-#include "compiler/Switch.h"
-#include "compiler/TOC.h"
-#include "compiler/ValueNumbering.h"
-#include "compiler/enode.h"
-#include "compiler/objc.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/tokens.h"
-#include "compiler/types.h"
-
-static Macro powcM;
-static Macro __powcM;
-static Macro ppc_cpu;
-static Macro profM;
-static Macro hostM;
-static Macro bendM;
-static Macro _ppc_M;
-static Macro longI;
-static Macro IEEED;
-Macro vecM;
-Macro altivecM;
-static Macro macM2;
-static Macro appleM;
-static Macro optM;
-static Macro alignM;
-static Macro _machM;
-static Macro archM;
-static Macro dynM;
-static Macro ppcM;
-Object *gFunction;
-static ObjectList *temps;
-CLabel *returnlabel;
-CLabel *cleanreturnlabel;
-Boolean needs_cleanup;
-Statement *current_statement;
-int has_catch_blocks;
-int disable_optimizer;
-SInt32 current_linenumber;
-Boolean has_altivec_arrays;
-short high_reg;
-short low_reg;
-short high_offset;
-short low_offset;
-short low_reg2;
-short high_reg2;
-PCodeLabel *pic_base_pcodelabel;
-Object *dyld_stub_binding_helper;
-Object *rt_cvt_fp2unsigned;
-Object *rt_profile_entry;
-Object *rt_profile_exit;
-Object *rt_div2i;
-Object *rt_div2u;
-Object *rt_mod2i;
-Object *rt_mod2u;
-Object *rt_shr2i;
-Object *rt_shr2u;
-Object *rt_shl2i;
-Object *rt_cvt_ull_dbl;
-Object *rt_cvt_sll_dbl;
-Object *rt_cvt_ull_flt;
-Object *rt_cvt_sll_flt;
-Object *rt_cvt_dbl_usll;
-static heaperror_t saveheaperror;
-
-enum {
- GPRLimit = 10,
- FPRLimit = 13,
- VRLimit = 13
-};
-
-// forward decls
-static void CodeGen_heaperror(void);
-
-VarInfo *CodeGen_GetNewVarInfo(void) {
- VarInfo *vi;
-
- vi = lalloc(sizeof(VarInfo));
- memclrw(vi, sizeof(VarInfo));
-
- vi->deftoken = *CPrep_CurStreamElement();
- vi->varnumber = localcount++;
-
- return vi;
-}
-
-Object *maketemporary(Type *type) {
- ObjectList *list;
- Object *obj;
-
- for (list = temps; list; list = list->next) {
- obj = list->object;
- if (obj->u.var.uid == 0 && obj->type == type) {
- obj->u.var.uid = 1;
- return obj;
- }
- }
-
- obj = lalloc(sizeof(Object));
- memclrw(obj, sizeof(Object));
- obj->otype = OT_OBJECT;
- obj->access = ACCESSPUBLIC;
- obj->datatype = DLOCAL;
- obj->type = type;
- obj->name = CParser_GetUniqueName();
- obj->u.var.info = CodeGen_GetNewVarInfo();
- obj->u.var.uid = 1;
-
- list = lalloc(sizeof(ObjectList));
- memclrw(list, sizeof(ObjectList));
- list->next = temps;
- list->object = obj;
- temps = list;
-
- return obj;
-}
-
-static void free_temporaries(void) {
- ObjectList *list;
-
- for (list = temps; list; list = list->next)
- list->object->u.var.uid = 0;
-}
-
-static void allocate_temporaries(void) {
- ObjectList *list;
-
- for (list = temps; list; list = list->next)
- assign_local_memory(list->object);
-}
-
-void process_arguments(ArgumentProcessor func, Boolean flag) {
- short gpr = 3;
- short fpr = 1;
- short vr = 2;
- Type *type;
- ObjectList *list;
-
- for (list = arguments; list; list = list->next) {
- type = list->object->type;
- if (IS_TYPE_FLOAT(type)) {
- func(list->object, (fpr <= FPRLimit) ? fpr : 0);
- fpr++;
- if (type->size == 4)
- gpr++;
- else
- gpr += 2;
- } else if (IS_TYPE_VECTOR(type)) {
- func(list->object, (vr <= VRLimit) ? vr : 0);
- vr++;
- if (flag) {
- if ((vr - 1) == 2)
- gpr = 9;
- else if ((vr - 1) > 2)
- gpr = 11;
- }
- } else {
- func(list->object, (gpr <= GPRLimit) ? gpr : 0);
- if (TYPE_FITS_IN_REGISTER(type)) {
- if (type->size <= 4)
- gpr += 1;
- else
- gpr += 2;
- } else {
- gpr += (type->size >> 2);
- if (type->size & 3)
- gpr++;
- }
- }
- }
-
- last_argument_register[RegClass_GPR] = gpr - 1;
- last_argument_register[RegClass_FPR] = fpr - 1;
- last_argument_register[RegClass_VR] = vr - 1;
- if (flag)
- move_varargs_to_memory();
-}
-
-static void retain_argument_register(Object *obj, short reg) {
- VarInfo *vi = Registers_GetVarInfo(obj);
- Type *type = obj->type;
-
- if (reg && !vi->noregister && vi->used) {
- if (TYPE_FITS_IN_REGISTER(type)) {
- if (type->size <= 4) {
- retain_register(obj, RegClass_GPR, reg);
- } else if (reg < GPRLimit) {
- if (copts.littleendian)
- retain_GPR_pair(obj, reg, reg + 1);
- else
- retain_GPR_pair(obj, reg + 1, reg);
- }
- } else if (IS_TYPE_FLOAT(type)) {
- retain_register(obj, RegClass_FPR, reg);
- } else if (IS_TYPE_VECTOR(type)) {
- retain_register(obj, RegClass_VR, reg);
- }
- }
-}
-
-static void allocate_local_vregs(void) {
- ObjectList *list;
- Object *obj;
- VarInfo *vi;
-
- if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
- if (assignable_registers[RegClass_GPR]) {
- vi = pic_base.u.var.info;
- vi->reg = 0;
- assign_register_by_type(&pic_base);
- pic_base_reg = vi->reg;
- CError_ASSERT(497, pic_base_reg);
- } else {
- CError_FATAL(500);
- }
- } else {
- pic_base_reg = 0;
- }
-
- for (list = exceptionlist; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
-
- if (vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
- assign_register_by_type(obj);
- }
- }
-
- set_last_exception_registers();
-
- for (list = arguments; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
-
- if (vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
- assign_register_by_type(obj);
- }
- }
-
- for (list = locals; list; list = list->next) {
- obj = list->object;
- if (!IsTempName(obj->name)) {
- vi = Registers_GetVarInfo(obj);
-
- if (vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
- assign_register_by_type(obj);
- }
- }
- }
-
- open_fe_temp_registers();
-
- for (list = locals; list; list = list->next) {
- obj = list->object;
- if (IsTempName(obj->name)) {
- vi = Registers_GetVarInfo(obj);
-
- if (vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
- assign_register_by_type(obj);
- }
- }
- }
-
- for (list = toclist; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
-
- if (!vi->reg && vi->used && vi->usage > 1)
- assign_register_by_type(obj);
- }
-}
-
-static void allocate_local_GPRs(void) {
- ObjectList *list;
- Object *obj;
- Object *winning_obj;
- SInt32 winning_usage;
- VarInfo *vi;
- Type *type;
-
- if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
- vi = pic_base.u.var.info;
- vi->reg = 0;
- assign_register_by_type(&pic_base);
- pic_base_reg = vi->reg;
- CError_ASSERT(605, pic_base_reg);
- } else {
- pic_base_reg = 0;
- }
-
- while (assignable_registers[RegClass_GPR]) {
- winning_obj = NULL;
- winning_usage = -1;
- if (!(disable_optimizer & 2)) {
- for (list = arguments; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- type = obj->type;
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
- if (!(disable_optimizer & 2)) {
- for (list = locals; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- type = obj->type;
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
- for (list = toclist; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used) {
- if (vi->usage >= winning_usage && vi->usage >= 3) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
-
- if (!winning_obj)
- break;
-
- assign_register_by_type(winning_obj);
- CError_ASSERT(698, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
- }
-}
-
-static void allocate_local_FPRs(void) {
- ObjectList *list;
- Object *obj;
- Object *winning_obj;
- SInt32 winning_usage;
- VarInfo *vi;
- Type *type;
-
- while (assignable_registers[RegClass_FPR]) {
- winning_obj = NULL;
- winning_usage = -1;
- if (!(disable_optimizer & 2)) {
- for (list = arguments; list; list = list->next) {
- obj = list->object;
- type = obj->type;
- vi = Registers_GetVarInfo(obj);
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (IS_TYPE_FLOAT(type)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
- if (!(disable_optimizer & 2)) {
- for (list = locals; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (IS_TYPE_FLOAT(obj->type)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
-
- if (!winning_obj)
- break;
-
- assign_register_by_type(winning_obj);
- CError_ASSERT(782, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
- }
-}
-
-static void allocate_local_VRs(void) {
- ObjectList *list;
- Object *obj;
- Object *winning_obj;
- SInt32 winning_usage;
- VarInfo *vi;
-
- while (assignable_registers[RegClass_VR]) {
- winning_obj = NULL;
- winning_usage = -1;
- if (!(disable_optimizer & 2)) {
- for (list = arguments; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (IS_TYPE_VECTOR(obj->type)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
- if (!(disable_optimizer & 2)) {
- for (list = locals; list; list = list->next) {
- obj = list->object;
- vi = Registers_GetVarInfo(obj);
- if (vi->flags & VarInfoFlag40)
- vi->usage = 100000;
- if (!vi->reg && vi->used && !vi->noregister) {
- if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
- if (IS_TYPE_VECTOR(obj->type)) {
- winning_obj = obj;
- winning_usage = vi->usage;
- }
- }
- }
- }
- }
-
- if (!winning_obj)
- break;
-
- assign_register_by_type(winning_obj);
- CError_ASSERT(846, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
- }
-}
-
-static void allocate_locals(void) {
- has_altivec_arrays = 0;
-
- if (!requires_frame && !optimizing)
- process_arguments(retain_argument_register, 0);
-
- if (optimizing) {
- allocate_local_vregs();
- } else {
- allocate_local_GPRs();
- allocate_local_FPRs();
- allocate_local_VRs();
- }
-
- assign_locals_to_memory(locals);
-}
-
-void move_assigned_argument(Object *obj, short reg) {
- VarInfo *vi;
- Type *type;
- SInt32 bytesLeft;
- SInt32 offset;
-
- vi = Registers_GetVarInfo(obj);
- type = obj->type;
- CError_ASSERT(901, obj->datatype == DLOCAL);
-
- if (!vi->used)
- return;
-
- if (reg) {
- if (vi->reg) {
- if (TYPE_IS_8BYTES(type)) {
- if (copts.littleendian) {
- if (vi->reg != reg)
- emitpcode(PC_MR, vi->reg, reg);
- if (reg < GPRLimit) {
- CError_FAIL(916, (vi->regHi == reg) || (vi->reg == (reg + 1)));
- if (vi->regHi != (reg + 1))
- emitpcode(PC_MR, vi->regHi, reg + 1);
- } else {
- load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
- }
- } else {
- if (vi->regHi != reg)
- emitpcode(PC_MR, vi->regHi, reg);
- if (reg < GPRLimit) {
- CError_FAIL(931, (vi->reg == reg) || (vi->regHi == (reg + 1)));
- if (vi->reg != (reg + 1))
- emitpcode(PC_MR, vi->reg, reg + 1);
- } else {
- load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
- }
- }
- } else if (vi->reg != reg) {
- if (IS_TYPE_FLOAT(type)) {
- emitpcode(PC_FMR, vi->reg, reg);
- } else if (IS_TYPE_VECTOR(type)) {
- emitpcode(PC_VMR, vi->reg, reg);
- } else {
- emitpcode(PC_MR, vi->reg, reg);
- }
- }
- } else {
- if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
- load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
- } else if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
- switch (type->size) {
- case 1:
- load_store_register(PC_STB, reg, local_base_register(obj), obj, 0);
- break;
- case 2:
- load_store_register(PC_STH, reg, local_base_register(obj), obj, 0);
- break;
- case 4:
- load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
- break;
- case 8:
- load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
- if (reg < GPRLimit)
- load_store_register(PC_STW, reg + 1, local_base_register(obj), obj, 4);
- break;
- default:
- CError_FATAL(993);
- }
- } else if (IS_TYPE_FLOAT(type)) {
- load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, local_base_register(obj), obj, 0);
- } else if (IS_TYPE_VECTOR(type)) {
- load_store_register(PC_STVX, reg, local_base_register(obj), obj, 0);
- } else {
- bytesLeft = (11 - reg) * 4;
- if (bytesLeft > obj->type->size)
- bytesLeft = obj->type->size;
- offset = 0;
- while (bytesLeft > 0) {
- load_store_register(PC_STW, reg, local_base_register(obj), obj, offset);
- reg++;
- offset += 4;
- bytesLeft -= 4;
- }
- }
- }
- } else {
- if (vi->reg) {
- if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
- load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
- } else if (IS_TYPE_FLOAT(type)) {
- load_store_register((type->size == 4) ? PC_LFS : PC_LFD, vi->reg, local_base_register(obj), obj, 0);
- } else if (IS_TYPE_VECTOR(type)) {
- load_store_register(PC_LVX, vi->reg, local_base_register(obj), obj, 0);
- } else {
- switch (type->size) {
- case 1:
- load_store_register(PC_LBZ, vi->reg, local_base_register(obj), obj, 0);
- break;
- case 2:
- load_store_register(is_unsigned(type) ? PC_LHZ : PC_LHA, vi->reg, local_base_register(obj), obj, 0);
- break;
- case 4:
- load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
- break;
- case 8:
- load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
- load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
- break;
- default:
- CError_FATAL(1095);
- }
- }
- } else if (!optimizing) {
- local_base_register(obj);
- }
- }
-}
-
-static void load_TOC_pointers(void) {
- VarInfo *vi;
- Object *obj;
- ObjectList *list;
- PCode *pc;
- Operand opnd;
-
- if (uses_globals && pic_base_reg) {
- pic_base_pcodelabel = makepclabel();
- pc = makepcode(PC_BC, 20, 7, 3, pic_base_pcodelabel);
- pcsetlinkbit(pc);
- pcsetsideeffects(pc);
- appendpcode(pclastblock, pc);
- pcbranch(pclastblock, pic_base_pcodelabel);
- makepcblock();
- pclabel(pclastblock, pic_base_pcodelabel);
- emitpcode(PC_MFLR, pic_base_reg);
- }
-
- memclrw(&opnd, sizeof(Operand));
- for (list = toclist; list; list = list->next) {
- obj = list->object;
- if ((vi = Registers_GetVarInfo(obj)) && (vi->flags & VarInfoFlag2)) {
- switch (obj->datatype) {
- case DNONLAZYPTR:
- symbol_operand(&opnd, obj);
- opnd.optype = OpndType_IndirectSymbol;
- if (opnd.optype)
- Coerce_to_register(&opnd, TYPE(&void_ptr), vi->reg);
- if (opnd.reg != vi->reg)
- emitpcode(PC_MR, vi->reg, opnd.reg);
- break;
- default:
- CError_FATAL(1206);
- }
- }
- }
-}
-
-static int has_vararglist(Object *funcobj) {
- FuncArg *arg;
-
- arg = TYPE_FUNC(funcobj->type)->args;
- while (arg && arg != &elipsis)
- arg = arg->next;
-
- return (arg == &elipsis);
-}
-
-void assign_labels(Statement *stmt) {
- Statement *last;
-
- last = NULL;
- while (stmt) {
- if (stmt->type == ST_LABEL && !stmt->label->pclabel) {
- if (last && last->type == ST_LABEL)
- stmt->label->pclabel = last->label->pclabel;
- else
- stmt->label->pclabel = makepclabel();
- }
-
- last = stmt;
- stmt = stmt->next;
- }
-}
-
-static Boolean islaststatement(Statement *stmt) {
- for (stmt = stmt->next; stmt; stmt = stmt->next) {
- if (stmt->type > ST_LABEL)
- return 0;
- }
- return 1;
-}
-
-static void newstatement(SInt32 sourceoffset, SInt32 value, int flag) {
- PCodeBlock *block = pclastblock;
-
- pcloopweight = value;
- if (!block->pcodeCount)
- block->loopWeight = value;
-
- if (block->pcodeCount > 100)
- branch_label(makepclabel());
-
- if (flag)
- block->flags |= fPCBlockFlag4000;
-}
-
-static void expressionstatement(ENode *expr) {
- Operand opnd;
-
- memclrw(&opnd, sizeof(Operand));
- cgdispatch[expr->type](expr, 0, 0, &opnd);
-
- if (ENODE_IS(expr, EINDIRECT) && (opnd.flags & OpndFlags_Volatile)) {
- if (TYPE_FITS_IN_REGISTER_2(expr->rtype)) {
- if (opnd.optype != OpndType_GPR)
- Coerce_to_register(&opnd, expr->rtype, 0);
- } else if (IS_TYPE_FLOAT(expr->rtype)) {
- if (opnd.optype != OpndType_FPR)
- Coerce_to_fp_register(&opnd, expr->rtype, 0);
- } else if (IS_TYPE_VECTOR(expr->rtype)) {
- if (opnd.optype != OpndType_VR)
- Coerce_to_v_register(&opnd, expr->rtype, 0);
- }
- }
-}
-
-static void labelstatement(CLabel *label) {
- if (!label->pclabel)
- label->pclabel = makepclabel();
- if (!label->pclabel->resolved)
- branch_label(label->pclabel);
- free_temporaries();
-}
-
-static void gotostatement(CLabel *label) {
- if (!label->pclabel)
- label->pclabel = makepclabel();
- branch_always(label->pclabel);
- free_temporaries();
-}
-
-static void gotoexpression(ENode *expr) {
- Operand opnd;
- CodeLabelList *list;
-
- memclrw(&opnd, sizeof(Operand));
- cgdispatch[expr->type](expr, 0, 0, &opnd);
-
- if (opnd.optype != OpndType_GPR)
- Coerce_to_register(&opnd, TYPE(&void_ptr), 0);
- CError_ASSERT(1397, opnd.optype == OpndType_GPR);
-
- for (list = codelabellist; list; list = list->next)
- pcbranch(pclastblock, list->label->pclabel);
-
- emitpcode(PC_MTCTR, opnd.reg);
- branch_indirect(NULL);
-}
-
-static void conditionalstatement(ENode *cond, CLabel *label, short truthy) {
- Operand opnd;
- memclrw(&opnd, sizeof(Operand));
-
- cond = evaluate_and_skip_comma(cond);
- if (!label->pclabel)
- label->pclabel = makepclabel();
-
- if (TYPE_IS_8BYTES(cond->data.diadic.right->rtype) || TYPE_IS_8BYTES(cond->data.diadic.left->rtype))
- I8_gen_condition(cond, &opnd, 0);
- else
- gen_condition(cond, &opnd);
-
- branch_conditional(opnd.reg, opnd.regOffset, truthy, label->pclabel);
- free_temporaries();
-}
-
-static void returnstatement(ENode *expr, Boolean dont_branch) {
- Operand opnd;
- Type *type;
- memclrw(&opnd, sizeof(Operand));
-
- if (expr) {
- type = expr->rtype;
- if (TYPE_FITS_IN_REGISTER(type)) {
- if (TYPE_IS_8BYTES(type)) {
- cgdispatch[expr->type](expr, low_reg, high_reg, &opnd);
- coerce_to_register_pair(&opnd, type, low_reg, high_reg);
- } else {
- cgdispatch[expr->type](expr, 3, 0, &opnd);
- if (opnd.optype != OpndType_GPR)
- Coerce_to_register(&opnd, type, 3);
- if (opnd.reg != 3)
- emitpcode(PC_MR, 3, opnd.reg);
- }
- } else if (IS_TYPE_FLOAT(type)) {
- cgdispatch[expr->type](expr, 1, 0, &opnd);
- if (opnd.optype != OpndType_FPR)
- Coerce_to_fp_register(&opnd, type, 1);
- if (opnd.reg != 1)
- emitpcode(PC_FMR, 1, opnd.reg);
- } else if (IS_TYPE_VECTOR(type)) {
- cgdispatch[expr->type](expr, 2, 0, &opnd);
- if (opnd.optype != OpndType_VR)
- Coerce_to_v_register(&opnd, type, 2);
- if (opnd.reg != 2)
- emitpcode(PC_VMR, 2, opnd.reg);
- } else {
- cgdispatch[expr->type](expr, 0, 0, &opnd);
- }
- }
-
- if (!dont_branch) {
- if (!returnlabel->pclabel)
- returnlabel->pclabel = makepclabel();
- branch_always(returnlabel->pclabel);
- free_temporaries();
- }
-}
-
-static void capturestackpointer(Object *obj) {
- branch_label(makepclabel());
- CError_ASSERT(1568, obj->datatype == DLOCAL);
-
- load_store_register(PC_STW, 1, local_base_register(obj), obj, 20);
- branch_label(makepclabel());
-}
-
-static void resetstackpointer(Object *obj) {
- PCode *pc;
-
- CError_ASSERT(1595, obj->datatype == DLOCAL);
-
- branch_label(makepclabel());
-
- load_store_register(PC_LWZ, 0, 1, NULL, 0);
-
- pc = makepcode(PC_LWZ, 1, local_base_register(obj), obj, 20);
- pcsetsideeffects(pc);
- appendpcode(pclastblock, pc);
-
- load_store_register(PC_STW, 0, 1, NULL, 0);
-
- branch_label(makepclabel());
-}
-
-static void callprofiler(char *name) {
- UInt32 masks[RegClassMax] = {0, 0, 0, 0, 0};
- load_store_register(PC_LWZ, 3, 1, NULL, 0);
- load_store_register(PC_LWZ, 3, 3, NULL, 8);
- masks[RegClass_GPR] |= (1 << 3);
- branch_subroutine(rt_profile_entry, 1, masks);
-}
-
-static void exitprofiler(void) {
-}
-
-void CodeGen_Generator(Statement *statements, Object *func, UInt8 mysteryFlag, Boolean callOnModuleBind) {
- Statement *stmt;
- Boolean has_varargs;
- PCodeBlock *tmp;
- SInt32 size;
-
- CodeGen_InitialSanityCheck();
- if (!saveheaperror) {
- saveheaperror = getheaperror();
- setheaperror(CodeGen_heaperror);
- }
-
- if (cparamblkptr->precompile == 1)
- CError_Error(CErrorStr180);
-
- if (!func) {
- func = createstaticinitobject();
- } else {
-#ifdef CW_CLT
- if (func && func->name)
- PrintProgressFunction(func->name->name);
-#endif
- }
-
- gFunction = func;
- has_varargs = has_vararglist(func);
- init_endian();
- init_stack_globals(func);
- assign_arguments_to_memory(func, mysteryFlag, has_varargs);
-
- needs_cleanup = 0;
- disable_optimizer = 0;
- has_catch_blocks = 0;
- current_statement = NULL;
- current_linenumber = 0;
- precomputedoperands = NULL;
- switchtables = NULL;
- temps = NULL;
- initializeexceptiontables();
- returnlabel = cleanreturnlabel = newlabel();
-
- if (copts.debuglisting)
- DumpIR(statements, func);
-
- statements = COpt_Optimizer(func, statements);
- if (copts.debuglisting)
- DumpIR(statements, func);
-
- resetTOCvarinfo();
- init_registers();
- expandTOCreferences(&statements->next);
- if (copts.debuglisting)
- DumpIR(statements, func);
-
- if (copts.profile) {
- makes_call = 1;
- requires_frame = 1;
- }
-
- initpcode();
-
- pclabel(prologue = makepcblock(), makepclabel());
- prologue->flags |= fIsProlog;
-
- pclabel(tmp = makepcblock(), makepclabel());
- pcbranch(prologue, tmp->labels);
-
- init_frame_sizes(has_varargs);
- allocate_locals();
- process_arguments(move_assigned_argument, has_varargs);
-
- if (copts.schedule_factor || copts.altivec_model)
- branch_label(makepclabel());
-
- load_TOC_pointers();
-
- if (copts.profile)
- callprofiler(CMangler_GetLinkName(func)->name);
-
- assign_labels(statements->next);
- open_temp_registers();
-
- for (stmt = statements->next; stmt; stmt = stmt->next) {
- current_statement = stmt;
- current_linenumber = stmt->sourceoffset;
- switch (stmt->type) {
- case ST_NOP:
- break;
- case ST_EXPRESSION:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- expressionstatement(stmt->expr);
- break;
- case ST_LABEL:
- labelstatement(stmt->label);
- break;
- case ST_IFGOTO:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- conditionalstatement(stmt->expr, stmt->label, 1);
- break;
- case ST_IFNGOTO:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- conditionalstatement(stmt->expr, stmt->label, 0);
- break;
- case ST_GOTOEXPR:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- gotoexpression(stmt->expr);
- break;
- case ST_GOTO:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- gotostatement(stmt->label);
- break;
- case ST_RETURN:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- returnstatement(stmt->expr, islaststatement(stmt));
- break;
- case ST_SWITCH:
- newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0);
- switchstatement(stmt->expr, (SwitchInfo *) stmt->label);
- break;
- case ST_BEGINCATCH:
- capturestackpointer(stmt->expr->data.objref);
- break;
- case ST_ENDCATCHDTOR:
- CError_ASSERT(2056, stmt->expr->data.objref->datatype == DLOCAL);
- add_immediate(3, local_base_register(stmt->expr->data.objref), stmt->expr->data.objref, 0);
- {
- UInt32 masks[RegClassMax] = {0, 0, 0, 0, 0};
- masks[RegClass_GPR] |= 1 << 3;
- branch_subroutine(Xecth_func, 1, masks);
- }
- case ST_ENDCATCH:
- resetstackpointer(stmt->expr->data.objref);
- break;
- case ST_ASM:
- if (stmt->expr) {
- if (((InlineAsm *) stmt->expr)->flags & IAFlag1) {
- CError_FATAL(2076);
- } else {
- branch_label(makepclabel());
- InlineAsm_TranslateIRtoPCode(stmt);
- }
- }
- break;
- case ST_BEGINLOOP:
- CError_FATAL(2086);
- break;
- case ST_ENDLOOP:
- CError_FATAL(2090);
- break;
- default:
- CError_FATAL(2094);
- }
- check_temp_registers();
- }
-
- close_temp_registers();
- labelstatement(returnlabel);
-
- current_statement = NULL;
-
- epilogue = pclastblock;
- pclastblock->flags |= fIsEpilogue;
-
- pccomputepredecessors();
- deleteunreachableblocks();
-
- if (copts.report_heap_info > 0)
- CodeGen_reportheapinfo(0, CMangler_GetLinkName(func)->name, "before optimization");
-
- if (copts.optimizationlevel > 0 && !disable_optimizer)
- globallyoptimizepcode(func);
- else
- pclistblocks(CMangler_GetLinkName(func)->name, "INITIAL CODE");
-
- if (copts.schedule_factor == 2) {
- if (copts.peephole)
- peepholemergeblocks(func, 0);
- if (copts.debuglisting)
- pclistblocks_start_scheduler(CMangler_GetLinkName(func)->name, "BEFORE SCHEDULING");
- scheduleinstructions(0);
- if (copts.debuglisting)
- pclistblocks_end_scheduler();
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER INSTRUCTION SCHEDULING");
- }
-
- if (copts.peephole) {
- if (copts.schedule_factor == 0 && copts.optimizationlevel > 1)
- peepholemergeblocks(func, 0);
- peepholeoptimizeforward(func);
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE FORWARD");
- }
-
- allocate_temporaries();
- colorinstructions(func);
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER REGISTER COLORING");
-
- if (copts.optimizationlevel > 1 && !disable_optimizer) {
- removecommonsubexpressions(func, 1);
- if (removedcommonsubexpressions && copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING (POST COLORING)");
- }
-
- compute_frame_sizes();
- generate_prologue(prologue, has_varargs);
- if (copts.profile)
- exitprofiler();
- generate_epilogue(epilogue, 1);
-
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER GENERATING EPILOGUE, PROLOGUE");
-
- if (copts.peephole) {
- if (copts.schedule_factor) {
- peepholemergeblocks(func, 1);
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER MERGING EPILOGUE, PROLOGUE");
- }
- peepholeoptimizepcode(func);
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE OPTIMIZATION");
- }
-
- if (copts.schedule_factor) {
- if (copts.debuglisting)
- pclistblocks_start_scheduler(CMangler_GetLinkName(func)->name, "BEFORE SCHEDULING");
- scheduleinstructions(1);
- if (copts.debuglisting)
- pclistblocks_end_scheduler();
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "FINAL CODE AFTER INSTRUCTION SCHEDULING");
- } else {
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "FINAL CODE");
- }
-
- size = assemblefunction(func, NULL);
- dumpswitchtables(func);
- dumpcodelabels(func);
- if (callOnModuleBind)
- ObjGen_DeclareInitFunction(func);
-
- pic_base_pcodelabel = NULL;
- pic_base_reg = 0;
- if (copts.exceptions && requires_frame)
- dumpexceptiontables(func, size);
-
- if (copts.report_heap_info > 0)
- CodeGen_reportheapinfo(0, CMangler_GetLinkName(func)->name, "finished");
-
- if (saveheaperror)
- setheaperror(saveheaperror);
-}
-
-enum {
- reg3 = 3,
- reg4 = 4
-};
-
-void CodeGen_GenVDispatchThunk(Object *thunkobj, Object *obj, SInt32 a, SInt32 b, SInt32 c) {
- Boolean save_debug;
- Boolean save_peephole;
- Boolean save_traceback;
- char reg;
-
- save_debug = copts.filesyminfo;
- save_peephole = copts.peephole;
- save_traceback = copts.traceback;
-
- CodeGen_InitialSanityCheck();
- CError_ASSERT(2270, b == 0);
-
- initpcode();
- makepcblock();
-
- if (a) {
- reg = CMach_PassResultInHiddenArg(TYPE_FUNC(obj->type)->functype) ? reg4 : reg3;
-
- if (c >= 0) {
- if (!FITS_IN_SHORT(c)) {
- emitpcode(PC_ADDIS, 11, 0, 0, HIGH_PART(c));
- if (c)
- emitpcode(PC_ADDI, 11, 11, 0, LOW_PART(c));
- } else {
- emitpcode(PC_ADDI, 11, 0, 0, c);
- }
- emitpcode(PC_LWZX, 11, reg, 11);
- emitpcode(PC_ADD, reg, reg, 11);
- }
-
- if (!FITS_IN_SHORT(a)) {
- emitpcode(PC_ADDIS, reg, reg, 0, HIGH_PART(a));
- if (a)
- emitpcode(PC_ADDI, reg, reg, 0, LOW_PART(a));
- } else {
- emitpcode(PC_ADDI, reg, reg, 0, a);
- }
- }
-
- emitpcode(PC_B, 0, obj);
-
- copts.filesyminfo = 0;
- copts.peephole = 0;
- copts.traceback = 0;
- assemblefunction(thunkobj, NULL);
- copts.filesyminfo = save_debug;
- copts.peephole = save_peephole;
- copts.traceback = save_traceback;
-}
-
-void CodeGen_SetupRuntimeObjects(void) {
- setupaddressing();
- dyld_stub_binding_helper = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_fp2unsigned = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_profile_entry = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_profile_exit = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_div2i = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_div2u = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_mod2i = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_mod2u = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_shr2i = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_shr2u = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_shl2i = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_ull_dbl = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_sll_dbl = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_ull_flt = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_sll_flt = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- rt_cvt_dbl_usll = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- Intrinsics_SetupRuntimeObjects();
-}
-
-Boolean CodeGen_ReInitRuntimeObjects(Boolean is_precompiler) {
- dyld_stub_binding_helper->name = GetHashNameNodeExport("dyld_stub_binding_helper");
- dyld_stub_binding_helper->u.func.linkname = dyld_stub_binding_helper->name;
-
- rt_cvt_fp2unsigned->name = GetHashNameNodeExport("__cvt_fp2unsigned");
-
- rt_profile_entry->name = GetHashNameNodeExport("mcount");
- rt_profile_entry->u.func.linkname = rt_profile_entry->name;
-
- rt_profile_exit->name = GetHashNameNodeExport("profile_exit");
-
- rt_div2i->name = GetHashNameNodeExport("__div2i");
- rt_div2u->name = GetHashNameNodeExport("__div2u");
- rt_mod2i->name = GetHashNameNodeExport("__mod2i");
- rt_mod2u->name = GetHashNameNodeExport("__mod2u");
- rt_shr2i->name = GetHashNameNodeExport("__shr2i");
- rt_shr2u->name = GetHashNameNodeExport("__shr2u");
- rt_shl2i->name = GetHashNameNodeExport("__shl2i");
-
- rt_cvt_ull_dbl->name = GetHashNameNodeExport("__cvt_ull_dbl");
- rt_cvt_sll_dbl->name = GetHashNameNodeExport("__cvt_sll_dbl");
- rt_cvt_ull_flt->name = GetHashNameNodeExport("__cvt_ull_flt");
- rt_cvt_sll_flt->name = GetHashNameNodeExport("__cvt_sll_flt");
- rt_cvt_dbl_usll->name = GetHashNameNodeExport("__cvt_dbl_usll");
-
- CMach_ReInitRuntimeObjects();
- return Intrinsics_ReInitRuntimeObjects(is_precompiler);
-}
-
-Boolean CodeGen_IsPublicRuntimeObject(Object *obj) {
- return Intrinsics_IsPublicRuntimeObject(obj);
-}
-
-void CodeGen_SOMStub(Object *a, Object *b, Object *c, SInt32 offset) {
- Boolean save_debug;
- Boolean save_peephole;
- Boolean save_traceback;
- Object *tmp;
- Operand opnd;
-
- save_debug = copts.filesyminfo;
- save_peephole = copts.peephole;
- save_traceback = copts.traceback;
-
- CodeGen_InitialSanityCheck();
- memclrw(&opnd, sizeof(Operand));
- CError_ASSERT(2528, offset <= 0x7FFF);
-
- initpcode();
- makepcblock();
-
- tmp = createIndirect(c, 1, 1);
- if (tmp) {
- opnd.optype = OpndType_Symbol;
- opnd.object = tmp;
- indirect(&opnd, NULL);
- } else {
- opnd.optype = OpndType_Symbol;
- opnd.object = c;
- }
-
- if (opnd.optype != OpndType_GPR)
- Coerce_to_register(&opnd, TYPE(&void_ptr), 12);
-
- if (opnd.optype != OpndType_GPR) {
- CError_FATAL(2562);
- } else if (opnd.reg != 12) {
- emitpcode(PC_MR, 12, opnd.reg);
- }
-
- load_store_register(PC_LWZ, 12, 12, NULL, (short) offset);
- emitpcode(PC_B, 0, b);
-
- copts.filesyminfo = 0;
- copts.peephole = 0;
- copts.traceback = 0;
- assemblefunction(a, NULL);
- copts.filesyminfo = save_debug;
- copts.peephole = save_peephole;
- copts.traceback = save_traceback;
-}
-
-void CodeGen_ParseDeclSpec(HashNameNode *identifier, DeclInfo *declinfo) {
- if (!strcmp(identifier->name, "private_extern")) {
- declinfo->storageclass = TK_EXTERN;
- declinfo->exportflags = EXPORT_FLAGS_INTERNAL;
- } else {
- CError_Error(CErrorStr176);
- }
-}
-
-static void CodeGen_EOLCheck(void) {
- short t;
-
- if (plex() != TK_EOL) {
- CPrep_Error(CErrorStr113);
- do {
- t = plex();
- } while (t != TK_EOL && t != 0);
- }
-}
-
-static void schedule_for(int what) {
- CPrep_PushOption(OPT_OFFSET(scheduling), what);
- if (copts.schedule_factor == 0)
- CPrep_PushOption(OPT_OFFSET(schedule_factor), 2);
-}
-
-static void pragma_scheduling(void) {
- Boolean *flag;
- int cpu;
-
- tk = plex();
- if (tk == TK_IDENTIFIER) {
- flag = &copts.altivec_model;
- if (!strcmp(tkidentifier->name, "vger")) {
- schedule_for(10);
- return;
- } else if (!strcmp(tkidentifier->name, "altivec")) {
- schedule_for(7);
- return;
- } else if (!strcmp(tkidentifier->name, "reset")) {
- CPrep_PopOption(OPT_OFFSET(scheduling));
- CPrep_PopOption(OPT_OFFSET(schedule_factor));
- return;
- } else if (!strcmp(tkidentifier->name, "off")) {
- CPrep_PushOption(OPT_OFFSET(schedule_factor), 0);
- return;
- } else if (!strcmp(tkidentifier->name, "once")) {
- CPrep_PushOption(OPT_OFFSET(schedule_factor), 1);
- return;
- } else if (!strcmp(tkidentifier->name, "twice")) {
- CPrep_PushOption(OPT_OFFSET(schedule_factor), 2);
- return;
- } else if (!strcmp(tkidentifier->name, "on")) {
- CPrep_PushOption(OPT_OFFSET(schedule_factor), 2);
- return;
- } else if (!*flag) {
- if (!strcmp(tkidentifier->name, "603e")) {
- schedule_for(5);
- return;
- } else if (!strcmp(tkidentifier->name, "604e")) {
- schedule_for(6);
- return;
- } else if (!strcmp(tkidentifier->name, "PPC603e")) {
- schedule_for(5);
- return;
- } else if (!strcmp(tkidentifier->name, "PPC604e")) {
- schedule_for(6);
- return;
- }
- } else {
- PPCError_Error(PPCErrorStr115);
- return;
- }
- CPrep_Error(CErrorStr186);
- return;
- }
-
- if (tk == TK_INTCONST) {
- switch (CInt64_GetULong(&tkintconst)) {
- case 601:
- cpu = 1;
- break;
- case 603:
- cpu = 2;
- break;
- case 604:
- cpu = 3;
- break;
- case 750:
- cpu = 4;
- break;
- case 7400:
- cpu = 7;
- break;
- case 7450:
- cpu = 10;
- break;
- case 8240:
- case 8260:
- cpu = 5;
- break;
- case 801:
- case 821:
- case 823:
- case 850:
- case 860:
- cpu = 9;
- break;
- default:
- CPrep_Error(CErrorStr186);
- return;
- }
- schedule_for(cpu);
- return;
- }
-
- if (copts.warn_illpragma)
- CPrep_Warning(CErrorStr186);
-}
-
-static SInt32 CodeGen_ParseLongIntegerORonORoff(void) {
- SInt32 result;
- short t;
-
- result = 0;
- t = plex();
- if (t == TK_INTCONST) {
- if (!tkintconst.hi)
- result = CInt64_GetULong(&tkintconst);
- else
- CPrep_Error(CErrorStr154);
- CodeGen_EOLCheck();
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "on")) {
- CodeGen_EOLCheck();
- return 1;
- }
- if (!strcmp(tkidentifier->name, "off")) {
- CodeGen_EOLCheck();
- return 0;
- }
- if (copts.warn_illpragma)
- CPrep_Warning(CErrorStr186);
- return 0;
- } else {
- if (copts.warn_illpragma)
- CPrep_Warning(CErrorStr186);
- }
-
- return result;
-}
-
-void CodeGen_ParsePragma(HashNameNode *name) {
- short t;
- SInt32 value;
- char *str;
- NameSpace *nspace;
- NameSpaceObjectList *list;
-
- if (!strcmp(name->name, "debuglisting")) {
- copts.debuglisting = CodeGen_ParseLongIntegerORonORoff();
- return;
- }
-
- if (!strcmp(name->name, "report_heap_info")) {
- t = plex();
- if (t == TK_INTCONST) {
- copts.report_heap_info = CInt64_GetULong(&tkintconst);
- if (copts.report_heap_info < 0) {
- copts.report_heap_info = 0;
- CError_Error(CErrorStr186);
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.report_heap_info = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.report_heap_info = 1;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "scheduling")) {
- pragma_scheduling();
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "ppc_unroll_speculative")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.unroll_speculative = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.unroll_speculative = 1;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "ppc_unroll_instructions_limit")) {
- t = plex();
- if (t == TK_INTCONST) {
- copts.unroll_instr_limit = CInt64_GetULong(&tkintconst);
- if (copts.unroll_instr_limit < 0) {
- copts.unroll_instr_limit = 0;
- CError_Error(CErrorStr186);
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.unroll_instr_limit = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.unroll_instr_limit = 70;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "gen_fsel")) {
- t = plex();
- if (t == TK_INTCONST) {
- value = CInt64_GetULong(&tkintconst);
- if (value < 0) {
- copts.gen_fsel = 0;
- CError_Error(CErrorStr186);
- } else if (value > 255) {
- copts.gen_fsel = 255;
- CError_Error(CErrorStr186);
- } else {
- copts.gen_fsel = value;
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.gen_fsel = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.gen_fsel = 10;
- } else if (!strcmp(tkidentifier->name, "always")) {
- copts.gen_fsel = 255;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "ppc_unroll_factor_limit")) {
- t = plex();
- if (t == TK_INTCONST) {
- copts.unroll_factor_limit = CInt64_GetULong(&tkintconst);
- if (copts.unroll_factor_limit < 0) {
- copts.unroll_factor_limit = 0;
- CError_Error(CErrorStr186);
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.unroll_factor_limit = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.unroll_factor_limit = 10;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "altivec_model")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.altivec_model = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.altivec_model = 1;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "altivec_vrsave")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- CPrep_PushOption(OPT_OFFSET(altivec_vrsave), 0);
- } else if (!strcmp(tkidentifier->name, "on")) {
- CPrep_PushOption(OPT_OFFSET(altivec_vrsave), 1);
- } else if (!strcmp(tkidentifier->name, "allon")) {
- CPrep_PushOption(OPT_OFFSET(altivec_vrsave), 2);
- } else if (!strcmp(tkidentifier->name, "reset")) {
- CPrep_PopOption(OPT_OFFSET(altivec_vrsave));
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "function_align")) {
- t = plex();
- if (t == TK_INTCONST) {
- value = CInt64_GetULong(&tkintconst);
- switch (value) {
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- CPrep_PushOption(OPT_OFFSET(function_align), value);
- break;
- default:
- PPCError_Warning(PPCErrorStr161);
- CodeGen_EOLCheck();
- return;
- }
- } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) {
- CPrep_PopOption(OPT_OFFSET(function_align));
- } else {
- PPCError_Warning(PPCErrorStr161);
- }
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "processor")) {
- if (cscope_currentfunc) {
- PPCError_Warning(PPCErrorStr156, "pragma processor");
- return;
- }
- t = plex();
- if (t == TK_INTCONST) {
- switch (CInt64_GetULong(&tkintconst)) {
- case 401:
- copts.processor = 0;
- break;
- case 403:
- copts.processor = 1;
- break;
- case 505:
- copts.processor = 2;
- break;
- case 509:
- copts.processor = 3;
- break;
- case 555:
- copts.processor = 4;
- break;
- case 556:
- copts.processor = 25;
- break;
- case 565:
- copts.processor = 26;
- break;
- case 601:
- copts.processor = 5;
- break;
- case 602:
- copts.processor = 6;
- break;
- case 8240:
- copts.processor = 18;
- break;
- case 8260:
- copts.processor = 19;
- break;
- case 603:
- copts.processor = 7;
- break;
- case 604:
- copts.processor = 9;
- break;
- case 740:
- copts.processor = 11;
- break;
- case 750:
- copts.processor = 12;
- break;
- case 801:
- copts.processor = 13;
- break;
- case 821:
- copts.processor = 14;
- break;
- case 823:
- copts.processor = 15;
- break;
- case 850:
- copts.processor = 16;
- break;
- case 860:
- copts.processor = 17;
- break;
- case 7400:
- copts.processor = 21;
- break;
- default:
- PPCError_Warning(PPCErrorStr208);
- CodeGen_EOLCheck();
- return;
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "generic"))
- copts.processor = 20;
- else if (!strcmp(tkidentifier->name, "603e"))
- copts.processor = 8;
- else if (!strcmp(tkidentifier->name, "604e"))
- copts.processor = 10;
- else if (!strcmp(tkidentifier->name, "PPC603e"))
- copts.processor = 8;
- else if (!strcmp(tkidentifier->name, "PPC604e"))
- copts.processor = 10;
- else
- PPCError_Warning(PPCErrorStr208);
- } else {
- PPCError_Warning(PPCErrorStr208);
- }
-
- if ((str = CMach_GetCPU()))
- CPrep_InsertSpecialMacro(&ppc_cpu, str);
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "min_struct_alignment")) {
- t = plex();
- if (t == TK_INTCONST) {
- value = CInt64_GetULong(&tkintconst);
- switch (value) {
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- CPrep_PushOption(OPT_OFFSET(min_struct_alignment), value);
- break;
- default:
- PPCError_Warning(PPCErrorStr191);
- CodeGen_EOLCheck();
- return;
- }
- } else if (t == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "reset"))
- CPrep_PopOption(OPT_OFFSET(min_struct_alignment));
- else if (!strcmp(tkidentifier->name, "on"))
- CPrep_PushOption(OPT_OFFSET(min_struct_alignment), 4);
- else if (!strcmp(tkidentifier->name, "off"))
- CPrep_PushOption(OPT_OFFSET(min_struct_alignment), 1);
- } else {
- PPCError_Warning(PPCErrorStr161);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "tvectors")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- no_descriptors = 1;
- } else if (!strcmp(tkidentifier->name, "on")) {
- no_descriptors = 0;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "dynamic")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.codegen_dynamic = 0;
- copts.codegen_pic = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.codegen_dynamic = 1;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "pic")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.codegen_pic = 0;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.codegen_pic = 1;
- if (!copts.codegen_dynamic) {
- PPCError_Error(PPCErrorStr189);
- copts.codegen_pic = 0;
- }
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "implicit_templates")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.no_implicit_templates = 1;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.no_implicit_templates = 0;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "common")) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "off")) {
- copts.no_common = 1;
- } else if (!strcmp(tkidentifier->name, "on")) {
- copts.no_common = 0;
- } else {
- CError_Error(CErrorStr186);
- return;
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (!strcmp(name->name, "CALL_ON_MODULE_BIND")) {
- if (plex() == TK_IDENTIFIER) {
- for (nspace = cscope_current; nspace; nspace = nspace->parent) {
- list = CScope_GetLocalObject(nspace, tkidentifier);
- if (list && list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DFUNC) {
- ObjGen_DeclareInitFunction(OBJECT(list->object));
- break;
- }
- }
- } else {
- CError_Error(CErrorStr186);
- }
-
- CodeGen_EOLCheck();
- return;
- }
-
- if (copts.warn_illpragma)
- CPrep_Warning(CErrorStr186);
-
- if (plex() != TK_EOL) {
- do {
- t = plex();
- } while (t != TK_EOL && t != 0);
- }
-}
-
-void CodeGen_UpdateObject(Object *object) {
- if (object->datatype == DDATA && object->section == SECT_DEFAULT && object == rt_ptmf_null)
- object->sclass = TK_EXTERN;
-}
-
-void CodeGen_UpdateBackEndOptions(void) {
- copts.globaloptimizer = 1;
-}
-
-SInt32 CodeGen_objc_method_self_offset(ObjCMethod *meth) {
- SInt32 size;
-
- if (!meth->return_type) {
- size = 4;
- } else if (
- IS_TYPE_ARRAY(meth->return_type) ||
- IS_TYPE_NONVECTOR_STRUCT(meth->return_type) ||
- IS_TYPE_CLASS(meth->return_type) ||
- IS_TYPE_12BYTES_MEMBERPOINTER(meth->return_type)
- )
- {
- size = 8;
- } else {
- size = meth->return_type->size;
- }
-
- if (size == 0)
- size = 1;
-
- return (size + 3) & ~3;
-}
-
-SInt32 CodeGen_objc_method_sel_offset(ObjCMethod *meth) {
- return (CodeGen_objc_method_self_offset(meth) + 7) & ~3;
-}
-
-SInt32 CodeGen_objc_method_arg_offset(ObjCMethod *meth, ObjCMethodArg *arg) {
- SInt32 pos;
- ObjCMethodArg *scan;
-
- pos = CodeGen_objc_method_sel_offset(meth) + 4;
- for (scan = meth->selector_args; scan; scan = scan->next) {
- if (scan == arg)
- return pos;
-
- if (scan->type == NULL)
- pos += 4;
- else
- pos += scan->type->size;
-
- pos = (pos + 3) & ~3;
- }
-
- return 0;
-}
-
-SInt32 CodeGen_objc_method_args_size(ObjCMethod *meth) {
- SInt32 size;
- ObjCMethodArg *scan;
-
- size = CodeGen_objc_method_self_offset(meth);
- for (scan = meth->selector_args; scan; scan = scan->next) {
- if (scan->next == NULL && scan->type == NULL)
- return size;
-
- size = (size + 3) & ~3;
- if (scan->type == NULL)
- size += 4;
- else
- size += scan->type->size;
- }
-
- return size;
-}
-
-ENode *CodeGen_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs) {
- return Intrinsics_HandleIntrinsicCall(func, arg_exprs);
-}
-
-ENode *CodeGen_HandleTypeCast(ENode *expr, Type *type, UInt32 qual) {
- short flags;
-
- if (copts.altivec_model) {
- flags = qual & ENODE_FLAG_QUALS;
- if (IS_TYPE_STRUCT(type) && IS_TYPE_STRUCT(expr->rtype) && expr->flags == flags) {
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- case STRUCT_VECTOR_FLOAT:
- case STRUCT_VECTOR_PIXEL:
- expr = makemonadicnode(expr, ETYPCON);
- expr->rtype = type;
- expr->flags = flags;
- return expr;
- }
- }
- }
-
- return NULL;
-}
-
-short CodeGen_AssignCheck(const ENode *expr, const Type *type, Boolean flag1, Boolean flag2) {
- short result;
- const Type *exprtype = expr->rtype;
-
- if (
- copts.altivec_model &&
- IS_TYPE_VECTOR(type) &&
- IS_TYPE_VECTOR(exprtype) &&
- TYPE_STRUCT(type)->stype == TYPE_STRUCT(exprtype)->stype
- )
- result = CheckResult3;
- else
- result = CheckResult0;
- return result;
-}
-
-Boolean CodeGen_CollapseVectorExpression(ENode *expr, MWVector128 *vec, Type *type) {
- // this function is a mess and needs lots of fixing
- Boolean result;
- //int count;
- int i;
- ENode *escan;
-
- result = 0;
- for (i = 0; i < 4; i++)
- vec->ul[i] = 0;
-
- if (ENODE_IS(expr, ECOMMA)) {
- i = 0;
- escan = expr;
- while (ENODE_IS(escan, ECOMMA)) {
- i++;
- escan = escan->data.diadic.left;
- }
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- if (i < 15) {
- PPCError_Error(PPCErrorStr110, type, 0);
- } else if (i > 15) {
- PPCError_Error(PPCErrorStr111, type, 0);
- } else {
- escan = expr;
- i = 15;
- while (ENODE_IS(escan, ECOMMA)) {
- CInt64 v;
- expr = escan->data.diadic.right;
- v = expr->data.intval;
- if (!ENODE_IS(expr, EINTCONST)) {
- PPCError_Error(PPCErrorStr112);
- break;
- }
-
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UCHAR) {
- if (!CInt64_IsInURange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
-
- vec->uc[i--] = (UInt8) v.lo;
- escan = escan->data.diadic.left;
- }
-
- if (ENODE_IS(escan, EINTCONST)) {
- CInt64 v = escan->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UCHAR) {
- if (!CInt64_IsInURange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- vec->uc[0] = (UInt8) v.lo;
- } else {
- PPCError_Error(PPCErrorStr112);
- break;
- }
- result = 1;
- }
- break;
-
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- if (i < 7) {
- PPCError_Error(PPCErrorStr110, type, 0);
- } else if (i > 7) {
- PPCError_Error(PPCErrorStr111, type, 0);
- } else {
- escan = expr;
- i = 7;
- while (ENODE_IS(escan, ECOMMA)) {
- ENode *e = escan->data.diadic.right;
- CInt64 v = e->data.intval;
- if (!ENODE_IS(e, EINTCONST)) {
- PPCError_Error(PPCErrorStr112);
- break;
- }
-
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_USHORT || TYPE_STRUCT(type)->stype == STRUCT_VECTOR_PIXEL) {
- if (!CInt64_IsInURange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
-
- vec->us[i--] = (UInt16) e->data.intval.lo;
- escan = escan->data.diadic.left;
- }
-
- if (ENODE_IS(escan, EINTCONST)) {
- CInt64 v = escan->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_USHORT || TYPE_STRUCT(type)->stype == STRUCT_VECTOR_PIXEL) {
- if (!CInt64_IsInURange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- vec->us[0] = (UInt16) v.lo;
- } else {
- PPCError_Error(PPCErrorStr112);
- break;
- }
- result = 1;
- }
- break;
-
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- if (i < 3) {
- PPCError_Error(PPCErrorStr110, type, 0);
- } else if (i > 3) {
- PPCError_Error(PPCErrorStr111, type, 0);
- } else {
- escan = expr;
- i = 3;
- while (ENODE_IS(escan, ECOMMA)) {
- CInt64 v;
- expr = escan->data.diadic.right;
- v = expr->data.intval;
- if (!ENODE_IS(expr, EINTCONST)) {
- PPCError_Error(PPCErrorStr112);
- break;
- }
-
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UINT) {
- if (!CInt64_IsInURange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
-
- vec->ul[i--] = expr->data.intval.lo;
- escan = escan->data.diadic.left;
- }
-
- if (ENODE_IS(escan, EINTCONST)) {
- CInt64 v = escan->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UINT) {
- if (!CInt64_IsInURange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- vec->ul[0] = v.lo;
- } else {
- PPCError_Error(PPCErrorStr112);
- break;
- }
- result = 1;
- }
- break;
-
- case STRUCT_VECTOR_FLOAT:
- if (i < 3) {
- PPCError_Error(PPCErrorStr110, type, 0);
- } else if (i > 3) {
- PPCError_Error(PPCErrorStr111, type, 0);
- } else {
- Float fv;
- escan = expr;
- i = 3;
- while (ENODE_IS(escan, ECOMMA)) {
- expr = escan->data.diadic.right;
- if (ENODE_IS(expr, EFLOATCONST)) {
- fv = expr->data.floatval;
- } else if (ENODE_IS(escan->data.diadic.right, EINTCONST)) {
- fv = CMach_CalcFloatConvertFromInt(expr->rtype,
- expr->data.intval);
- } else {
- PPCError_Error(PPCErrorStr112);
- break;
- }
-
- CMach_InitFloatMem(TYPE(&stfloat), fv, &vec->f[i]);
- i--;
- escan = escan->data.diadic.left;
- }
-
- if (ENODE_IS(escan, EFLOATCONST)) {
- fv = escan->data.floatval;
- } else if (ENODE_IS(escan, EINTCONST)) {
- fv = CMach_CalcFloatConvertFromInt(escan->rtype, escan->data.intval);
- } else {
- PPCError_Error(PPCErrorStr112);
- break;
- }
-
- CMach_InitFloatMem(TYPE(&stfloat), fv, &vec->f[0]);
- result = 1;
- }
- break;
- }
- } else if (ENODE_IS(expr, EINTCONST)) {
- int i = 0;
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- {
- CInt64 v = expr->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UCHAR) {
- if (!CInt64_IsInURange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 1))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- while (i < 16)
- vec->uc[i++] = (UInt8) v.lo;
- result = 1;
- break;
- }
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- {
- CInt64 v = expr->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_USHORT || TYPE_STRUCT(type)->stype == STRUCT_VECTOR_PIXEL) {
- if (!CInt64_IsInURange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 2))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- while (i < 8)
- vec->us[i++] = (UInt16) v.lo;
- result = 1;
- break;
- }
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- {
- CInt64 v = expr->data.intval;
- if (copts.pedantic) {
- if (TYPE_STRUCT(type)->stype == STRUCT_VECTOR_UINT) {
- if (!CInt64_IsInURange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- } else {
- if (!CInt64_IsInRange(v, 4))
- PPCError_Warning(PPCErrorStr113, type, 0);
- }
- }
- while (i < 4)
- vec->ul[i++] = v.lo;
- result = 1;
- break;
- }
- case STRUCT_VECTOR_FLOAT:
- {
- Float fv;
- if (!CInt64_IsInRange(expr->data.intval, 4)) {
- PPCError_Error(PPCErrorStr112);
- break;
- }
- fv = CMach_CalcFloatConvertFromInt(expr->rtype, expr->data.intval);
- for (; i < 4; i++)
- CMach_InitFloatMem(TYPE(&stfloat), fv, &vec->f[i]);
- result = 1;
- break;
- }
- default:
- PPCError_Error(PPCErrorStr112);
- }
- } else if (ENODE_IS(expr, EFLOATCONST)) {
- switch (TYPE_STRUCT(type)->stype) {
- default:
- PPCError_Error(PPCErrorStr112);
- break;
- case STRUCT_VECTOR_FLOAT:
- {
- Float fv;
- i = 0;
- fv = expr->data.floatval;
- CMach_InitFloatMem(TYPE(&stfloat), fv, &vec->f[0]);
- while (i < 4)
- CMach_InitFloatMem(TYPE(&stfloat), fv, &vec->f[i++]);
- result = 1;
- break;
- }
- }
- } else if (ENODE_IS2(expr, EINDIRECT, EFUNCCALL)) {
- if (!IS_TYPE_STRUCT(expr->rtype))
- PPCError_Error(PPCErrorStr112);
- } else if (!ENODE_IS(expr, EVECTOR128CONST)) {
- PPCError_Error(PPCErrorStr112);
- }
-
- return result;
-}
-
-void CodeGen_InsertSpecialMacros(void) {
- char *str;
-
- CPrep_InsertSpecialMacro(&vecM, "__VEC__");
- CPrep_InsertSpecialMacro(&altivecM, "__ALTIVEC__");
- CPrep_InsertSpecialMacro(&powcM, "powerc");
- CPrep_InsertSpecialMacro(&__powcM, "__powerc");
- CPrep_InsertSpecialMacro(&hostM, "__POWERPC__");
- CPrep_InsertSpecialMacro(&_ppc_M, "__ppc__");
-
- CPrep_InsertSpecialMacro(&bendM, "__BIG_ENDIAN__");
-
- if ((str = CMach_GetCPU()))
- CPrep_InsertSpecialMacro(&ppc_cpu, str);
-
- CPrep_InsertSpecialMacro(&profM, "__profile__");
- CPrep_InsertSpecialMacro(&longI, "__fourbyteints__");
- CPrep_InsertSpecialMacro(&IEEED, "__IEEEdoubles__");
- CPrep_InsertSpecialMacro(&macM2, "__MACOS__");
- CPrep_InsertSpecialMacro(&appleM, "__APPLE__");
- CPrep_InsertSpecialMacro(&_machM, "__MACH__");
- CPrep_InsertSpecialMacro(&archM, "__ARCHITECTURE__");
-
- if (copts.optimizationlevel > 0)
- CPrep_InsertSpecialMacro(&optM, "__OPTIMIZE__");
-
- if (copts.codegen_dynamic)
- CPrep_InsertSpecialMacro(&dynM, "__DYNAMIC__");
- if (!copts.codegen_dynamic)
- CPrep_InsertSpecialMacro(&dynM, "__STATIC__");
-
- if (copts.oldalignment && copts.structalignment == AlignMode2_PPC)
- CPrep_InsertSpecialMacro(&alignM, "__NATURAL_ALIGNMENT__");
-
- if (!copts.ANSIstrict)
- CPrep_InsertSpecialMacro(&ppcM, "ppc");
-}
-
-char *CodeGen_ExpandSpecialMacro(Macro *macro) {
- if (macro == &vecM) return "10205";
- if (macro == &altivecM) return "100000000";
- if (macro == &powcM) return "1";
- if (macro == &__powcM) return "1";
- if (macro == &hostM) return "1";
- if (macro == &bendM) return "1";
- if (macro == &_ppc_M) return "1";
- if (CMach_GetCPU() && macro == &ppc_cpu) return "1";
- if (macro == &profM) return copts.profile ? "1" : "0";
- if (macro == &longI) return "1";
- if (macro == &IEEED) return "1";
- if (macro == &macM2) return "1";
- if (macro == &appleM) return "1";
- if (macro == &alignM) return "1";
-
- if (macro == &optM) {
- switch (copts.optimizationlevel) {
- case 1: return "1";
- case 2: return "2";
- case 3: return "3";
- case 4: return "4";
- case 0: return "0";
- default: return "9";
- }
- }
-
- if (macro == &_machM) return "1";
- if (macro == &archM) return "ppc";
- if (macro == &dynM) return "1";
- if (!copts.ANSIstrict && macro == &ppcM) return "1";
- if (macro == &_ppc_M) return "1";
-
- CError_FATAL(4801);
- return "0";
-}
-
-void CodeGen_reportheapinfo(Boolean release_flag, char *name, char *text) {
- HeapInfo o;
- HeapInfo all;
-
- CTool_GetHeapInfo(&o, 3);
- CTool_GetHeapInfo(&all, 5);
-
- if (release_flag)
- releaseoheap();
-
- PPCError_Message(
- "%n:%u HEAP STATUS\n"
- " optimizer: %i blocks, used: %i, free: %i, total: %i, largest free: %i\n"
- " all: %i blocks, used: %i, free: %i, total: %i, largest free: %i",
- name, text,
- o.blocks, o.total_size - o.total_free, o.total_free, o.total_size, o.largest_free_block,
- all.blocks, all.total_size - all.total_free, all.total_free, all.total_size, all.largest_free_block
- );
-}
-
-static void CodeGen_heaperror(void) {
- CodeGen_reportheapinfo(1, "?", "out of memory");
- if (saveheaperror) {
- setheaperror(saveheaperror);
- saveheaperror();
- }
-}
-
-void CodeGen_InitialSanityCheck(void) {
-}
diff --git a/compiler_and_linker/unsorted/CodeMotion.c b/compiler_and_linker/unsorted/CodeMotion.c
deleted file mode 100644
index 8ce2962..0000000
--- a/compiler_and_linker/unsorted/CodeMotion.c
+++ /dev/null
@@ -1,906 +0,0 @@
-#include "compiler/CodeMotion.h"
-#include "compiler/Alias.h"
-#include "compiler/BitVectors.h"
-#include "compiler/LoopDetection.h"
-#include "compiler/LoopOptimization.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/RegisterInfo.h"
-
-int movedloopinvariantcode;
-int unswitchedinvariantcode;
-
-static int isloopinvariant(PCode *pcode, Loop *loop, UInt32 *vec, int flag1, int flag2) {
- PCodeArg *op;
- RegUseOrDef *list;
- int i;
-
- if (pcode->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- if (pcode->alias) {
- if (pcode->alias->type == AliasType2 || (pcode->flags & (fIsVolatile | fSideEffects)))
- return 0;
-
- if (pcode->flags & fIsRead) {
- for (list = findobjectusedef(pcode->alias->object)->defs; list; list = list->next) {
- if (
- may_alias(pcode, Defs[list->id].pcode) &&
- bitvectorgetbit(list->id, vec) &&
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 0;
- }
- }
-
- if (pcode->flags & fIsWrite) {
- for (list = findobjectusedef(pcode->alias->object)->uses; list; list = list->next) {
- if (
- may_alias(pcode, Uses[list->id].pcode) &&
- bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 0;
- }
- }
- } else {
- return 0;
- }
- }
-
- if ((pcode->flags & fIsWrite) && !bitvectorgetbit(pcode->block->blockIndex, loop->vec2C))
- return 0;
-
- op = pcode->args;
- i = pcode->argCount;
- while (i--) {
- switch (op->kind) {
- case PCOp_MEMORY:
- if ((pcode->flags & fIsRead) && ((pcode->flags == 0) & 0x40)) {
- for (list = findobjectusedef(op->data.mem.obj)->defs; list; list = list->next) {
- if (
- may_alias(pcode, Defs[list->id].pcode) &&
- bitvectorgetbit(list->id, vec) &&
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 0;
- }
- }
- if (pcode->flags & fIsWrite) {
- for (list = findobjectusedef(op->data.mem.obj)->uses; list; list = list->next) {
- if (
- may_alias(pcode, Uses[list->id].pcode) &&
- bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 0;
- }
- }
- break;
- case PCOp_REGISTER:
- if (op->data.reg.effect & (EffectRead | EffectWrite)) {
- if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
- if (op->data.reg.reg == _FP_)
- break;
- if (op->data.reg.reg == _CALLER_SP_)
- break;
- if (op->data.reg.reg == 2)
- break;
- }
- if (op->data.reg.reg < n_real_registers[op->arg]) {
- if (op->arg == RegClass_CRFIELD) {
- if (!flag2 || (op->data.reg.effect & EffectRead))
- return 0;
- } else if (op->arg == RegClass_SPR) {
- if (!flag1)
- return 0;
- } else {
- return 0;
- }
- } else if (op->data.reg.effect & EffectRead) {
- if (flag1 && op->kind == PCOp_REGISTER && op->arg == RegClass_SPR)
- break;
- if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
- if (op->data.reg.reg == _FP_)
- break;
- if (op->data.reg.reg == _CALLER_SP_)
- break;
- if (op->data.reg.reg == 2)
- break;
- }
-
- for (list = reg_Defs[op->arg][op->data.reg.reg]; list; list = list->next) {
- if (
- bitvectorgetbit(list->id, vec) &&
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 0;
- }
- }
- }
- break;
- }
- op++;
- }
-
- return 1;
-}
-
-static int isuniquedefinition(PCode *pcode, Loop *loop) {
- RegUseOrDef *list;
- int defID;
- UseOrDef *def;
-
- defID = pcode->defID;
- def = &Defs[defID];
- if (defID >= number_of_Defs)
- return 0;
- if (def->pcode != pcode)
- return 0;
- if ((defID + 1) < number_of_Defs && def[1].pcode == pcode)
- return 0;
-
- if (def->v.kind == PCOp_REGISTER) {
- for (list = reg_Defs[def->v.arg][def->v.u.reg]; list; list = list->next) {
- if (
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks) &&
- list->id != defID
- )
- return 0;
- }
- } else if (def->v.kind == PCOp_MEMORY) {
- for (list = findobjectusedef(def->v.u.object)->defs; list; list = list->next) {
- if (
- may_alias(pcode, Defs[list->id].pcode) &&
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks) &&
- list->id != defID
- )
- return 0;
- }
- } else {
- CError_FATAL(292);
- }
-
- return 1;
-}
-
-static int uniquelyreachesuse(int defID, int useID) {
- UseOrDef *def;
- UseOrDef *use;
- RegUseOrDef *list;
- PCode *pcode;
-
- def = &Defs[defID];
- use = &Uses[useID];
- if (def->v.kind == PCOp_REGISTER) {
- for (list = reg_Defs[def->v.arg][def->v.u.reg]; list; list = list->next) {
- if (
- list->id != defID &&
- bitvectorgetbit(list->id, usedefinfo[use->pcode->block->blockIndex].defvec8)
- )
- break;
- }
- } else if (def->v.kind == PCOp_MEMORY) {
- for (list = findobjectusedef(def->v.u.object)->defs; list; list = list->next) {
- if (
- may_alias(def->pcode, Defs[list->id].pcode) &&
- list->id != defID &&
- bitvectorgetbit(list->id, usedefinfo[use->pcode->block->blockIndex].defvec8)
- )
- break;
- }
- }
-
- if (!list)
- return 1;
-
- if (def->pcode->block == use->pcode->block) {
- for (pcode = use->pcode->prevPCode; pcode; pcode = pcode->prevPCode) {
- if (pcode == def->pcode)
- return 1;
- }
- }
-
- return 0;
-}
-
-static int uniquelyreachesalluses(int defID, Loop *loop) {
- UseOrDef *def;
- RegUseOrDef *list;
-
- def = &Defs[defID];
-
- if (def->v.kind == PCOp_REGISTER) {
- for (list = reg_Uses[def->v.arg][def->v.u.reg]; list; list = list->next) {
- if (
- bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].usevec1C) ||
- (bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks) && !uniquelyreachesuse(defID, list->id))
- )
- return 0;
- }
- } else if (def->v.kind == PCOp_MEMORY) {
- for (list = findobjectusedef(def->v.u.object)->uses; list; list = list->next) {
- if (may_alias(def->pcode, Uses[list->id].pcode)) {
- if (
- bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].usevec1C) ||
- (bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks) && !uniquelyreachesuse(defID, list->id))
- )
- return 0;
- }
- }
- } else {
- CError_FATAL(382);
- }
-
- return 1;
-}
-
-static int isliveonexit(TinyValue *v, Loop *loop) {
- RegUseOrDef *list;
- UInt32 *vec;
-
- vec = usedefinfo[loop->preheader->blockIndex].usevec1C;
-
- if (v->kind == PCOp_REGISTER) {
- for (list = reg_Uses[v->arg][v->u.reg]; list; list = list->next) {
- if (
- bitvectorgetbit(list->id, vec) &&
- !bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 1;
- }
- } else if (v->kind == PCOp_MEMORY) {
- for (list = findobjectusedef(v->u.object)->uses; list; list = list->next) {
- if (
- bitvectorgetbit(list->id, vec) &&
- !bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)
- )
- return 1;
- }
- }
-
- return 0;
-}
-
-static int dominatesallexits(PCode *pcode, Loop *loop) {
- return bitvectorgetbit(pcode->block->blockIndex, loop->vec28) != 0;
-}
-
-static int maymove(PCode *pcode, Loop *loop) {
- short reg;
-
- if (!isuniquedefinition(pcode, loop))
- return 0;
- if (!uniquelyreachesalluses(pcode->defID, loop))
- return 0;
- if (!dominatesallexits(pcode, loop) && isliveonexit(&Defs[pcode->defID].v, loop))
- return 0;
-
- if (loop->bodySize > 25) {
- switch (pcode->op) {
- case PC_LI:
- if (
- pcode->nextPCode &&
- pcode->nextPCode->op == PC_LVX &&
- (pcode->nextPCode->flags & fIsConst)
- ) {
- reg = pcode->args[0].data.reg.reg;
- if (pcode->nextPCode->args[1].data.reg.reg == reg ||
- pcode->nextPCode->args[2].data.reg.reg == reg)
- return 1;
- }
- case PC_VSPLTISB:
- case PC_VSPLTISH:
- case PC_VSPLTISW:
- return 0;
- default:
- if (!bitvectorgetbit(pcode->block->blockIndex, loop->vec2C))
- return 0;
- }
- }
-
- return 1;
-}
-
-static void moveinvariantcomputation(PCode *pcode, Loop *loop) {
- ObjectUseDef *oud;
- BlockList *blocklist;
- RegUseOrDef *list;
- UseOrDef *def;
- int defID;
-
- defID = pcode->defID;
- def = &Defs[defID];
- deletepcode(pcode);
- insertpcodebefore(loop->preheader->lastPCode, pcode);
- loop->bodySize--;
- movedloopinvariantcode = 1;
-
- if (def->v.kind == PCOp_REGISTER) {
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- for (list = reg_Defs[def->v.arg][def->v.u.reg]; list; list = list->next)
- bitvectorclearbit(list->id, usedefinfo[blocklist->block->blockIndex].defvec8);
- bitvectorsetbit(defID, usedefinfo[blocklist->block->blockIndex].defvec8);
- }
- } else if (def->v.kind == PCOp_MEMORY) {
- oud = findobjectusedef(def->v.u.object);
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- for (list = oud->defs; list; list = list->next) {
- if (uniquely_aliases(pcode, Defs[list->id].pcode))
- bitvectorclearbit(list->id, usedefinfo[blocklist->block->blockIndex].defvec8);
- }
- bitvectorsetbit(defID, usedefinfo[blocklist->block->blockIndex].defvec8);
- }
- } else {
- CError_FATAL(545);
- }
-}
-
-static int srawi_addze_maymove(PCode *pcode, Loop *loop) {
- RegUseOrDef *list;
- UseOrDef *def;
- int defID;
- int nextDefID;
-
- defID = pcode->defID;
- nextDefID = pcode->nextPCode->defID;
-
- def = &Defs[defID];
- if (defID >= number_of_Defs)
- return 0;
- if (def->pcode != pcode)
- return 0;
- if ((defID + 1) < number_of_Defs && def[1].pcode == pcode)
- return 0;
-
- if (def->v.kind == PCOp_REGISTER && def->v.arg == RegClass_GPR) {
- for (list = reg_Defs[RegClass_GPR][def->v.u.reg]; list; list = list->next) {
- if (
- bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks) &&
- list->id != defID &&
- list->id != nextDefID
- )
- return 0;
- }
- } else {
- CError_FATAL(582);
- }
-
- if (!uniquelyreachesalluses(pcode->defID, loop))
- return 0;
- if (!dominatesallexits(pcode, loop) && isliveonexit(&Defs[pcode->defID].v, loop))
- return 0;
- if (!dominatesallexits(pcode->nextPCode, loop) && isliveonexit(&Defs[pcode->nextPCode->defID].v, loop))
- return 0;
-
- return 1;
-}
-
-static int srawi_addze_isloopinvariant(PCode *pcode, Loop *loop, UInt32 *vec) {
- static PCode *oldNextInstr;
- PCode *nextInstr;
-
- nextInstr = pcode->nextPCode;
- if (
- pcode->op == PC_ADDZE &&
- oldNextInstr == pcode
- ) {
- oldNextInstr = NULL;
- return 1;
- } else if (
- pcode->op == PC_SRAWI &&
- nextInstr &&
- nextInstr->op == PC_ADDZE &&
- pcode->args[0].data.reg.reg == nextInstr->args[0].data.reg.reg &&
- nextInstr->args[0].data.reg.reg == nextInstr->args[1].data.reg.reg &&
- !(pcode->flags & (fIsCall | fIsPtrOp | fIsVolatile | fSideEffects)) &&
- !(nextInstr->flags & (fIsCall | fIsPtrOp | fIsVolatile | fSideEffects)) &&
- isloopinvariant(pcode, loop, vec, 1, 0) &&
- srawi_addze_maymove(pcode, loop)
- ) {
- oldNextInstr = nextInstr;
- return 1;
- } else {
- oldNextInstr = NULL;
- return 0;
- }
-}
-
-static void removeblockfromloop(Loop *loop, PCodeBlock *block) {
- BlockList *list;
- BlockList **ptr;
-
- bitvectorclearbit(block->blockIndex, loop->memberblocks);
- bitvectorclearbit(block->blockIndex, loop->vec24);
- bitvectorclearbit(block->blockIndex, loop->vec28);
- bitvectorclearbit(block->blockIndex, loop->vec2C);
- loop->bodySize -= block->pcodeCount;
-
- ptr = &loop->blocks;
- while ((list = *ptr)) {
- if (list->block == block)
- *ptr = list->next;
- else
- ptr = &list->next;
- }
-}
-
-static void changesuccessor(PCodeBlock *block, PCodeBlock *from, PCodeBlock *to) {
- PCLink **ptr;
- PCLink *link;
-
- for (link = block->successors; link; link = link->nextLink) {
- if (link->block == from)
- link->block = to;
- }
-
- ptr = &from->predecessors;
- while ((link = *ptr)) {
- if (link->block == block) {
- *ptr = link->nextLink;
- link->nextLink = to->predecessors;
- to->predecessors = link;
- } else {
- ptr = &link->nextLink;
- }
- }
-}
-
-static void movesuccessor(PCodeBlock *to, PCodeBlock *from, PCodeBlock *block) {
- PCLink **ptr;
- PCLink *link;
-
- for (link = block->predecessors; link; link = link->nextLink) {
- if (link->block == from)
- link->block = to;
- }
-
- ptr = &from->successors;
- while ((link = *ptr)) {
- if (link->block == block) {
- *ptr = link->nextLink;
- link->nextLink = to->successors;
- to->successors = link;
- } else {
- ptr = &link->nextLink;
- }
- }
-}
-
-static void movecmptopreheader(Loop *loop, PCodeBlock *block, PCode *pc1, PCode *pc2, PCodeArg *op) {
- PCodeBlock *preheader;
- PCode *pc3;
-
- preheader = loop->preheader;
- if (PCODE_FLAG_SET_F(pc1) & fRecordBit) {
- moveinvariantcomputation(pc1, loop);
- } else {
- deletepcode(pc1);
- insertpcodebefore(loop->preheader->lastPCode, pc1);
- loop->bodySize--;
- movedloopinvariantcode = 1;
- }
- loop->preheader = NULL;
-
- insertpreheaderblock(loop);
-
- pc3 = preheader->lastPCode;
- CError_ASSERT(775, pc3->op == PC_B);
- deletepcode(pc3);
- deletepcode(pc2);
- appendpcode(preheader, pc2);
- movesuccessor(preheader, block, op->data.label.label->block);
-}
-
-static PCodeBlock *appendheadercopy(Loop *loop, PCodeBlock *block1, PCodeBlock *block2, PCodeBlock *block3) {
- PCodeBlock *newblock1;
- PCodeBlock *newblock2;
- PCLink *link;
- PCode *scan;
-
- newblock1 = lalloc(sizeof(PCodeBlock));
- newblock2 = lalloc(sizeof(PCodeBlock));
-
- newblock1->labels = NULL;
- newblock1->predecessors = newblock1->successors = NULL;
- newblock1->firstPCode = newblock1->lastPCode = NULL;
- newblock1->pcodeCount = 0;
- newblock1->loopWeight = loop->body->loopWeight;
- newblock1->flags = 0;
- newblock1->blockIndex = pcblockcount++;
-
- newblock2->labels = NULL;
- newblock2->predecessors = newblock2->successors = NULL;
- newblock2->firstPCode = newblock2->lastPCode = NULL;
- newblock2->pcodeCount = 0;
- newblock2->loopWeight = loop->body->loopWeight;
- newblock2->flags = 0;
- newblock2->blockIndex = pcblockcount++;
-
- newblock1->nextBlock = newblock2;
- newblock2->prevBlock = newblock1;
- newblock1->prevBlock = block1;
- newblock2->nextBlock = block1->nextBlock;
- block1->nextBlock = newblock1;
- newblock2->nextBlock->prevBlock = newblock2;
-
- pclabel(newblock1, makepclabel());
- pclabel(newblock2, makepclabel());
-
- changesuccessor(block1, block1->successors->block, newblock1);
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock2;
- link->nextLink = newblock1->successors;
- newblock1->successors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock1;
- link->nextLink = newblock2->predecessors;
- newblock2->predecessors = link;
-
- appendpcode(newblock2, makepcode(PC_B, block2->nextBlock->labels));
- pcbranch(newblock2, block2->nextBlock->labels);
- pccomputepredecessors1(newblock2);
-
- for (scan = block2->firstPCode; scan; scan = scan->nextPCode)
- appendpcode(newblock1, copypcode(scan));
-
- pcbranch(newblock1, block3->labels);
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock1;
- link->nextLink = block3->predecessors;
- block3->predecessors = link;
-
- addblocktoloop(loop, newblock1);
- if (bitvectorgetbit(block2->blockIndex, loop->vec28))
- bitvectorsetbit(newblock1->blockIndex, loop->vec28);
- if (bitvectorgetbit(block2->blockIndex, loop->vec2C))
- bitvectorsetbit(newblock1->blockIndex, loop->vec2C);
-
- for (loop = loop->parent; loop; loop = loop->parent) {
- addblocktoloop(loop, newblock1);
- if (bitvectorgetbit(block2->blockIndex, loop->vec28))
- bitvectorsetbit(newblock1->blockIndex, loop->vec28);
- if (bitvectorgetbit(block2->blockIndex, loop->vec2C))
- bitvectorsetbit(newblock1->blockIndex, loop->vec2C);
-
- addblocktoloop(loop, newblock2);
- if (bitvectorgetbit(block2->blockIndex, loop->vec28))
- bitvectorsetbit(newblock2->blockIndex, loop->vec28);
- if (bitvectorgetbit(block2->blockIndex, loop->vec2C))
- bitvectorsetbit(newblock2->blockIndex, loop->vec2C);
- }
-
- return newblock1;
-}
-
-static BlockList *findswitchpath(Loop *loop, PCodeBlock *block) {
- BlockList *head;
- BlockList *tail;
- BlockList *node;
- PCodeBlock *scan;
-
- head = NULL;
- tail = NULL;
-
- for (scan = block; scan && scan != loop->body; scan = scan->successors->block) {
- if (!bitvectorgetbit(scan->blockIndex, loop->memberblocks))
- return NULL;
- if (scan->successors && scan->successors->nextLink)
- return NULL;
-
- node = oalloc(sizeof(BlockList));
- node->block = scan;
- node->next = NULL;
- if (head) {
- tail->next = node;
- tail = node;
- } else {
- head = node;
- tail = node;
- }
- }
-
- return head;
-}
-
-static void simpleunswitchloop(Loop *loop) {
- PCode *pc29;
- PCodeArg *op27;
- UInt32 *myvec;
- PCodeBlock *block26;
- PCode *pc25; // r25
- BlockList *path2_24;
- PCodeArg *op23;
- PCode *pc23; // r23
- BlockList *scanlist; // r23
- BlockList *bestpath1; // r23
- BlockList *bestpath2; // r22
- PCodeBlock *headercopy; // r22
- Loop *newloop; // r21
- PCodeBlock *preheader21;
- BlockList *path20;
- PCode *scan20;
- PCode *lastpcode;
- int i;
- BlockList *pathiter1;
- BlockList *pathiter2;
-
- if (!(lastpcode = loop->body->lastPCode))
- return;
- if (lastpcode->op != PC_BT && lastpcode->op != PC_BF)
- return;
- if (lastpcode->args[2].kind != PCOp_LABEL)
- return;
- if (!bitvectorgetbit(lastpcode->args[2].data.label.label->block->blockIndex, loop->memberblocks))
- return;
- if (loop->x57)
- return;
- if (loop->x4D)
- return;
- if (bitvectorgetbit(loop->body->nextBlock->blockIndex, loop->memberblocks))
- return;
-
- for (block26 = pcbasicblocks; block26; block26 = block26->nextBlock) {
- if (bitvectorgetbit(block26->blockIndex, loop->memberblocks))
- break;
- }
-
- if (!block26)
- return;
-
- myvec = oalloc(4 * ((number_of_Defs + 31) >> 5));
- bitvectorcopy(myvec, usedefinfo[block26->blockIndex].defvec8, number_of_Defs);
- for (pc25 = loop->preheader->nextBlock->firstPCode; pc25; pc25 = pc25->nextPCode) {
- if (!(PCODE_FLAG_SET_F(pc25) & (fIsCall | fIsPtrOp | fIsVolatile | fSideEffects | fRecordBit))) {
- if (isloopinvariant(pc25, loop, myvec, 0, 1))
- break;
- }
- }
-
- if (!pc25 || pc25->argCount < 1)
- return;
-
- if (
- pc25->argCount < 1 ||
- pc25->args[0].kind != PCOp_REGISTER ||
- pc25->args[0].arg != RegClass_CRFIELD
- )
- return;
-
- pc29 = pc25->block->lastPCode;
- if (
- !pc29 ||
- !(pc29->flags & fIsBranch) ||
- pc29->args[0].kind != PCOp_REGISTER ||
- pc29->args[0].arg != RegClass_CRFIELD
- )
- return;
-
- if (pc29->args[0].data.reg.reg != pc25->args[0].data.reg.reg)
- return;
-
- op27 = NULL;
- for (i = 0; i < pc29->argCount; i++) {
- if (pc29->args[i].kind == PCOp_LABEL)
- op27 = &pc29->args[i];
- }
-
- if (op27) {
- preheader21 = loop->preheader;
-
- path20 = findswitchpath(loop, block26->nextBlock);
- if (!path20)
- return;
-
- path2_24 = findswitchpath(loop, op27->data.label.label->block);
- if (!path2_24)
- return;
-
- bestpath1 = NULL;
- bestpath2 = NULL;
- for (pathiter1 = path20; pathiter1; pathiter1 = pathiter1->next) {
- for (pathiter2 = path2_24; pathiter2; pathiter2 = pathiter2->next) {
- if (pathiter1->block == pathiter2->block) {
- bestpath1 = pathiter1;
- break;
- }
- }
- if (bestpath1)
- break;
- bestpath2 = pathiter1;
- }
-
- CError_ASSERT(1192, bestpath2->block);
-
- if (bestpath2->block->lastPCode && bestpath2->block->lastPCode->op == PC_B)
- deletepcode(bestpath2->block->lastPCode);
-
- while (bestpath1) {
- for (scan20 = bestpath1->block->firstPCode; scan20; scan20 = scan20->nextPCode) {
- if (scan20->op != PC_B)
- appendpcode(bestpath2->block, copypcode(scan20));
- }
- bestpath1 = bestpath1->next;
- }
-
- headercopy = appendheadercopy(loop, bestpath2->block, loop->body, block26);
- movecmptopreheader(loop, block26, pc25, pc29, op27);
-
- if (block26->pcodeCount) {
- if (path2_24->block->firstPCode) {
- pc23 = path2_24->block->firstPCode;
- for (scan20 = block26->firstPCode; scan20; scan20 = scan20->nextPCode) {
- if (scan20->op != PC_B)
- insertpcodebefore(pc23, copypcode(scan20));
- }
- } else {
- for (scan20 = block26->firstPCode; scan20; scan20 = scan20->nextPCode) {
- if (scan20->op != PC_B)
- appendpcode(path2_24->block, copypcode(scan20));
- }
- }
- }
-
- op23 = NULL;
- for (i = 0; i < loop->body->lastPCode->argCount; i++) {
- if (loop->body->lastPCode->args[i].kind == PCOp_LABEL)
- op23 = &loop->body->lastPCode->args[i];
- }
-
- CError_ASSERT(1250, op23 != NULL);
-
- changesuccessor(loop->body, op23->data.label.label->block, path2_24->block);
- op23->data.label.label = path2_24->block->labels;
-
- op23 = NULL;
- for (i = 0; i < preheader21->lastPCode->argCount; i++) {
- if (preheader21->lastPCode->args[i].kind == PCOp_LABEL)
- op23 = &preheader21->lastPCode->args[i];
- }
-
- CError_ASSERT(1267, op23 != NULL);
-
- changesuccessor(preheader21, op23->data.label.label->block, loop->body);
- op23->data.label.label = loop->body->labels;
-
- op23 = NULL;
- for (i = 0; i < loop->preheader->lastPCode->argCount; i++) {
- if (loop->preheader->lastPCode->args[i].kind == PCOp_LABEL)
- op23 = &loop->preheader->lastPCode->args[i];
- }
-
- CError_ASSERT(1284, op23 != NULL);
-
- changesuccessor(loop->preheader, op23->data.label.label->block, headercopy);
- op23->data.label.label = headercopy->labels;
-
- newloop = lalloc(sizeof(Loop));
- newloop->parent = loop->parent;
- newloop->children = NULL;
- newloop->nextSibling = loop->nextSibling;
- loop->nextSibling = newloop;
- newloop->body = loop->body;
- newloop->preheader = NULL;
- newloop->blocks = NULL;
- newloop->basicInductionVars = NULL;
- newloop->footer = NULL;
- newloop->pc18 = NULL;
- newloop->loopWeight = loop->loopWeight;
-
- bitvectorinitialize(newloop->memberblocks = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(newloop->vec24 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(newloop->vec28 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(newloop->vec2C = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
-
- removeblockfromloop(loop, newloop->body);
- addblocktoloop(newloop, newloop->body);
-
- bitvectorsetbit(newloop->body->blockIndex, newloop->vec24);
- bitvectorsetbit(newloop->body->blockIndex, newloop->vec2C);
- bitvectorsetbit(newloop->body->blockIndex, newloop->vec28);
-
- for (scanlist = path2_24; scanlist; scanlist = scanlist->next) {
- removeblockfromloop(loop, scanlist->block);
- addblocktoloop(newloop, scanlist->block);
- bitvectorsetbit(scanlist->block->blockIndex, newloop->vec2C);
- }
-
- newloop->preheader = NULL;
- insertpreheaderblock(newloop);
- analyzeloop(newloop);
-
- loop->body = headercopy;
-
- for (scanlist = loop->blocks; scanlist; scanlist = scanlist->next)
- bitvectorsetbit(scanlist->block->blockIndex, loop->vec2C);
-
- bitvectorsetbit(headercopy->blockIndex, loop->vec24);
- analyzeloop(loop);
-
- unswitchedinvariantcode = 1;
- }
-}
-
-static void simpleunswitchloops(Loop *loop) {
- while (loop) {
- if (loop->children)
- simpleunswitchloops(loop->children);
- else if (!loop->x4F)
- simpleunswitchloop(loop);
- loop = loop->nextSibling;
- }
-}
-
-static void moveinvariantsfromloop(Loop *loop) {
- RegUseOrDef *list;
- BlockList *blocklist;
- PCode *instr;
- PCode *nextInstr;
- UInt32 *myvec;
- UseOrDef *def;
- int defID;
- int flag;
- PCodeBlock *block;
-
- myvec = oalloc(4 * ((number_of_Defs + 31) >> 5));
- do {
- flag = 0;
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- block = blocklist->block;
- bitvectorcopy(myvec, usedefinfo[block->blockIndex].defvec8, number_of_Defs);
- for (instr = block->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- if (!(instr->flags & fIsBranch) && instr->argCount) {
- if (
- !(instr->flags & (fIsCall | fIsPtrOp | fIsVolatile | fSideEffects)) &&
- isloopinvariant(instr, loop, myvec, 0, 0) &&
- maymove(instr, loop)
- ) {
- moveinvariantcomputation(instr, loop);
- flag = 1;
- } else if (srawi_addze_isloopinvariant(instr, loop, myvec)) {
- moveinvariantcomputation(instr, loop);
- flag = 1;
- }
-
- for (def = &Defs[defID = instr->defID]; defID < number_of_Defs && def->pcode == instr; def++, defID++) {
- if (def->v.kind == PCOp_REGISTER) {
- for (list = reg_Defs[def->v.arg][def->v.u.reg]; list; list = list->next)
- bitvectorclearbit(list->id, myvec);
- } else if (def->v.kind == PCOp_MEMORY) {
- if (def->v.arg == PCOpMemory0) {
- for (list = findobjectusedef(def->v.u.object)->defs; list; list = list->next) {
- if (uniquely_aliases(instr, Defs[list->id].pcode))
- bitvectorclearbit(list->id, myvec);
- }
- }
- } else {
- CError_FATAL(1434);
- }
-
- bitvectorsetbit(defID, myvec);
- }
- }
- }
- }
- } while (flag);
-}
-
-static void moveinvariantsfromloops(Loop *loop) {
- while (loop) {
- if (loop->children)
- moveinvariantsfromloops(loop->children);
- moveinvariantsfromloop(loop);
- loop = loop->nextSibling;
- }
-}
-
-void moveloopinvariantcode(void) {
- unswitchedinvariantcode = 0;
- movedloopinvariantcode = 0;
- if (loopsinflowgraph) {
- moveinvariantsfromloops(loopsinflowgraph);
- simpleunswitchloops(loopsinflowgraph);
- }
- freeoheap();
-}
diff --git a/compiler_and_linker/unsorted/Coloring.c b/compiler_and_linker/unsorted/Coloring.c
deleted file mode 100644
index 8036435..0000000
--- a/compiler_and_linker/unsorted/Coloring.c
+++ /dev/null
@@ -1,268 +0,0 @@
-#include "compiler/Coloring.h"
-#include "compiler/CFunc.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InterferenceGraph.h"
-#include "compiler/PCode.h"
-#include "compiler/PPCError.h"
-#include "compiler/Registers.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/SpillCode.h"
-#include "compiler/StackFrame.h"
-#include "compiler/objects.h"
-
-RegClass coloring_class;
-static short used_regs_before_coloring;
-
-static void markspecialregisters(RegClass rclass) {
- ObjectList *list;
- Object *object;
- VarInfo *vi;
- UInt32 i;
-
- for (i = 0; i < n_real_registers[rclass]; i++)
- interferencegraph[i]->x14 = i;
-
- for (list = arguments; list; list = list->next) {
- object = list->object;
- vi = Registers_GetVarInfo(object);
- if ((vi->flags & VarInfoFlag2) && vi->rclass == rclass) {
- interferencegraph[vi->reg]->spillTemporary = object;
- if (vi->flags & VarInfoFlag4) {
- interferencegraph[vi->reg]->flags |= fPairLow;
- interferencegraph[vi->regHi]->flags |= fPairHigh;
- interferencegraph[vi->regHi]->spillTemporary = object;
- }
- }
- }
-
- for (list = locals; list; list = list->next) {
- object = list->object;
- vi = Registers_GetVarInfo(object);
- if ((vi->flags & VarInfoFlag2) && vi->rclass == rclass) {
- interferencegraph[vi->reg]->spillTemporary = object;
- if (vi->flags & VarInfoFlag4) {
- interferencegraph[vi->reg]->flags |= fPairLow;
- interferencegraph[vi->regHi]->flags |= fPairHigh;
- interferencegraph[vi->regHi]->spillTemporary = object;
- }
- }
- }
-}
-
-static IGNode *simplifygraph(void) {
- int availableRegs;
- IGNode *spilledNodes;
- IGNode *pushedNodes;
- IGNode *best;
- IGNode *node;
- UInt32 i;
- UInt32 j;
- int flag;
- float bestScore;
- float score;
-
- availableRegs = available_registers(coloring_class);
- pushedNodes = NULL;
-
- do {
- spilledNodes = NULL;
- flag = 0;
- for (i = n_real_registers[coloring_class]; i < used_virtual_registers[coloring_class]; i++) {
- node = interferencegraph[i];
- if (!(node->flags & (fPushed | fCoalesced))) {
- if (node->x12 < availableRegs) {
- for (j = 0; j < node->arraySize; j++)
- interferencegraph[node->array[j]]->x12--;
- node->flags |= fPushed;
- node->next = pushedNodes;
- pushedNodes = node;
- flag = 1;
- } else {
- node->next = spilledNodes;
- spilledNodes = node;
- }
- }
- }
- } while (flag);
-
- if (spilledNodes)
- estimatespillcosts();
-
- while (spilledNodes) {
- best = spilledNodes;
- bestScore = (spilledNodes->x10 >= used_regs_before_coloring) ? FLT_MAX : ((float) spilledNodes->spillCost / (float) spilledNodes->x12);
-
- for (node = spilledNodes->next; node; node = node->next) {
- score = (node->x10 >= used_regs_before_coloring) ? FLT_MAX : ((float) node->spillCost / (float) node->x12);
- if (score < bestScore) {
- best = node;
- bestScore = score;
- }
- }
-
- for (i = 0; i < best->arraySize; i++)
- interferencegraph[best->array[i]]->x12--;
-
- best->flags |= fPushed;
- best->next = pushedNodes;
- pushedNodes = best;
-
- do {
- spilledNodes = NULL;
- flag = 0;
- for (i = n_real_registers[coloring_class]; i < used_virtual_registers[coloring_class]; i++) {
- node = interferencegraph[i];
- if (!(node->flags & (fPushed | fCoalesced))) {
- if (node->x12 < availableRegs) {
- for (j = 0; j < node->arraySize; j++)
- interferencegraph[node->array[j]]->x12--;
- node->flags |= fPushed;
- node->next = pushedNodes;
- pushedNodes = node;
- flag = 1;
- } else {
- node->next = spilledNodes;
- spilledNodes = node;
- }
- }
- }
- } while (flag);
- }
-
- return pushedNodes;
-}
-
-static int colorgraph(IGNode *node) {
- UInt32 volatileRegs;
- int result;
- IGNode *otherNode;
- int reg;
- UInt32 workingMask;
- int i;
- short *array;
-
- result = 1;
-
- reset_nonvolatile_registers(coloring_class);
- volatileRegs = volatile_registers(coloring_class);
-
- while (node) {
- workingMask = volatileRegs;
- for (array = node->array, i = 0; i < node->arraySize; i++) {
- otherNode = interferencegraph[*(array++)];
- reg = otherNode->x14;
- if (reg != -1 && reg < n_real_registers[coloring_class])
- workingMask &= ~(1 << reg);
- }
-
- if (workingMask) {
- for (i = 0; i < n_real_registers[coloring_class]; i++) {
- if (workingMask & (1 << i)) {
- node->x14 = i;
- break;
- }
- }
- } else {
- reg = obtain_nonvolatile_register(coloring_class);
- if (reg != -1) {
- volatileRegs |= 1 << (node->x14 = reg);
- } else {
- node->flags |= fSpilled;
- result = 0;
- }
- }
-
- node = node->next;
- }
-
- return result;
-}
-
-static void rewritepcode(void) {
- PCodeBlock *block;
- PCode *instr;
- PCodeArg *op;
- UInt32 i;
- IGNode *node;
- int reg;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_ANY_REGISTER(op, coloring_class))
- op->data.reg.reg = interferencegraph[op->data.reg.reg]->x14;
- op++;
- }
-
- if (
- (instr->flags & fIsMove) &&
- (instr->args[1].arg == coloring_class) &&
- instr->args[1].data.reg.reg == instr->args[0].data.reg.reg
- )
- deletepcode(instr);
- }
- }
-
- for (i = n_real_registers[coloring_class]; i < used_virtual_registers[coloring_class]; i++) {
- node = interferencegraph[i];
- if (node->spillTemporary && !(node->flags & fSpilled)) {
- if (node->flags & fCoalesced) {
- reg = node->x14;
- while (reg >= n_real_registers[coloring_class]) {
- reg = interferencegraph[reg]->x14;
- if (reg < 0)
- break;
- }
- node->x14 = reg;
- }
-
- if (node->flags & fPairHigh) {
- reg = node->x14;
- Registers_GetVarInfo(node->spillTemporary)->regHi = reg;
- } else {
- reg = node->x14;
- Registers_GetVarInfo(node->spillTemporary)->reg = reg;
- }
- }
- }
-}
-
-void colorinstructions(Object *proc) {
- RegClass rclass;
- int flag;
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- coloring_class = rclass;
-
- if (rclass == RegClass_GPR)
- check_dynamic_aligned_frame();
-
- if (used_virtual_registers[rclass] > n_real_registers[rclass]) {
- save_before_coloring_nonvolatile_registers(rclass);
- used_regs_before_coloring = used_virtual_registers[rclass];
- if (!available_registers(rclass)) {
- PPCError_Error(PPCErrorStr102, register_class_name[rclass]);
- return;
- }
-
- flag = 1;
- while (flag && used_virtual_registers[rclass] > n_real_registers[rclass]) {
- buildinterferencegraph(proc);
- markspecialregisters(rclass);
- flag = colorgraph(simplifygraph()) ? 0 : 1;
-
- if (flag)
- insertspillcode();
- else
- rewritepcode();
- freeoheap();
- }
- }
-
- used_virtual_registers[rclass] = n_real_registers[rclass];
- }
-
- coloring = 0;
-}
diff --git a/compiler_and_linker/unsorted/ConstantPropagation.c b/compiler_and_linker/unsorted/ConstantPropagation.c
deleted file mode 100644
index 2b40453..0000000
--- a/compiler_and_linker/unsorted/ConstantPropagation.c
+++ /dev/null
@@ -1,643 +0,0 @@
-#include "compiler/ConstantPropagation.h"
-#include "compiler/Alias.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/objects.h"
-
-int propagatedconstants;
-static int changed;
-static PCode **defininginstruction;
-static PCode **vrdefininginstruction;
-
-static void computedefininginstructions(PCodeBlock *block) {
- RegUseOrDef *list;
- PCode *instr;
- int i;
-
- for (i = 0; i < used_virtual_registers[RegClass_GPR]; i++) {
- instr = NULL;
- for (list = reg_Defs[RegClass_GPR][i]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[block->blockIndex].defvec8)) {
- if (instr == NULL) {
- instr = Defs[list->id].pcode;
- } else {
- instr = NULL;
- break;
- }
- }
- }
- defininginstruction[i] = instr;
- }
-
- for (i = 0; i < used_virtual_registers[RegClass_VR]; i++) {
- instr = NULL;
- for (list = reg_Defs[RegClass_VR][i]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[block->blockIndex].defvec8)) {
- if (instr == NULL) {
- instr = Defs[list->id].pcode;
- } else {
- instr = NULL;
- break;
- }
- }
- }
- vrdefininginstruction[i] = instr;
- }
-}
-
-static PCode *isstackoperand(PCodeArg *op, SInt16 *resultValue, SInt16 addend) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg]) && instr->op == PC_ADDI) {
- if (
- instr->args[2].kind == PCOp_MEMORY &&
- (instr->args[1].data.reg.reg == _FP_ || instr->args[1].data.reg.reg == _CALLER_SP_) &&
- instr->args[2].data.mem.obj->datatype == DLOCAL
- )
- {
- if (can_add_displ_to_local(instr->args[2].data.mem.obj, addend)) {
- *resultValue = instr->args[2].data.mem.offset;
- return instr;
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
-}
-
-static int isconstantoperand(PCodeArg *op, SInt16 *resultValue) {
- PCode *instr;
-
- if (
- (instr = defininginstruction[op->data.reg.reg]) &&
- instr->op == PC_LI &&
- instr->args[1].kind == PCOp_IMMEDIATE
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isuint16constantoperand(PCodeArg *op, SInt16 *resultValue) {
- PCode *instr;
-
- if (
- (instr = defininginstruction[op->data.reg.reg]) &&
- instr->op == PC_LI &&
- instr->args[1].kind == PCOp_IMMEDIATE &&
- FITS_IN_USHORT(instr->args[1].data.imm.value)
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isvectorconstantoperand(PCodeArg *op, SInt16 *resultValue, Opcode *resultNewOp) {
- PCode *instr;
-
- if (
- (instr = vrdefininginstruction[op->data.reg.reg]) &&
- (instr->op == PC_VSPLTISB || instr->op == PC_VSPLTISH || instr->op == PC_VSPLTISW) &&
- instr->args[1].kind == PCOp_IMMEDIATE
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- *resultNewOp = instr->op;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isunsignedloadoperand(PCodeArg *op) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg])) {
- if (instr->flags & fIsRead) {
- if (instr->op >= PC_LHZ && instr->op <= PC_LHZUX)
- return 2;
- if (instr->op >= PC_LBZ && instr->op <= PC_LBZUX)
- return 1;
- } else if (instr->op == PC_RLWINM) {
- int var3 = instr->args[3].data.imm.value;
- int var4 = instr->args[4].data.imm.value;
- if (var4 == 31) {
- if (var3 == 24)
- return 1;
- if (var3 == 16)
- return 2;
- }
- }
- }
-
- return 0;
-}
-
-static int ismaskedoperand(PCodeArg *op, UInt32 *resultMask) {
- PCode *instr;
- UInt32 mask;
-
- if ((instr = defininginstruction[op->data.reg.reg]) && instr->op == PC_RLWINM) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value) {
- mask =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) &
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- } else {
- mask =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) |
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- }
- *resultMask = mask;
- return 1;
- }
-
- return 0;
-}
-
-static int issignedloadoperand(PCodeArg *op) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg])) {
- if (instr->flags & fIsRead) {
- if (instr->op >= PC_LHA && instr->op <= PC_LHAUX)
- return 2;
- } else if (instr->op == PC_EXTSB) {
- return 1;
- } else if (instr->op == PC_EXTSH) {
- return 2;
- }
- }
-
- return 0;
-}
-
-static void propagateconstantstoblock(PCodeBlock *block) {
- PCode *instr;
- SInt16 immAddend;
- SInt16 value1;
- SInt16 valueU16;
- Opcode newOpcode;
- SInt16 value2;
- UInt32 mask;
- UInt32 mask2;
- int loadSize;
- PCodeArg *op;
- int i;
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- switch (instr->op) {
- case PC_MR:
- if (isconstantoperand(&instr->args[1], &value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
- break;
- case PC_VMR:
- if (isvectorconstantoperand(&instr->args[1], &value1, &newOpcode)) {
- change_opcode(instr, newOpcode);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
- break;
- case PC_RLWINM:
- if (
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- instr->args[2].data.imm.value == 0 &&
- instr->args[4].data.imm.value == 31
- )
- {
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (
- (instr->args[3].data.imm.value == 16 && value1 == (value1 & 0x7FFF)) ||
- (instr->args[3].data.imm.value == 24 && value1 == (value1 & 0xFF))
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
- }
-
- loadSize = isunsignedloadoperand(&instr->args[1]);
- if (
- (loadSize == 2 && instr->args[3].data.imm.value <= 16) ||
- (loadSize == 1 && instr->args[3].data.imm.value <= 24)
- )
- {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- if (ismaskedoperand(&instr->args[1], &mask)) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value) {
- mask2 =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) &
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- } else {
- mask2 =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) |
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- }
- if (mask == (mask & mask2)) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- }
- break;
-
- case PC_EXTSH:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- loadSize = issignedloadoperand(&instr->args[1]);
- if (loadSize == 1 || loadSize == 2) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_EXTSB:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (
- isconstantoperand(&instr->args[1], &value1) &&
- value1 >= -128 &&
- value1 <= 127
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- loadSize = issignedloadoperand(&instr->args[1]);
- if (loadSize == 1) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_ADDI:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- immAddend = instr->args[2].data.imm.value;
- if (
- isconstantoperand(&instr->args[1], &value1) &&
- FITS_IN_SHORT(immAddend + value1)
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend + value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_ADD:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[2], &value1)) {
- if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- immAddend = value1;
- }
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (instr->op == PC_ADDI || instr->op == PC_MR) {
- if (FITS_IN_SHORT(immAddend + value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend + value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- } else {
- instr->args[1] = instr->args[2];
- if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- }
- }
-
- if (changed) {
- if (instr->op == PC_MR) {
- PCode *stackInstr;
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, 0))) {
- change_opcode(instr, PC_ADDI);
- instr->flags = stackInstr->flags;
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- change_num_operands(instr, 3);
- propagatedconstants = 1;
- changed = 1;
- }
- } else if (instr->op == PC_ADDI && instr->args[2].kind == PCOp_IMMEDIATE) {
- PCode *stackInstr;
- SInt16 addend = instr->args[2].data.imm.value;
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, addend))) {
- change_opcode(instr, PC_ADDI);
- instr->flags = stackInstr->flags;
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- instr->args[2].data.imm.value = value1 + addend;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000))
- instr->alias = make_alias(instr->args[2].data.imm.obj, instr->args[2].data.imm.value, 1);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- }
- break;
-
- case PC_OR:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- value1 = 0;
- immAddend = 0;
- if (isconstantoperand(&instr->args[2], &value1)) {
- if (isuint16constantoperand(&instr->args[2], &valueU16)) {
- if (valueU16 != 0) {
- change_opcode(instr, PC_ORI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = valueU16;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- value1 = valueU16;
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- immAddend = value1;
- }
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (instr->op == PC_ORI || instr->op == PC_MR) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend | value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- } else if (isuint16constantoperand(&instr->args[1], &valueU16)) {
- if (valueU16 != 0) {
- change_opcode(instr, PC_ORI);
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = valueU16;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- break;
-
- case PC_SUBF:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[1], &value1) && FITS_IN_SHORT(-value1)) {
- if (isconstantoperand(&instr->args[2], &value2) && FITS_IN_SHORT(value2 - value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value2 - value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = -value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- value2 = value1;
- } else if (isconstantoperand(&instr->args[2], &value1) && FITS_IN_SHORT(-value1)) {
- if (value1 == 0) {
- change_opcode(instr, PC_NEG);
- change_num_operands(instr, 2);
- } else {
- instr->flags = opcodeinfo[PC_SUBFIC].flags | (instr->flags & ~opcodeinfo[PC_SUBF].flags);
- change_opcode(instr, PC_SUBFIC);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- instr->args[3].kind = PCOp_REGISTER;
- instr->args[3].arg = RegClass_SPR;
- instr->args[3].data.reg.reg = 0;
- instr->args[3].data.reg.effect = EffectWrite;
- change_num_operands(instr, 4);
- }
- propagatedconstants = 1;
- changed = 1;
- }
-
- break;
-
- case PC_LBZ:
- case PC_LHZ:
- case PC_LHA:
- case PC_LWZ:
- case PC_STB:
- case PC_STH:
- case PC_STW:
- case PC_LFS:
- case PC_LFD:
- case PC_STFS:
- case PC_STFD:
- if (instr->args[2].kind == PCOp_IMMEDIATE) {
- PCode *stackInstr;
- SInt16 addend = instr->args[2].data.imm.value;
-
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, addend))) {
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- instr->args[2].data.imm.value = value1 + addend;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000))
- instr->alias = make_alias(instr->args[2].data.imm.obj, instr->args[2].data.imm.value,
- nbytes_loaded_or_stored_by(instr));
- propagatedconstants = 1;
- changed = 1;
- }
- }
- break;
-
- case PC_LBZX:
- case PC_LHZX:
- case PC_LHAX:
- case PC_LWZX:
- case PC_STBX:
- case PC_STHX:
- case PC_STWX:
- case PC_LFSX:
- case PC_LFDX:
- case PC_STFSX:
- case PC_STFDX:
- if (isconstantoperand(&instr->args[2], &value1)) {
- instr->op -= 2;
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else if (isconstantoperand(&instr->args[1], &value1)) {
- instr->op -= 2;
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
-
- break;
- }
-
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite)
- )
- {
- defininginstruction[op->data.reg.reg] = instr;
- }
- else if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_VR &&
- (op->data.reg.effect & EffectWrite)
- )
- {
- vrdefininginstruction[op->data.reg.reg] = instr;
- }
- }
- }
-}
-
-void propagateconstants(void) {
- PCodeBlock *block;
- int i;
-
- propagatedconstants = 0;
- computeusedefchains(0);
- defininginstruction = galloc(sizeof(PCode *) * used_virtual_registers[RegClass_GPR]);
- vrdefininginstruction = galloc(sizeof(PCode *) * used_virtual_registers[RegClass_VR]);
-
- do {
- changed = 0;
- for (i = 0; i < pcblockcount; i++) {
- if ((block = depthfirstordering[i])) {
- computedefininginstructions(block);
- propagateconstantstoblock(block);
- }
- }
- } while (changed);
-
- freeoheap();
-}
diff --git a/compiler_and_linker/unsorted/uDump.c b/compiler_and_linker/unsorted/DumpIR.c
index 89574a5..5f6eea4 100644
--- a/compiler_and_linker/unsorted/uDump.c
+++ b/compiler_and_linker/unsorted/DumpIR.c
@@ -1,4 +1,4 @@
-#include "compiler/uDump.h"
+#include "compiler/DumpIR.h"
#include "compiler/CFunc.h"
#include "compiler/CInt64.h"
#include "compiler/CMachine.h"
diff --git a/compiler_and_linker/unsorted/Exceptions.c b/compiler_and_linker/unsorted/Exceptions.c
deleted file mode 100644
index 14627cf..0000000
--- a/compiler_and_linker/unsorted/Exceptions.c
+++ /dev/null
@@ -1,857 +0,0 @@
-#include "compiler/Exceptions.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CInit.h"
-#include "compiler/CFunc.h"
-#include "compiler/CParser.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/objects.h"
-
-static PCAction *pc_actions;
-static PCAction *last_pc_action;
-EANode *DAG[EAT_NACTIONS];
-static GList exceptmodule;
-static OLinkList *except_refs;
-static OLinkList *last_except_ref;
-
-static EANode *makeEAnode(ExceptionAction *ea) {
- EANode *prev;
- EANode *node;
-
- for (node = DAG[ea->type]; node; node = node->dagListNext) {
- if (node->action == ea)
- return node;
- }
-
- if (ea->prev)
- prev = makeEAnode(ea->prev);
- else
- prev = NULL;
-
- for (node = DAG[ea->type]; node; node = node->dagListNext) {
- if (node->prev == prev && CExcept_ActionCompare(node->action, ea))
- return node;
- }
-
- node = lalloc(sizeof(EANode));
- node->prev = prev;
- node->action = ea;
- node->count = 0;
- node->xE = 0;
-
- node->dagListNext = DAG[ea->type];
- DAG[ea->type] = node;
-
- if (prev)
- prev->count++;
- return node;
-}
-
-static void addrelocation(Object *obj, SInt32 offset) {
- OLinkList *ref;
-
- ref = lalloc(sizeof(OLinkList));
- ref->next = NULL;
- ref->obj = obj;
- ref->offset = offset;
- ref->somevalue = 0;
- if (except_refs)
- last_except_ref->next = ref;
- else
- except_refs = ref;
- last_except_ref = ref;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct AABC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt32 d;
-} AABC;
-
-typedef struct AACC {
- UInt8 a;
- UInt8 b;
- UInt32 c;
- UInt32 d;
-} AACC;
-
-typedef struct AABBC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt16 d;
- UInt32 e;
-} AABBC;
-
-typedef struct AABCC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt32 d;
- UInt32 e;
-} AABCC;
-
-typedef struct AACCC {
- UInt8 a;
- UInt8 b;
- UInt32 c;
- UInt32 d;
- UInt32 e;
-} AACCC;
-
-typedef struct AABBBC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt16 d;
- UInt16 e;
- UInt32 f;
-} AABBBC;
-
-typedef struct AABBCC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt16 d;
- UInt32 e;
- UInt32 f;
-} AABBCC;
-
-typedef struct AACCCC {
- UInt8 a;
- UInt8 b;
- UInt32 c;
- UInt32 d;
- UInt32 e;
- UInt32 f;
-} AACCCC;
-
-typedef struct AABCCCC {
- UInt8 a;
- UInt8 b;
- UInt16 c;
- UInt32 d;
- UInt32 e;
- UInt32 f;
- UInt32 g;
-} AABCCCC;
-
-typedef struct AACCCCC {
- UInt8 a;
- UInt8 b;
- UInt32 c;
- UInt32 d;
- UInt32 e;
- UInt32 f;
- UInt32 g;
-} AACCCCC;
-
-typedef struct AAB {
- UInt8 a;
- UInt8 b;
- UInt16 c;
-} AAB;
-
-typedef struct AAC {
- UInt8 a;
- UInt8 b;
- UInt32 c;
-} AAC;
-
-typedef struct AA {
- UInt8 a;
- UInt8 b;
-} AA;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void allocateactioninfo(EANode *node) {
- ExceptionAction *ea;
- SInt32 offset;
- UInt32 flag26;
- int reg;
- int reg2;
-
- while (node && (node->xE == 0 || node->prev == NULL)) {
- offset = exceptmodule.size;
- if (node->xE == 0)
- node->xE = offset;
-
- flag26 = node->prev ? 0 : 0x80;
-
- ea = node->action;
-
- switch (ea->type) {
- case EAT_NOP:
- CError_FATAL(146);
- break;
- case EAT_DESTROYLOCAL: {
- if (local_is_16bit_offset(ea->data.destroy_local.local)) {
- AABC e;
- e.a = flag26 | 2;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(local_offset_16(ea->data.destroy_local.local));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local.dtor, offset + 4);
- } else {
- AACC e;
- e.a = flag26 | 0x11;
- e.b = 0;
- e.c = CTool_EndianConvertWord32(local_offset_32(ea->data.destroy_local.local));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local.dtor, offset + 6);
- }
- break;
- }
- case EAT_DESTROYLOCALCOND: {
- reg = OBJECT_REG(ea->data.destroy_local_cond.cond);
- if (
- (reg || local_is_16bit_offset(ea->data.destroy_local_cond.cond)) &&
- local_is_16bit_offset(ea->data.destroy_local_cond.local)
- )
- {
- AABBC e;
- e.a = flag26 | 3;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_local_cond.cond));
- e.d = CTool_EndianConvertWord16(local_offset_16(ea->data.destroy_local_cond.local));
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_cond.dtor, offset + 6);
- } else {
- AACCC e;
- e.a = flag26 | 0x12;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_local_cond.cond));
- e.d = CTool_EndianConvertWord32(local_offset_32(ea->data.destroy_local_cond.local));
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_cond.dtor, offset + 10);
- }
- break;
- }
- case EAT_DESTROYLOCALOFFSET: {
- if (local_is_16bit_offset(ea->data.destroy_local_offset.local)) {
- AABC e;
- e.a = flag26 | 2;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(ea->data.destroy_local_offset.offset + local_offset_16(ea->data.destroy_local_offset.local));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_offset.dtor, offset + 4);
- } else {
- AACC e;
- e.a = flag26 | 0x11;
- e.b = 0;
- e.c = CTool_EndianConvertWord32(ea->data.destroy_local_offset.offset + local_offset_32(ea->data.destroy_local_offset.local));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_offset.dtor, offset + 6);
- }
- break;
- }
- case EAT_DESTROYLOCALPOINTER: {
- reg = OBJECT_REG(ea->data.destroy_local_pointer.pointer);
- if (reg || local_is_16bit_offset(ea->data.destroy_local_pointer.pointer)) {
- AABC e;
- e.a = flag26 | 4;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_local_pointer.pointer));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_pointer.dtor, offset + 4);
- } else {
- AACC e;
- e.a = flag26 | 0x13;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_local_pointer.pointer));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_pointer.dtor, offset + 6);
- }
- break;
- }
- case EAT_DESTROYLOCALARRAY: {
- if (local_is_16bit_offset(ea->data.destroy_local_array.localarray)) {
- AABBBC e;
- e.a = flag26 | 5;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(local_offset_16(ea->data.destroy_local_array.localarray));
- e.d = CTool_EndianConvertWord16(ea->data.destroy_local_array.elements);
- e.e = CTool_EndianConvertWord16(ea->data.destroy_local_array.element_size);
- e.f = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_array.dtor, offset + 8);
- } else {
- AACCCC e;
- e.a = flag26 | 0x14;
- e.b = 0;
- e.c = CTool_EndianConvertWord32(local_offset_32(ea->data.destroy_local_array.localarray));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_local_array.elements);
- e.e = CTool_EndianConvertWord32(ea->data.destroy_local_array.element_size);
- e.f = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_local_array.dtor, offset + 14);
- }
- break;
- }
- case EAT_DESTROYMEMBER: {
- reg = OBJECT_REG(ea->data.destroy_member.objectptr);
- if (reg || local_is_16bit_offset(ea->data.destroy_member.objectptr)) {
- AABCC e;
- e.a = flag26 | 7;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_member.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member.offset);
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member.dtor, offset + 8);
- } else {
- AACCC e;
- e.a = flag26 | 0x16;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_member.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member.offset);
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member.dtor, offset + 10);
- }
- break;
- }
- case EAT_DESTROYBASE: {
- reg = OBJECT_REG(ea->data.destroy_member.objectptr);
- if (reg || local_is_16bit_offset(ea->data.destroy_member.objectptr)) {
- AABCC e;
- e.a = flag26 | 6;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_member.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member.offset);
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member.dtor, offset + 8);
- } else {
- AACCC e;
- e.a = flag26 | 0x15;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_member.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member.offset);
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member.dtor, offset + 10);
- }
- break;
- }
- case EAT_DESTROYMEMBERCOND: {
- reg = OBJECT_REG(ea->data.destroy_member_cond.cond);
- reg2 = OBJECT_REG(ea->data.destroy_member_cond.objectptr);
- if (
- (reg || local_is_16bit_offset(ea->data.destroy_member_cond.cond)) &&
- (reg2 || local_is_16bit_offset(ea->data.destroy_member_cond.objectptr))
- )
- {
- AABBCC e;
- e.a = flag26 | 8;
- e.b = ((reg ? 1 : 0) << 7) | ((reg2 ? 1 : 0) << 6);
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_member_cond.cond));
- e.d = CTool_EndianConvertWord16(reg2 ? reg2 : local_offset_16(ea->data.destroy_member_cond.objectptr));
- e.e = CTool_EndianConvertWord32(ea->data.destroy_member_cond.offset);
- e.f = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member_cond.dtor, offset + 10);
- } else {
- AACCCC e;
- e.a = flag26 | 0x17;
- e.b = ((reg ? 1 : 0) << 7) | ((reg2 ? 1 : 0) << 6);
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_member_cond.cond));
- e.d = CTool_EndianConvertWord32(reg2 ? reg2 : local_offset_32(ea->data.destroy_member_cond.objectptr));
- e.e = CTool_EndianConvertWord32(ea->data.destroy_member_cond.offset);
- e.f = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member_cond.dtor, offset + 14);
- }
- break;
- }
- case EAT_DESTROYMEMBERARRAY: {
- reg = OBJECT_REG(ea->data.destroy_member_array.objectptr);
- if (reg || local_is_16bit_offset(ea->data.destroy_member_array.objectptr)) {
- AABCCCC e;
- e.a = flag26 | 9;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.destroy_member_array.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member_array.offset);
- e.e = CTool_EndianConvertWord32(ea->data.destroy_member_array.elements);
- e.f = CTool_EndianConvertWord32(ea->data.destroy_member_array.element_size);
- e.g = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member_array.dtor, offset + 16);
- } else {
- AACCCCC e;
- e.a = flag26 | 0x18;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.destroy_member_array.objectptr));
- e.d = CTool_EndianConvertWord32(ea->data.destroy_member_array.offset);
- e.e = CTool_EndianConvertWord32(ea->data.destroy_member_array.elements);
- e.f = CTool_EndianConvertWord32(ea->data.destroy_member_array.element_size);
- e.g = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.destroy_member_array.dtor, offset + 18);
- }
- break;
- }
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER: {
- reg = OBJECT_REG(ea->data.delete_pointer.pointerobject);
- if (reg || local_is_16bit_offset(ea->data.delete_pointer.pointerobject)) {
- AABC e;
- e.a = flag26 | 0xA;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.delete_pointer.pointerobject));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.delete_pointer.deletefunc, offset + 4);
- } else {
- AACC e;
- e.a = flag26 | 0x19;
- e.b = (reg != 0) << 7;
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.delete_pointer.pointerobject));
- e.d = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.delete_pointer.deletefunc, offset + 6);
- }
- break;
- }
- case EAT_DELETEPOINTERCOND: {
- reg = OBJECT_REG(ea->data.delete_pointer_cond.cond);
- reg2 = OBJECT_REG(ea->data.delete_pointer_cond.pointerobject);
- if (
- (reg || local_is_16bit_offset(ea->data.delete_pointer_cond.cond)) &&
- (reg2 || local_is_16bit_offset(ea->data.delete_pointer_cond.pointerobject))
- )
- {
- AABBC e;
- e.a = flag26 | 0xB;
- e.b = ((reg ? 1 : 0) << 7) | ((reg2 ? 1 : 0) << 6);
- e.c = CTool_EndianConvertWord16(reg ? reg : local_offset_16(ea->data.delete_pointer_cond.cond));
- e.d = CTool_EndianConvertWord16(reg2 ? reg2 : local_offset_16(ea->data.delete_pointer_cond.pointerobject));
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.delete_pointer_cond.deletefunc, offset + 6);
- } else {
- AACCC e;
- e.a = flag26 | 0x1A;
- e.b = ((reg ? 1 : 0) << 7) | ((reg2 ? 1 : 0) << 6);
- e.c = CTool_EndianConvertWord32(reg ? reg : local_offset_32(ea->data.delete_pointer_cond.cond));
- e.d = CTool_EndianConvertWord32(reg2 ? reg2 : local_offset_32(ea->data.delete_pointer_cond.pointerobject));
- e.e = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- addrelocation(ea->data.delete_pointer_cond.deletefunc, offset + 10);
- }
- break;
- }
- case EAT_CATCHBLOCK: {
- AACCC e;
- e.a = flag26 | 0x10;
- e.b = 0;
- e.c = 0;
- if (ea->data.catch_block.catch_label->pclabel)
- e.d = CTool_EndianConvertWord32(ea->data.catch_block.catch_label->pclabel->block->codeOffset);
- else
- e.d = 0;
- e.e = CTool_EndianConvertWord32(local_offset_16(ea->data.catch_block.catch_info_object));
- AppendGListData(&exceptmodule, &e, sizeof(e));
- if (ea->data.catch_block.catch_typeid)
- addrelocation(ea->data.catch_block.catch_typeid, offset + 2);
- break;
- }
- case EAT_ACTIVECATCHBLOCK: {
- if (local_is_16bit_offset(ea->data.active_catch_block.catch_info_object)) {
- AAB e;
- e.a = flag26 | 0xD;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(local_offset_16(ea->data.active_catch_block.catch_info_object));
- AppendGListData(&exceptmodule, &e, sizeof(e));
- } else {
- AAC e;
- e.a = flag26 | 0x1B;
- e.b = 0;
- e.c = CTool_EndianConvertWord32(local_offset_32(ea->data.active_catch_block.catch_info_object));
- AppendGListData(&exceptmodule, &e, sizeof(e));
- }
- break;
- }
- case EAT_SPECIFICATION: {
- AABCC e;
- int i;
-
- e.a = flag26 | 0xF;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(ea->data.specification.unexp_ids);
- if (ea->data.specification.unexp_label->pclabel)
- e.d = CTool_EndianConvertWord32(ea->data.specification.unexp_label->pclabel->block->codeOffset);
- e.e = CTool_EndianConvertWord32(local_offset_16(ea->data.specification.unexp_info_object));
- AppendGListData(&exceptmodule, &e, sizeof(e));
-
- for (i = 0; i < ea->data.specification.unexp_ids; i++) {
- addrelocation(ea->data.specification.unexp_id[i], 12 + i * 4 + offset);
- AppendGListLong(&exceptmodule, 0);
- }
- break;
- }
- case EAT_TERMINATE: {
- AA e;
- e.a = flag26 | 0xE;
- e.b = 0;
- AppendGListData(&exceptmodule, &e, sizeof(e));
- break;
- }
- default:
- CError_FATAL(671);
- }
-
- node = node->prev;
- }
-
- if (node) {
- AAB e;
- e.a = 1;
- e.b = 0;
- e.c = CTool_EndianConvertWord16(node->xE);
- AppendGListData(&exceptmodule, &e, sizeof(e));
- }
-}
-
-static UInt32 findPC(PCode *instr) {
- UInt32 pc = instr->block->codeOffset;
- instr = instr->prevPCode;
- while (instr) {
- instr = instr->prevPCode;
- pc += 4;
- }
- CError_ASSERT(704, FITS_IN_USHORT(pc));
- return pc;
-}
-
-static UInt32 findPC_long(PCode *instr) {
- UInt32 pc = instr->block->codeOffset;
- instr = instr->prevPCode;
- while (instr) {
- instr = instr->prevPCode;
- pc += 4;
- }
- return pc;
-}
-
-void initializeexceptiontables(void) {
- int i;
-
- for (i = 0; i < EAT_NACTIONS; i++)
- DAG[i] = NULL;
-
- pc_actions = last_pc_action = NULL;
- except_refs = last_except_ref = NULL;
-}
-
-int countexceptionactionregisters(ExceptionAction *actions) {
- int count = 0;
-
- while (actions) {
- switch (actions->type) {
- case EAT_DESTROYLOCALCOND:
- if (OBJECT_REG(actions->data.destroy_local_cond.cond))
- count++;
- break;
- case EAT_DESTROYLOCALPOINTER:
- if (OBJECT_REG(actions->data.destroy_local_pointer.pointer))
- count++;
- break;
- case EAT_DESTROYMEMBER:
- if (OBJECT_REG(actions->data.destroy_member.objectptr))
- count++;
- break;
- case EAT_DESTROYBASE:
- if (OBJECT_REG(actions->data.destroy_base.objectptr))
- count++;
- break;
- case EAT_DESTROYMEMBERCOND:
- if (OBJECT_REG(actions->data.destroy_member_cond.cond))
- count++;
- if (OBJECT_REG(actions->data.destroy_member_cond.objectptr))
- count++;
- break;
- case EAT_DESTROYMEMBERARRAY:
- if (OBJECT_REG(actions->data.destroy_member_array.objectptr))
- count++;
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- if (OBJECT_REG(actions->data.delete_pointer.pointerobject))
- count++;
- break;
- case EAT_DELETEPOINTERCOND:
- if (OBJECT_REG(actions->data.delete_pointer_cond.cond))
- count++;
- if (OBJECT_REG(actions->data.delete_pointer_cond.pointerobject))
- count++;
- break;
- }
- actions = actions->prev;
- }
-
- return count;
-}
-
-void noteexceptionactionregisters(ExceptionAction *actions, PCodeArg *ops) {
- Object *obj;
- int reg;
-
- while (actions) {
- switch (actions->type) {
- case EAT_DESTROYLOCALCOND:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_local_cond.cond))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DESTROYLOCALPOINTER:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_local_pointer.pointer))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DESTROYMEMBER:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_member.objectptr))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DESTROYBASE:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_base.objectptr))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DESTROYMEMBERCOND:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_member_cond.cond))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- if ((reg = OBJECT_REG(obj = actions->data.destroy_member_cond.objectptr))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DESTROYMEMBERARRAY:
- if ((reg = OBJECT_REG(obj = actions->data.destroy_member_array.objectptr))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DELETEPOINTER:
- case EAT_DELETELOCALPOINTER:
- if ((reg = OBJECT_REG(obj = actions->data.delete_pointer.pointerobject))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- case EAT_DELETEPOINTERCOND:
- if ((reg = OBJECT_REG(obj = actions->data.delete_pointer_cond.cond))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- if ((reg = OBJECT_REG(obj = actions->data.delete_pointer_cond.pointerobject))) {
- ops->kind = PCOp_REGISTER;
- ops->arg = obj->u.var.info->rclass;
- ops->data.reg.reg = reg;
- ops->data.reg.effect = EffectRead | Effect8;
- ops++;
- }
- break;
- }
- actions = actions->prev;
- }
-}
-
-void recordexceptionactions(PCode *instr, ExceptionAction *actions) {
- PCAction *pca;
-
- if (!actions && (!last_pc_action || !last_pc_action->actions))
- return;
-
- pca = lalloc(sizeof(PCAction));
- pca->next = NULL;
- pca->firstInstr = pca->lastInstr = instr;
- pca->actions = actions;
- pca->prev = last_pc_action;
- if (last_pc_action)
- last_pc_action->next = pca;
- else
- pc_actions = pca;
- last_pc_action = pca;
-
- branch_label(makepclabel());
- while (actions) {
- if (actions->type == EAT_CATCHBLOCK && actions->data.catch_block.catch_label->pclabel)
- pcbranch(instr->block, actions->data.catch_block.catch_label->pclabel);
- else if (actions->type == EAT_SPECIFICATION && actions->data.specification.unexp_label->pclabel)
- pcbranch(instr->block, actions->data.specification.unexp_label->pclabel);
- actions = actions->prev;
- }
-}
-
-static void deleteexceptionaction(PCAction *pca) {
- if (pca->prev)
- pca->prev->next = pca->next;
- else
- pc_actions = pca->next;
-
- if (pca->next)
- pca->next->prev = pca->prev;
-}
-
-static int mergeexceptionactions(void) {
- int count;
- PCAction *pca;
- PCAction *prev;
-
- if (!pc_actions)
- return 0;
-
- for (pca = pc_actions; pca; pca = pca->next) {
- if (pca->firstInstr->block->flags & fDeleted)
- deleteexceptionaction(pca);
- }
-
- if (!(pca = pc_actions))
- return 0;
-
- while (pca) {
- pca->node = pca->actions ? makeEAnode(pca->actions) : NULL;
- pca = pca->next;
- }
-
- prev = pc_actions;
- for (pca = pc_actions->next; pca; pca = pca->next) {
- if (pca->node == prev->node) {
- prev->lastInstr = pca->lastInstr;
- deleteexceptionaction(pca);
- } else {
- prev = pca;
- }
- }
-
- count = 0;
- for (pca = pc_actions; pca; pca = pca->next) {
- if (!pca->actions)
- deleteexceptionaction(pca);
- else
- count++;
- }
-
- return count;
-}
-
-typedef struct ExceptionThing {
- UInt32 x0;
- UInt16 x4;
- UInt16 x6;
-} ExceptionThing;
-
-void dumpexceptiontables(Object *function, SInt32 codesize) {
- PCAction *pca;
- UInt32 insn_start;
- UInt32 insn_count;
- UInt16 *sh;
- ExceptionThing *thing;
- int count;
-
- count = mergeexceptionactions();
- InitGList(&exceptmodule, 256);
- AppendGListNoData(&exceptmodule, 8 * count + 4);
- AppendGListLong(&exceptmodule, 0);
-
- for (pca = pc_actions; pca; pca = pca->next) {
- if (pca->node->count == 0 && pca->node->xE == 0)
- allocateactioninfo(pca->node);
- }
-
- sh = (UInt16 *) *exceptmodule.data;
- if (copts.altivec_model && used_nonvolatile_registers[RegClass_VR]) {
- sh[0] =
- CTool_EndianConvertWord16(
- (used_nonvolatile_registers[RegClass_GPR] << 11) |
- ((used_nonvolatile_registers[RegClass_FPR] & 0x1F) << 6) |
- (((used_nonvolatile_registers[RegClass_CRFIELD] != 0) & 1) << 5) |
- ((dynamic_stack & 1) << 4) |
- 8);
- sh[0] |= 4;
- if (copts.altivec_vrsave)
- sh[1] = CTool_EndianConvertWord16((used_nonvolatile_registers[RegClass_VR] << 11) | 0x400);
- else
- sh[1] = CTool_EndianConvertWord16((used_nonvolatile_registers[RegClass_VR] & 0x1F) << 11);
- } else {
- sh[0] =
- CTool_EndianConvertWord16(
- (used_nonvolatile_registers[RegClass_GPR] << 11) |
- ((used_nonvolatile_registers[RegClass_FPR] & 0x1F) << 6) |
- (((used_nonvolatile_registers[RegClass_CRFIELD] != 0) & 1) << 5) |
- ((dynamic_stack & 1) << 4) |
- 8);
- sh[1] = 0;
- }
-
- thing = (ExceptionThing *) (sh + 2);
- pca = pc_actions;
- while (pca) {
- insn_start = findPC_long(pca->firstInstr);
- insn_count = (findPC_long(pca->lastInstr) - insn_start) / 4;
- CError_ASSERT(1203, (insn_count & 0xFFFF0000) == 0);
- thing->x0 = CTool_EndianConvertWord32(insn_start + 4);
- thing->x4 = CTool_EndianConvertWord16(insn_count);
- thing->x6 = CTool_EndianConvertWord16(pca->node->xE);
- pca = pca->next;
- thing++;
- }
-
- LockGList(&exceptmodule);
- ObjGen_DeclareExceptionTables(function, codesize, *exceptmodule.data, exceptmodule.size, except_refs);
- FreeGList(&exceptmodule);
-}
diff --git a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c b/compiler_and_linker/unsorted/FuncLevelAsmPPC.c
deleted file mode 100644
index 27528b8..0000000
--- a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c
+++ /dev/null
@@ -1,393 +0,0 @@
-#include "compiler/FuncLevelAsmPPC.h"
-#include "compiler/CCompiler.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CodeGen.h"
-#include "compiler/Coloring.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/uDump.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/InlineAsmRegisters.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeAssembly.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/PPCError.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/objects.h"
-
-static EntryPoint *entrypoints_head;
-static EntryPoint **entrypoints_tail;
-
-void setup_assembly_argument(Object *obj, short reg) {
- VarInfo *vi;
- Type *type;
-
- vi = Registers_GetVarInfo(obj);
- type = obj->type;
- vi->used = 1;
-
- if (!requires_frame) {
- if (is_register_object(obj)) {
- if (!reg)
- CError_Error(CErrorStr263, obj->name->name);
-
- if (TYPE_IS_8BYTES(type)) {
- short regLo;
- short regHi;
- if (reg < 10) {
- if (copts.littleendian) {
- regLo = reg;
- regHi = reg + 1;
- } else {
- regLo = reg + 1;
- regHi = reg;
- }
- retain_GPR_pair(obj, regLo, regHi);
- InlineAsm_InsertRegister(obj->name->name, RegClass_GPR, regLo, obj);
- }
- } else if (IS_TYPE_FLOAT(type)) {
- retain_register(obj, RegClass_FPR, reg);
- InlineAsm_InsertRegister(obj->name->name, RegClass_FPR, reg, obj);
- } else if (IS_TYPE_VECTOR(type)) {
- retain_register(obj, RegClass_VR, reg);
- InlineAsm_InsertRegister(obj->name->name, RegClass_VR, reg, obj);
- } else {
- retain_register(obj, RegClass_GPR, reg);
- InlineAsm_InsertRegister(obj->name->name, RegClass_GPR, reg, obj);
- }
- }
- } else {
- if (is_register_object(obj)) {
- vi = Registers_GetVarInfo(obj);
- if (!vi->reg) {
- assign_register_by_type(obj);
- if (!(vi->flags & VarInfoFlag2))
- CError_Error(CErrorStr263, obj->name->name);
- else
- InlineAsm_InsertRegister(obj->name->name, vi->rclass, vi->reg, obj);
- }
- }
- }
-}
-
-void assign_local_addresses(void) {
- VarInfo *vi;
- ObjectList *list;
- Object *object;
-
- for (list = locals; list; list = list->next) {
- vi = CodeGen_GetNewVarInfo();
- list->object->u.var.info = vi;
- list->object->flags |= OBJECT_USED;
- vi->used = 1;
- }
-
- for (list = locals; list; list = list->next) {
- object = list->object;
- if (is_register_object(object)) {
- vi = Registers_GetVarInfo(object);
- if (!vi->reg) {
- assign_register_by_type(object);
- if (!(vi->flags & VarInfoFlag2))
- CError_Error(CErrorStr263, object->name->name);
- else
- InlineAsm_InsertRegister(object->name->name, vi->rclass, vi->reg, object);
- }
- }
- }
-
- for (list = locals; list; list = list->next) {
- object = list->object;
- if (OBJECT_REG(object) == 0)
- assign_local_memory(object);
- }
-}
-
-static void FuncAsm_PreScanDirectives(void) {
- SInt32 directive;
- Boolean save_eoltokens;
-
- in_assembler = 1;
- save_eoltokens = cprep_eoltokens;
- cprep_eoltokens = 1;
-
- if (setjmp(InlineAsm_assemblererror) == 0) {
- while (tk == TK_IDENTIFIER && (directive = InlineAsm_IsDirective(AssemblerType_1))) {
- InlineAsm_ProcessDirective(directive);
-
- if (tk == ';' || tk == TK_EOL) {
- CPrep_TokenStreamFlush();
- tk = lex();
- } else {
- InlineAsm_SyntaxError(CErrorStr113);
- }
-
- if (directive == IADirective_FrAlloc) {
- requires_frame = 1;
- break;
- } else if (directive == IADirective_NoFrAlloc) {
- user_responsible_for_frame = 1;
- break;
- }
- }
- }
-
- in_assembler = 0;
- cprep_eoltokens = save_eoltokens;
-}
-
-static void FuncAsm_AddEntryPoint(Statement *stmt, PCodeBlock *block) {
- EntryPoint *ep;
- IAEntryPoint *ia_ep;
-
- ia_ep = (IAEntryPoint *) stmt->expr;
- ep = lalloc(sizeof(EntryPoint));
- memclrw(ep, sizeof(EntryPoint));
-
- ep->object = ia_ep->x8;
- ep->block = block;
-
- *entrypoints_tail = ep;
- entrypoints_tail = &ep->next;
-
- block->flags |= fPCBlockFlag8000;
-}
-
-void Assembler(Object *func) {
- PCodeBlock *block;
- Statement *stmt;
- Boolean flag17;
- Boolean flag16;
- char *name;
- InlineAsm *ia;
- Boolean save_unusedvar;
- Boolean save_unusedarg;
-
- flag17 = 0;
- flag16 = 0;
-
- init_endian();
- init_stack_globals(func);
- memclrw(asm_alloc_flags, sizeof(asm_alloc_flags));
- fralloc_parameter_area_size = 0;
- user_responsible_for_frame = 0;
- assembledinstructions = 0;
-
- entrypoints_head = NULL;
- entrypoints_tail = &entrypoints_head;
-
- stmt = curstmt;
-
- if (func && func->name)
- PrintProgressFunction(func->name->name);
-
- CodeGen_InitialSanityCheck();
-
- if (func->qual & Q_INLINE)
- PPCError_Warning(PPCErrorStr173);
-
- CheckCLabels();
-
- if (fatalerrors)
- return;
-
- if (copts.filesyminfo)
- CPrep_SetSourceFile(&cparser_fileoffset);
-
- sm_section = SECT_TEXT;
-
- initpcode();
-
- pclabel(prologue = makepcblock(), makepclabel());
- pclabel(block = makepcblock(), makepclabel());
- pcbranch(prologue, block->labels);
-
- resetTOCvarinfo();
- InlineAsm_InitializePPC();
- FuncAsm_PreScanDirectives();
-
- disable_optimizer = 1;
-
- init_registers();
- assign_arguments_to_memory(func, 0, 0);
- init_frame_sizes(0);
-
- if (copts.debuglisting)
- DumpIR(stmt, func);
-
- cprep_eoltokens = 1;
- in_assembler = 1;
-
- save_unusedvar = copts.warn_unusedvar;
- save_unusedarg = copts.warn_unusedarg;
- copts.warn_unusedvar = 0;
- copts.warn_unusedarg = 0;
-
- InlineAsm_ScanFunction('}');
-
- expandTOCreferences(&stmt->next);
-
- if (!anyerrors && copts.debuglisting)
- DumpIR(stmt, func);
-
- in_assembler = 0;
- cprep_eoltokens = 0;
-
- name = CMangler_GetLinkName(func)->name;
- func->flags |= OBJECT_DEFINED;
-
- if (fralloc_parameter_area_size)
- update_out_param_size(fralloc_parameter_area_size);
- if (!user_responsible_for_frame)
- process_arguments(move_assigned_argument, 0);
-
- branch_label(makepclabel());
- assign_labels(stmt->next);
-
- copts.warn_unusedvar = save_unusedvar;
- copts.warn_unusedarg = save_unusedarg;
-
- for (stmt = stmt->next; stmt; stmt = stmt->next) {
- current_statement = stmt;
- switch (stmt->type) {
- case ST_ASM:
- if ((ia = (InlineAsm *) stmt->expr)) {
- if (ia->flags & IAFlag1) {
- if (ia->opcode == IADirective_Entry) {
- branch_label(makepclabel());
- FuncAsm_AddEntryPoint(stmt, pclastblock);
- } else if (ia->opcode == IADirective_FrFree) {
- if (flag16)
- PPCError_Error(PPCErrorStr188);
- else
- flag16 = 1;
-
- asm_alloc_flags[3] = 1;
- asm_alloc_flags[4] = 1;
- branch_label(makepclabel());
-
- epilogue = pclastblock;
- pclastblock->flags |= fIsEpilogue;
-
- CheckCLabels();
- if (fatalerrors)
- return;
-
- pccomputepredecessors();
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] INITIAL CODE");
- colorinstructions(func);
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] AFTER REGISTER COLORING");
- compute_frame_sizes();
- generate_prologue(prologue, 0);
- epilogue = pclastblock;
- generate_epilogue(epilogue, 0);
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] AFTER PROLOGUE/EPILOGUE CREATION");
-
- flag17 = 1;
- }
- } else {
- branch_label(makepclabel());
- asm_alloc_flags[6] = 0;
- asm_alloc_flags[7] = 0;
- InlineAsm_TranslateIRtoPCode(stmt);
- asm_alloc_flags[4] = 0;
- }
- }
- break;
- case ST_LABEL:
- if (!stmt->label->pclabel->resolved)
- branch_label(stmt->label->pclabel);
- break;
- default:
- CError_FATAL(525);
- }
- }
-
- current_statement = NULL;
-
- if (fatalerrors)
- return;
- CheckCLabels();
- if (fatalerrors)
- return;
-
- if (!flag17) {
- branch_label(makepclabel());
-
- epilogue = pclastblock;
- pclastblock->flags |= fIsEpilogue;
-
- pccomputepredecessors();
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] INITIAL CODE");
-
- if (!asm_alloc_flags[1]) {
- colorinstructions(func);
- if (fatalerrors)
- return;
-
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] AFTER REGISTER COLORING");
- }
-
- compute_frame_sizes();
- if (asm_alloc_flags[1])
- no_frame_for_asm();
-
- if (fatalerrors)
- return;
-
- if (!asm_alloc_flags[1]) {
- generate_prologue(prologue, 0);
- generate_epilogue(epilogue, !asm_alloc_flags[6] && !asm_alloc_flags[7]);
- }
-
- if (copts.debuglisting)
- pclistblocks(name, "[FUNCTION-LEVEL ASM] AFTER PROLOGUE/EPILOGUE CREATION");
- }
-
- if (fatalerrors)
- return;
-
- if (!asm_alloc_flags[1] && needs_frame()) {
- if (asm_alloc_flags[3]) {
- if (!asm_alloc_flags[5] || !asm_alloc_flags[6])
- PPCError_Warning(PPCErrorStr187, "blr");
- if (asm_alloc_flags[8])
- PPCError_Warning(PPCErrorStr186);
- } else {
- PPCError_Warning(PPCErrorStr185, "blr");
- }
- }
-
- func->section = sm_section;
-
- if (copts.filesyminfo)
- symdeclend = CPrep_GetFileOffsetInfo(&cparser_fileoffset);
-
- copts.peephole = 0;
- if (pic_base_label)
- pic_base_pcodelabel = pic_base_label->pclabel;
- assemblefunction(func, entrypoints_head);
-
- if (copts.debuglisting)
- pclistblocks(CMangler_GetLinkName(func)->name, "[FUNCTION-LEVEL ASM] FINAL CODE");
-
- CFunc_WarnUnused();
-}
-
-void SetupAssembler(void) {
-}
-
-void CleanupAssembler(void) {
-}
diff --git a/compiler_and_linker/unsorted/FunctionCalls.c b/compiler_and_linker/unsorted/FunctionCalls.c
deleted file mode 100644
index 67d7443..0000000
--- a/compiler_and_linker/unsorted/FunctionCalls.c
+++ /dev/null
@@ -1,642 +0,0 @@
-#include "compiler/FunctionCalls.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InstrSelection.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Registers.h"
-#include "compiler/StackFrame.h"
-#include "compiler/StructMoves.h"
-#include "compiler/types.h"
-
-enum {
- AIF_PassInGPR = 1,
- AIF_PassInFPR = 2,
- AIF_PassOnStack = 4,
- AIF_ExtendTo32Bits = 8,
- AIF_ForceDoublePrecision = 0x10,
- AIF_PassInVR = 0x20,
- AIF_PassMask = AIF_PassInGPR | AIF_PassInFPR | AIF_PassOnStack | AIF_PassInVR
-};
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct ArgInfo {
- struct ArgInfo *next;
- ENode *expr;
- Operand opnd;
- SInt32 offset;
- short gpr;
- short gprHi;
- short fpr;
- short vr;
- short evaluated;
- short flags;
-} ArgInfo;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// forward decls
-static void branch_subroutine_indirect_ctr(Operand *addrOpnd, UInt32 *used_regs);
-
-static ArgInfo *make_arginfo(ENode *expr) {
- ArgInfo *info = lalloc(sizeof(ArgInfo));
- memclrw(info, sizeof(ArgInfo));
-
- info->next = NULL;
- info->expr = expr;
- info->offset = -1;
- info->gpr = -1;
- info->gprHi = -1;
- info->fpr = -1;
- info->vr = -1;
- info->evaluated = 0;
- info->flags = 0;
-
- return info;
-}
-
-static ArgInfo *analyze_arguments(ENode *funcref, ENodeList *arg_expr, FuncArg *arg, UInt32 *used_regs, Boolean *resultHasFloats, char has_varargs) {
- ArgInfo *infos;
- ArgInfo *info;
- SInt32 displ;
- SInt32 arg_size;
- int gpr_counter;
- int fpr_counter;
- int vr_counter;
- Type *type;
- RegClass rclass;
- Boolean spilledVectorFlag;
-
- infos = NULL;
- displ = 0;
- gpr_counter = 3;
- fpr_counter = 1;
- vr_counter = 2;
-
- for (rclass = 0; rclass < RegClassMax; rclass++)
- used_regs[rclass] = 0;
- *resultHasFloats = 0;
-
- while (arg_expr) {
- if (arg_expr->node == funcref) {
- arg_expr = arg_expr->next;
- arg = arg->next;
- continue;
- }
-
- type = arg_expr->node->rtype;
- if (infos) {
- info->next = make_arginfo(arg_expr->node);
- info = info->next;
- } else {
- infos = info = make_arginfo(arg_expr->node);
- }
-
- arg_size = 0;
- if (IS_TYPE_VECTOR(type)) {
- if (arg == &elipsis) {
- spilledVectorFlag = 1;
- info->flags |= AIF_PassOnStack;
- } else {
- spilledVectorFlag = 0;
- if (vr_counter <= 13) {
- info->flags |= AIF_PassInVR;
- info->vr = vr_counter;
- used_regs[RegClass_VR] |= 1 << vr_counter;
- } else {
- spilledVectorFlag = 1;
- info->flags |= AIF_PassOnStack;
- }
- }
-
- if (has_varargs) {
- if (gpr_counter < 10) {
- gpr_counter = ((gpr_counter - 2) & ~3) + 5;
- if (arg == &elipsis && gpr_counter < 10) {
- info->flags |= AIF_PassInGPR;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= (15 << gpr_counter) & 0x7E0;
- }
- gpr_counter += 4;
- }
- spilledVectorFlag = 1;
- }
-
- if (spilledVectorFlag)
- arg_size = 16;
- vr_counter++;
- } else if (IS_TYPE_FLOAT(type)) {
- *resultHasFloats = 1;
- if (!arg || arg == &oldstyle) {
- if (fpr_counter <= 13) {
- info->flags |= AIF_PassInFPR;
- info->fpr = fpr_counter;
- used_regs[RegClass_FPR] |= 1 << fpr_counter;
- } else {
- info->flags |= AIF_PassOnStack | AIF_ForceDoublePrecision;
- }
- arg_size = 8;
- fpr_counter++;
- gpr_counter += 2;
- } else if (arg == &elipsis) {
- if (gpr_counter < 10) {
- info->flags |= AIF_PassInGPR;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= 3 << gpr_counter;
- } else if (gpr_counter == 10) {
- info->flags |= AIF_PassInGPR | AIF_PassOnStack | AIF_ForceDoublePrecision;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= 3 << gpr_counter;
- } else {
- info->flags |= AIF_PassOnStack | AIF_ForceDoublePrecision;
- }
- arg_size = 8;
- fpr_counter++;
- gpr_counter += 2;
- } else {
- if (fpr_counter <= 13) {
- info->flags |= AIF_PassInFPR;
- info->fpr = fpr_counter;
- used_regs[RegClass_FPR] |= 1 << fpr_counter;
- } else {
- info->flags |= AIF_PassOnStack;
- }
-
- if (type->size == 4) {
- arg_size = 4;
- gpr_counter++;
- } else {
- arg_size = 8;
- gpr_counter += 2;
- }
-
- fpr_counter++;
- }
- } else if (TYPE_IS_8BYTES(type)) {
- if (gpr_counter <= 10) {
- info->flags |= AIF_PassInGPR;
- if (copts.littleendian) {
- info->gpr = gpr_counter;
- info->gprHi = gpr_counter + 1;
- } else {
- info->gpr = gpr_counter + 1;
- info->gprHi = gpr_counter;
- }
- used_regs[RegClass_GPR] |= 1 << gpr_counter;
- if ((gpr_counter + 1) <= 10)
- used_regs[RegClass_GPR] |= 1 << (gpr_counter + 1);
- } else {
- info->flags |= AIF_PassOnStack;
- }
-
- arg_size = 8;
- gpr_counter += 2;
- } else if (TYPE_FITS_IN_REGISTER(type)) {
- if ((!arg || arg == &elipsis || arg == &oldstyle) && type->size < 4)
- info->flags |= AIF_ExtendTo32Bits;
-
- if (gpr_counter <= 10) {
- info->flags |= AIF_PassInGPR;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= 1 << gpr_counter;
- } else {
- info->flags |= AIF_PassOnStack;
- }
-
- arg_size = 4;
- gpr_counter++;
- } else if (IS_TYPE_ARRAY(type) || IS_TYPE_NONVECTOR_STRUCT(type) || IS_TYPE_CLASS(type) ||
- IS_TYPE_12BYTES_MEMBERPOINTER(type)) {
- SInt32 gprs_needed = (type->size >> 2) + ((type->size & 3) != 0);
- if (gpr_counter <= 10) {
- if ((gpr_counter + gprs_needed - 1) <= 10) {
- info->flags |= AIF_PassInGPR;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= ((1 << gprs_needed) - 1) << gpr_counter;
- } else {
- info->flags |= AIF_PassInGPR | AIF_PassOnStack;
- info->gpr = gpr_counter;
- used_regs[RegClass_GPR] |= ((1 << (11 - gpr_counter)) - 1) << gpr_counter;
- }
- } else {
- info->flags |= AIF_PassOnStack;
- }
-
- gpr_counter += gprs_needed;
- arg_size = type->size;
- } else {
- CError_FATAL(421);
- }
-
- displ = set_out_param_displ(displ, type, info->flags & AIF_PassOnStack, &info->offset, arg_size);
-
- arg_expr = arg_expr->next;
- if (arg && arg != &elipsis && arg != &oldstyle)
- arg = arg->next;
- }
-
- update_out_param_size(displ);
-
- return infos;
-}
-
-static void pass_in_memory(ArgInfo *info) {
- Type *type;
- Operand opnd;
-
- type = info->expr->rtype;
- memclrw(&opnd, sizeof(Operand));
-
- if (TYPE_FITS_IN_REGISTER(type)) {
- if (TYPE_IS_8BYTES(type)) {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
- coerce_to_register_pair(&info->opnd, type, 0, 0);
-
- load_store_register(
- PC_STW, info->opnd.reg, 1,
- NULL, low_offset + out_param_displ_to_offset(info->offset));
- load_store_register(
- PC_STW, info->opnd.regHi, 1,
- NULL, high_offset + out_param_displ_to_offset(info->offset));
- } else {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
- if (info->flags & AIF_ExtendTo32Bits)
- extend32(&info->opnd, type, 0);
- ENSURE_GPR(&info->opnd, type, 0);
-
- load_store_register(
- PC_STW, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- }
- } else if (IS_TYPE_FLOAT(type)) {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
- ENSURE_FPR(&info->opnd, type, 0);
-
- if (type->size == 4 && !(info->flags & AIF_ForceDoublePrecision)) {
- load_store_register(
- PC_STFS, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- } else {
- load_store_register(
- PC_STFD, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- }
- } else if (IS_TYPE_VECTOR(type)) {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
- ENSURE_VR(&info->opnd, type, 0);
-
- load_store_register(
- PC_STVX, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- } else {
- opnd.optype = OpndType_IndirectGPR_ImmOffset;
- opnd.reg = 1;
- opnd.object = NULL;
- opnd.immOffset = out_param_displ_to_offset(info->offset);
-
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
-
- move_block(&opnd, &info->opnd, type->size, CMach_ArgumentAlignment(type));
- }
-}
-
-static void pass_in_register(ArgInfo *info) {
- Type *type;
-
- type = info->expr->rtype;
-
- if ((info->flags & AIF_PassMask) == AIF_PassInFPR) {
- if (!info->evaluated)
- GEN_NODE_TO_REG(info->expr, info->fpr, 0, &info->opnd);
- ENSURE_FPR(&info->opnd, type, info->fpr);
- if (info->opnd.reg != info->fpr)
- emitpcode(PC_FMR, info->fpr, info->opnd.reg);
- } else if ((info->flags & AIF_PassMask) == AIF_PassInVR) {
- if (!info->evaluated)
- GEN_NODE_TO_REG(info->expr, info->vr, 0, &info->opnd);
- ENSURE_VR(&info->opnd, type, info->vr);
- if (info->opnd.reg != info->vr)
- emitpcode(PC_VMR, info->vr, info->opnd.reg);
- } else if (TYPE_FITS_IN_REGISTER(type)) {
- if (TYPE_IS_8BYTES(type)) {
- if (!info->evaluated)
- GEN_NODE_TO_REG(info->expr, info->gpr, info->gprHi, &info->opnd);
- coerce_to_register_pair(&info->opnd, type, info->gpr, info->gprHi);
- if (copts.littleendian) {
- if (info->gprHi > 10) {
- load_store_register(
- PC_STW, info->opnd.regHi, 1,
- NULL, high_offset + out_param_displ_to_offset(info->offset));
- }
- } else {
- if (info->gpr > 10) {
- load_store_register(
- PC_STW, info->opnd.reg, 1,
- NULL, low_offset + out_param_displ_to_offset(info->offset));
- }
- }
- } else {
- if (!info->evaluated)
- GEN_NODE_TO_REG(info->expr, info->gpr, 0, &info->opnd);
- if (info->flags & AIF_ExtendTo32Bits)
- extend32(&info->opnd, type, info->gpr);
- ENSURE_GPR(&info->opnd, type, info->gpr);
- if (info->opnd.reg != info->gpr)
- emitpcode(PC_MR, info->gpr, info->opnd.reg);
- }
- } else if (IS_TYPE_FLOAT(type)) {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
-
- if (type->size != 4 && info->opnd.optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(
- PC_LWZ, info->gpr, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset);
- load_store_register(
- PC_LWZ, info->gpr + 1, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + 4);
- } else {
- ENSURE_FPR(&info->opnd, type, 0);
- load_store_register(
- PC_STFD, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- load_store_register(
- PC_LWZ, info->gpr, 1,
- NULL, out_param_displ_to_offset(info->offset));
- load_store_register(
- PC_LWZ, info->gpr + 1, 1,
- NULL, out_param_displ_to_offset(info->offset) + 4);
- }
- } else if (IS_TYPE_VECTOR(type)) {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
-
- if (info->opnd.optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(
- PC_LWZ, info->gpr, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset);
- load_store_register(
- PC_LWZ, info->gpr + 1, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + 4);
- if ((info->gpr + 2) < 10) {
- load_store_register(
- PC_LWZ, info->gpr + 2, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + 8);
- load_store_register(
- PC_LWZ, info->gpr + 3, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + 12);
- }
- } else {
- ENSURE_VR(&info->opnd, type, 0);
- load_store_register(
- PC_STVX, info->opnd.reg, 1,
- NULL, out_param_displ_to_offset(info->offset));
- load_store_register(
- PC_LWZ, info->gpr, 1,
- NULL, out_param_displ_to_offset(info->offset));
- load_store_register(
- PC_LWZ, info->gpr + 1, 1,
- NULL, out_param_displ_to_offset(info->offset) + 4);
- if ((info->gpr + 2) < 10) {
- load_store_register(
- PC_LWZ, info->gpr + 2, 1,
- NULL, out_param_displ_to_offset(info->offset) + 8);
- load_store_register(
- PC_LWZ, info->gpr + 3, 1,
- NULL, out_param_displ_to_offset(info->offset) + 12);
- }
- }
- } else {
- if (!info->evaluated)
- GEN_NODE(info->expr, &info->opnd);
-
- if (type->size <= 4) {
- if (info->opnd.optype == OpndType_IndirectSymbol)
- coerce_to_addressable(&info->opnd);
-
- if (info->opnd.optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(
- PC_LWZ, info->gpr, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset);
- } else if (info->opnd.optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(
- PC_LWZX, info->gpr, info->opnd.reg,
- info->opnd.regOffset);
- }
- } else {
- SInt32 gprs_needed = (type->size >> 2) + ((type->size & 3) != 0);
- SInt32 i;
-
- make_addressable(&info->opnd, gprs_needed * 4, 12);
- for (i = 0; i < gprs_needed; i++) {
- if (info->opnd.reg != (info->gpr + i)) {
- load_store_register(
- PC_LWZ, info->gpr + i, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + i * 4);
- }
- }
-
- if (info->opnd.reg >= info->gpr && info->opnd.reg < (info->gpr + gprs_needed)) {
- load_store_register(
- PC_LWZ, info->opnd.reg, info->opnd.reg,
- info->opnd.object, info->opnd.immOffset + (info->opnd.reg - info->gpr) * 4);
- }
- }
- }
-}
-
-static void pass_in_register_and_memory(ArgInfo *info) {
- Type *type;
- int gpr;
- SInt32 offset;
-
- type = info->expr->rtype;
- gpr = info->gpr;
- offset = 0;
- while (offset < type->size && gpr <= 10) {
- load_store_register(
- PC_LWZ, gpr, 1,
- NULL, offset + out_param_displ_to_offset(info->offset));
- gpr++;
- offset += 4;
- }
-}
-
-static Boolean needs_TOC_reload(Object *func) {
- return 0;
-}
-
-static void load_virtual_function(TypeClass *tclass, SInt32 offset, int reg, Operand *opnd) {
- if (tclass->flags & CLASS_HANDLEOBJECT) {
- load_store_register(PC_LWZ, 12, reg, NULL, 0);
- load_store_register(PC_LWZ, 12, 12, NULL, tclass->vtable->offset);
- } else {
- load_store_register(PC_LWZ, 12, reg, NULL, tclass->vtable->offset);
- }
- load_store_register(PC_LWZ, 12, 12, NULL, offset);
- opnd->optype = OpndType_GPR;
- opnd->reg = 12;
-}
-
-static void branch_subroutine_indirect(Object *func, Operand *addrOpnd, UInt32 *used_regs) {
- if (addrOpnd->reg != 12)
- emitpcode(PC_MR, 12, addrOpnd->reg);
-
- used_regs[RegClass_GPR] |= 1 << 12;
- branch_subroutine(func, 1, used_regs);
-}
-
-static void evaluate_nested_function_calls(ArgInfo *info) {
- ArgInfo *scan;
-
- scan = info->next;
- while (scan && !scan->expr->hascall)
- scan = scan->next;
-
- if (scan)
- evaluate_nested_function_calls(scan);
-
- if (info->expr->hascall) {
- GEN_NODE(info->expr, &info->opnd);
- info->evaluated = 1;
- }
-}
-
-void call_function(ENode *expr, Operand *output) {
- ArgInfo *infos; // r31
- ENode *funcref = expr->data.funccall.funcref; // r27
- Type *resultType = expr->data.funccall.functype->functype; // r26
- ENode *node = NULL; // r25
- char has_varargs; // r24
- ArgInfo *info; // r22
- Operand opnd;
- UInt32 used_regs[RegClassMax] = {0};
- Boolean has_floats;
- FuncArg *arg;
-
- memclrw(&opnd, sizeof(Operand));
-
- has_varargs = 0;
- for (arg = expr->data.funccall.functype->args; arg; arg = arg->next) {
- if (arg == &elipsis) {
- has_varargs = 1;
- break;
- }
- }
-
- if (expr->data.funccall.functype->flags & FUNC_FLAGS_80) {
- if (CMach_PassResultInHiddenArg(resultType))
- node = expr->data.funccall.args->next->node;
- else
- node = expr->data.funccall.args->node;
- }
-
- infos = analyze_arguments(
- node,
- expr->data.funccall.args,
- expr->data.funccall.functype->args,
- used_regs,
- &has_floats,
- has_varargs);
-
- if (infos)
- evaluate_nested_function_calls(infos);
-
- if (funcref->hascall) {
- GEN_NODE_TO_GPR(funcref, &opnd, TYPE(&void_ptr), 0);
- } else if (node && node->hascall) {
- GEN_NODE_TO_GPR(node, &opnd, TYPE(&void_ptr), 0);
- }
-
- for (info = infos; info; info = info->next) {
- if (info->flags & AIF_PassOnStack)
- pass_in_memory(info);
- }
- for (info = infos; info; info = info->next) {
- if ((info->flags & AIF_PassMask) == (AIF_PassInGPR | AIF_PassOnStack))
- pass_in_register_and_memory(info);
- }
- for (info = infos; info; info = info->next) {
- int flag = info->flags & AIF_PassMask;
- if (
- flag == AIF_PassInGPR ||
- flag == AIF_PassInFPR ||
- flag == AIF_PassInVR
- )
- pass_in_register(info);
- }
-
- if (funcref->type == EOBJREF) {
- TypeClass *tclass;
- SInt32 vfOffset;
- if (CParser_IsVirtualFunction(funcref->data.objref, &tclass, &vfOffset)) {
- load_virtual_function(
- tclass,
- vfOffset,
- CMach_PassResultInHiddenArg(resultType) ? Register4 : Register3,
- &opnd
- );
- branch_subroutine_indirect_ctr(&opnd, used_regs);
- } else if (node) {
- if (!node->hascall) {
- GEN_NODE_TO_REG(node, 12, 0, &opnd);
- ENSURE_GPR(&opnd, TYPE(&void_ptr), 12);
- }
- branch_subroutine_indirect(funcref->data.objref, &opnd, used_regs);
- } else {
- branch_subroutine(funcref->data.objref, needs_TOC_reload(funcref->data.objref), used_regs);
- }
- } else {
- if (!funcref->hascall)
- GEN_NODE_TO_REG(funcref, 12, 0, &opnd);
- ENSURE_GPR(&opnd, TYPE(&void_ptr), 12);
- branch_subroutine_indirect_ctr(&opnd, used_regs);
- }
-
- if (IS_TYPE_FLOAT(resultType)) {
- output->optype = OpndType_FPR;
- output->reg = used_virtual_registers[RegClass_FPR]++;
- emitpcode(PC_FMR, output->reg, 1);
- } else if (IS_TYPE_VECTOR(resultType)) {
- output->optype = OpndType_VR;
- output->reg = used_virtual_registers[RegClass_VR]++;
- emitpcode(PC_VMR, output->reg, 2);
- } else if (TYPE_FITS_IN_REGISTER(resultType)) {
- if (resultType->size > 4) {
- output->optype = OpndType_GPRPair;
- output->reg = used_virtual_registers[RegClass_GPR]++;
- output->regHi = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_MR, output->reg, low_reg);
- emitpcode(PC_MR, output->regHi, high_reg);
- } else {
- output->optype = OpndType_GPR;
- output->reg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_MR, output->reg, 3);
- }
- } else {
- output->optype = OpndType_Absolute;
- output->immediate = 0;
- }
-}
-
-static void branch_subroutine_indirect_ctr(Operand *addrOpnd, UInt32 *used_regs) {
- if (addrOpnd->reg != 12)
- emitpcode(PC_MR, 12, addrOpnd->reg);
-
- emitpcode(PC_MTCTR, 12);
- used_regs[RegClass_GPR] |= 1 << 12;
- branch_subroutine_ctr(used_regs);
-}
diff --git a/compiler_and_linker/unsorted/GCCInlineAsm.c b/compiler_and_linker/unsorted/GCCInlineAsm.c
deleted file mode 100644
index 897df9b..0000000
--- a/compiler_and_linker/unsorted/GCCInlineAsm.c
+++ /dev/null
@@ -1,230 +0,0 @@
-#include "compiler/GCCInlineAsm.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/objects.h"
-
-Statement *first_ST_ASM;
-IALookupResult gcc_name_list[20];
-int gcc_name_list_index;
-
-void InlineAsm_SkipComment(void) {
- while (1) {
- if (tk != '/')
- break;
- if (lookahead() != '*')
- break;
-
- tk = lex();
- while (!((tk = lex()) == '*' && (tk = lex()) == '/')) {
- // nothing
- }
- tk = lex();
- }
-}
-
-static char gcc_parse_attribute(void) {
- char ch;
-
- while (tk == TK_EOL)
- tk = lex();
-
- if (tk != '"')
- CError_Error(CErrorStr105);
-
- while ((tk = lex()) != TK_IDENTIFIER) {
- // nothing
- }
-
- ch = tkidentifier->name[0];
-
- if ((tk = lex()) != '"')
- CError_Error(CErrorStr105);
- tk = lex();
-
- return ch;
-}
-
-static void gcc_parse_name(Boolean flag, char attribute) {
- IALookupResult *nameentry;
- ENode *expr;
- Object *tempobj;
- ENode *tempexpr;
- Statement *stmt;
-
- while (tk == TK_EOL)
- tk = lex();
-
- if (tk != '(')
- CError_Error(CErrorStr114);
-
- tk = lex();
-
- if (flag) {
- if (tk != TK_IDENTIFIER)
- CError_Error(CErrorStr105);
-
- InlineAsm_LookupSymbol(tkidentifier, &gcc_name_list[++gcc_name_list_index]);
- if (gcc_name_list[gcc_name_list_index].object && gcc_name_list[gcc_name_list_index].object->u.var.info)
- gcc_name_list[gcc_name_list_index].object->u.var.info->used = 1;
-
- tk = lex();
- } else {
- in_assembler = 0;
- cprep_nostring = 0;
- nameentry = &gcc_name_list[++gcc_name_list_index];
-
- expr = expression();
- if (attribute == 'i' || attribute == 'I') {
- if (!ENODE_IS(expr, EINTCONST))
- CError_Error(CErrorStr144);
- nameentry->value = CInt64_GetULong(&expr->data.intval);
- nameentry->has_value = 1;
- } else {
- tempobj = create_temp_object(expr->rtype);
- tempexpr = create_objectnode(tempobj);
- if (tempobj->u.var.info)
- tempobj->u.var.info->used = 1;
- expr = makediadicnode(tempexpr, expr, EASS);
-
- stmt = CFunc_InsertBeforeStatement(ST_EXPRESSION, first_ST_ASM);
- first_ST_ASM = stmt->next;
- if (!first_ST_ASM->next)
- curstmt = first_ST_ASM;
- stmt->expr = expr;
-
- nameentry->name = tempobj->name;
- nameentry->object = tempobj;
- nameentry->label = NULL;
- nameentry->type = NULL;
- nameentry->has_value = 0;
- }
- }
-
- cprep_nostring = 1;
- in_assembler = 1;
-
- if (tk != ')')
- CError_Error(CErrorStr115);
- tk = lex();
-}
-
-static void gcc_parse_expression(Boolean flag) {
- while (1) {
- gcc_parse_name(flag, gcc_parse_attribute());
- if (tk != ',')
- break;
- tk = lex();
- }
-}
-
-static void gcc_parse_input(void) {
- if (tk == ':') {
- if ((tk = lex()) == ':' || tk == ')' || tk == '}')
- return;
- gcc_parse_expression(0);
- }
-}
-
-static void gcc_parse_output(void) {
- if (tk == ':') {
- if ((tk = lex()) == ':' || tk == ')' || tk == '}')
- return;
- gcc_parse_expression(1);
- }
-}
-
-static void gcc_parse_killed(void) {
- if (tk == ':') {
- while (1) {
- if ((tk = lex()) != '"')
- return;
-
- tk = lex();
- while (1) {
- if (tk == '"') {
- if (lookahead() == ',') {
- tk = lex();
- break;
- }
- tk = lex();
- return;
- }
- tk = lex();
- }
- }
- }
-}
-
-static void gcc_replace_arg_st_asm(Statement *stmt) {
- InlineAsm *ia;
- int i;
- IAOperand *op;
- short effect;
- short rclass;
- SInt32 num;
-
- if ((ia = (InlineAsm *) stmt->expr)) {
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_Imm:
- case IAOpnd_Reg:
- case IAOpnd_3:
- case IAOpnd_4:
- case IAOpnd_Lab:
- break;
-
- case IAOpnd_6:
- if (op->u.unk6.unk4 == 2) {
- effect = op->u.unk6.effect;
- rclass = op->u.unk6.rclass;
- num = op->u.unk6.num;
- op->type = IAOpnd_Reg;
- op->u.reg.effect = effect;
- op->u.reg.rclass = rclass;
- op->u.reg.object = NULL;
- if (num <= gcc_name_list_index)
- op->u.reg.object = gcc_name_list[num].object;
- else
- CError_Error(CErrorStr144);
- op->u.reg.num = 0;
- } else {
- CError_FATAL(365);
- }
- break;
-
- case IAOpnd_7:
- op->type = IAOpnd_Imm;
- op->u.imm.value = gcc_name_list[op->u.unk7.value].value;
- break;
- }
- }
- }
-}
-
-static void gcc_replace_arg(void) {
- Statement *stmt;
-
- for (stmt = first_ST_ASM; stmt; stmt = stmt->next) {
- if (stmt->type == ST_ASM)
- gcc_replace_arg_st_asm(stmt);
- }
-}
-
-void InlineAsm_gcc_parse(void) {
- gcc_name_list_index = -1;
- cprep_eoltokens = 0;
-
- if (tk == TK_EOL)
- tk = lex();
-
- gcc_parse_output();
- gcc_parse_input();
- gcc_parse_killed();
- gcc_replace_arg();
-}
diff --git a/compiler_and_linker/unsorted/IROUseDef.c b/compiler_and_linker/unsorted/IROUseDef.c
deleted file mode 100644
index 19d39ff..0000000
--- a/compiler_and_linker/unsorted/IROUseDef.c
+++ /dev/null
@@ -1,1432 +0,0 @@
-#include "compiler/IROUseDef.h"
-#include "compiler/IRODump.h"
-#include "compiler/IROVars.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroTransform.h"
-#include "compiler/IroUtil.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmPPC.h"
-
-ENodeType IRO_NonAssignmentOp[MAXEXPR];
-typedef CInt64 (*AssignmentFoldingFunc)(CInt64, CInt64);
-static AssignmentFoldingFunc AssignmentFoldingFunction[MAXEXPR];
-static SInt32 NumDefs;
-static IRODef *FirstDef;
-static IRODef *LastDef;
-static SInt32 NumUses;
-static BitVector *Reaches;
-static BitVector *MightReachAnyUse;
-static BitVector *alldefs;
-static BitVector *alluses;
-static BitVector *defset;
-static BitVector *useset;
-IROUse *IRO_FirstVarUse;
-IROUse *IRO_LastVarUse;
-
-// forward decls
-static void AddDefToRange(IRODef *def);
-
-static void MakeDef(VarRecord *var, IROLinear *linear, IRONode *node, Boolean flag) {
- IRODef *def = oalloc(sizeof(IRODef));
-
- def->index = NumDefs++;
- def->node = node;
- def->linear = linear;
- def->var = var;
- def->globalnext = NULL;
- def->x18 = 0;
- def->x1A = Inline_IsObjectData(var->object);
- def->x1B = var->xB;
- def->x1C = flag;
- def->x1D = 0;
-
- if (FirstDef)
- LastDef->globalnext = def;
- else
- FirstDef = def;
- LastDef = def;
-
- def->varnext = var->defs;
- var->defs = def;
-}
-
-static void MakeUse(VarRecord *var, IROLinear *linear, IRONode *node) {
- IROUse *use = oalloc(sizeof(IROUse));
-
- use->index = NumUses++;
- use->node = node;
- use->linear = linear;
- use->var = var;
- use->globalnext = NULL;
- use->x1C = 0;
-
- if (IRO_FirstVarUse)
- IRO_LastVarUse->globalnext = use;
- else
- IRO_FirstVarUse = use;
- IRO_LastVarUse = use;
-
- use->varnext = var->uses;
- var->uses = use;
-}
-
-static void FindDefsAndUses(void) {
- VarRecord *var;
- IROLinear *linear;
- IRONode *node;
-
- NumDefs = 0;
- NumUses = 0;
- IRO_FirstVarUse = NULL;
- FirstDef = NULL;
-
- for (var = IRO_FirstVar; var; var = var->next) {
- var->defs = NULL;
- var->uses = NULL;
- var->xC = 0;
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- for (linear = node->first; linear; linear = linear->next) {
- if (IS_LINEAR_ENODE(linear, EOBJREF)) {
- Object *obj = linear->u.node->data.objref;
- if ((linear->flags & IROLF_Ind) && (!(linear->flags & IROLF_Assigned) || (linear->flags & IROLF_Used))) {
- if ((var = IRO_FindVar(obj, 0, 1)))
- MakeUse(var, linear, node);
- }
- }
-
- if (IRO_IsAssignment(linear) && (var = IRO_FindAssigned(linear))) {
- MakeDef(
- var,
- linear,
- node,
- (linear->rtype->size == var->object->type->size) && !IRO_IsBitField
- );
- }
-
- if (linear->type == IROLinearAsm) {
- IAEffects effects;
- int i;
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
-
- for (i = 0; i < effects.numoperands; i++) {
- var = IRO_FindVar(effects.operands[i].object, 0, 1);
- switch (effects.operands[i].type) {
- case IAEffect_0:
- MakeUse(var, linear, node);
- break;
- case IAEffect_1:
- MakeDef(
- var,
- linear,
- node,
- (effects.operands[i].offset == 0) && (effects.operands[i].size == var->object->type->size)
- );
- break;
- case IAEffect_2:
- MakeDef(var, linear, node, 0);
- break;
- case IAEffect_4:
- MakeUse(var, linear, node);
- MakeDef(
- var,
- linear,
- node,
- (effects.operands[i].offset == 0) && (effects.operands[i].size == var->object->type->size)
- );
- break;
- }
- }
- }
-
- if (linear == node->last)
- break;
- }
- }
-
- for (var = IRO_FirstVar; var; var = var->next)
- MakeDef(var, NULL, NULL, 1);
-}
-
-static void MarkUses(Object *obj) {
- VarRecord *var;
- IRODef *def;
-
- if ((var = IRO_FindVar(obj, 0, 1))) {
- for (def = var->defs; def; def = def->varnext) {
- if (Bv_IsBitSet(def->index, Reaches)) {
- Bv_SetBit(def->index, MightReachAnyUse);
- def->x18++;
- }
- }
-
- var->xC = 1;
- }
-}
-
-static Boolean IsIncOrDec(IROLinear *linear) {
- switch (linear->type) {
- case IROLinearOp1Arg:
- if (linear->nodetype == EPOSTINC || linear->nodetype == EPOSTDEC || linear->nodetype == EPREINC || linear->nodetype == EPREDEC) {
- if (!(linear->u.monadic->flags & IROLF_BitfieldIndirect))
- return 1;
- }
- break;
- case IROLinearOp2Arg:
- if (linear->nodetype == EADDASS || linear->nodetype == ESUBASS) {
- if (IRO_IsIntConstant(linear->u.diadic.right) && !(linear->u.diadic.left->flags & IROLF_BitfieldIndirect))
- return 1;
- }
- break;
- }
-
- return 0;
-}
-
-static Boolean IsOtherSelfAssignment(IROLinear *linear) {
- switch (linear->type) {
- case IROLinearOp2Arg:
- switch (linear->nodetype) {
- case EMULASS:
- case EDIVASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- if (IRO_IsIntConstant(linear->u.diadic.right))
- return 1;
- break;
- }
- break;
- }
-
- return 0;
-}
-
-CInt64 IRO_GetSelfAssignmentVal(IROLinear *linear) {
- CInt64 result;
-
- if (linear->type == IROLinearOp1Arg) {
- switch (linear->nodetype) {
- case EPOSTINC:
- case EPREINC:
- CInt64_SetLong(&result, 1);
- break;
- case EPOSTDEC:
- case EPREDEC:
- CInt64_SetLong(&result, -1);
- break;
- default:
- CError_FATAL(445);
- }
-
- if (IS_TYPE_POINTER_ONLY(linear->rtype)) {
- CInt64 mul;
- CInt64_SetLong(&mul, TPTR_TARGET(linear->rtype)->size);
- result = CInt64_Mul(result, mul);
- }
- } else if (linear->type == IROLinearOp2Arg) {
- switch (linear->nodetype) {
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- result = linear->u.diadic.right->u.node->data.intval;
- break;
- case ESUBASS:
- result = linear->u.diadic.right->u.node->data.intval;
- result = CInt64_Neg(result);
- break;
- default:
- CError_FATAL(491);
- }
- } else {
- CError_FATAL(496);
- }
-
- return result;
-}
-
-static void UpdateUse(IROLinear *linear, CInt64 val, Type *type) {
- IROLinear *father;
- IROLinear *repl;
- IROLinear *newdiadic;
-
- if ((father = IRO_LocateFather(linear))) {
- switch (father->type) {
- case IROLinearOp1Arg:
- switch (father->nodetype) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- val = CInt64_Add(val, IRO_GetSelfAssignmentVal(father));
- father->nodetype = EADDASS;
- father->type = IROLinearOp2Arg;
- repl = IRO_NewIntConst(val, type);
- father->u.diadic.right = repl;
- IRO_PasteAfter(repl, repl, linear);
- return;
- }
- break;
- case IROLinearOp2Arg:
- if (IRO_IsIntConstant(father->u.diadic.right)) {
- switch (father->nodetype) {
- case EADD:
- case EADDASS:
- father->u.diadic.right->u.node->data.intval = CInt64_Add(
- father->u.diadic.right->u.node->data.intval, val);
- return;
- case ESUB:
- case ESUBASS:
- father->u.diadic.right->u.node->data.intval = CInt64_Sub(
- father->u.diadic.right->u.node->data.intval, val);
- return;
- }
- }
- break;
- }
- }
-
- repl = IRO_NewIntConst(val, type);
- newdiadic = IRO_NewLinear(IROLinearOp2Arg);
- newdiadic->index = ++IRO_NumLinear;
- newdiadic->nodetype = EADD;
- newdiadic->u.diadic.left = linear;
- newdiadic->u.diadic.right = repl;
- newdiadic->rtype = linear->rtype;
- repl->next = newdiadic;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(linear, newdiadic);
- IRO_PasteAfter(repl, newdiadic, linear);
-}
-
-void IRO_InitializeNonAssignmentOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- IRO_NonAssignmentOp[i] = MAXEXPR;
-
- IRO_NonAssignmentOp[EPOSTINC] = MAXEXPR;
- IRO_NonAssignmentOp[EPOSTDEC] = MAXEXPR;
- IRO_NonAssignmentOp[EPREINC] = MAXEXPR;
- IRO_NonAssignmentOp[EPREDEC] = MAXEXPR;
- IRO_NonAssignmentOp[EINDIRECT] = MAXEXPR;
- IRO_NonAssignmentOp[EMONMIN] = MAXEXPR;
- IRO_NonAssignmentOp[EBINNOT] = MAXEXPR;
- IRO_NonAssignmentOp[ELOGNOT] = MAXEXPR;
- IRO_NonAssignmentOp[EFORCELOAD] = MAXEXPR;
- IRO_NonAssignmentOp[EMUL] = MAXEXPR;
- IRO_NonAssignmentOp[EMULV] = MAXEXPR;
- IRO_NonAssignmentOp[EDIV] = MAXEXPR;
- IRO_NonAssignmentOp[EMODULO] = MAXEXPR;
- IRO_NonAssignmentOp[EADDV] = MAXEXPR;
- IRO_NonAssignmentOp[ESUBV] = MAXEXPR;
- IRO_NonAssignmentOp[EADD] = MAXEXPR;
- IRO_NonAssignmentOp[ESUB] = MAXEXPR;
- IRO_NonAssignmentOp[ESHL] = MAXEXPR;
- IRO_NonAssignmentOp[ESHR] = MAXEXPR;
- IRO_NonAssignmentOp[ELESS] = MAXEXPR;
- IRO_NonAssignmentOp[EGREATER] = MAXEXPR;
- IRO_NonAssignmentOp[ELESSEQU] = MAXEXPR;
- IRO_NonAssignmentOp[EGREATEREQU] = MAXEXPR;
- IRO_NonAssignmentOp[EEQU] = MAXEXPR;
- IRO_NonAssignmentOp[ENOTEQU] = MAXEXPR;
- IRO_NonAssignmentOp[EAND] = MAXEXPR;
- IRO_NonAssignmentOp[EXOR] = MAXEXPR;
- IRO_NonAssignmentOp[EOR] = MAXEXPR;
- IRO_NonAssignmentOp[ELAND] = MAXEXPR;
- IRO_NonAssignmentOp[ELOR] = MAXEXPR;
- IRO_NonAssignmentOp[EASS] = MAXEXPR;
- IRO_NonAssignmentOp[EMULASS] = EMUL;
- IRO_NonAssignmentOp[EDIVASS] = EDIV;
- IRO_NonAssignmentOp[EMODASS] = EMODULO;
- IRO_NonAssignmentOp[EADDASS] = EADD;
- IRO_NonAssignmentOp[ESUBASS] = ESUB;
- IRO_NonAssignmentOp[ESHLASS] = ESHL;
- IRO_NonAssignmentOp[ESHRASS] = ESHR;
- IRO_NonAssignmentOp[EANDASS] = EAND;
- IRO_NonAssignmentOp[EXORASS] = EXOR;
- IRO_NonAssignmentOp[EORASS] = EOR;
- IRO_NonAssignmentOp[ECOMMA] = MAXEXPR;
- IRO_NonAssignmentOp[EPMODULO] = MAXEXPR;
- IRO_NonAssignmentOp[EROTL] = MAXEXPR;
- IRO_NonAssignmentOp[EROTR] = MAXEXPR;
- IRO_NonAssignmentOp[EBCLR] = MAXEXPR;
- IRO_NonAssignmentOp[EBTST] = MAXEXPR;
- IRO_NonAssignmentOp[EBSET] = MAXEXPR;
- IRO_NonAssignmentOp[ETYPCON] = MAXEXPR;
- IRO_NonAssignmentOp[EBITFIELD] = MAXEXPR;
- IRO_NonAssignmentOp[EINTCONST] = MAXEXPR;
- IRO_NonAssignmentOp[EFLOATCONST] = MAXEXPR;
- IRO_NonAssignmentOp[ESTRINGCONST] = MAXEXPR;
- IRO_NonAssignmentOp[ECOND] = MAXEXPR;
- IRO_NonAssignmentOp[EFUNCCALL] = MAXEXPR;
- IRO_NonAssignmentOp[EFUNCCALLP] = MAXEXPR;
- IRO_NonAssignmentOp[EOBJREF] = MAXEXPR;
- IRO_NonAssignmentOp[EMFPOINTER] = MAXEXPR;
- IRO_NonAssignmentOp[ENULLCHECK] = MAXEXPR;
- IRO_NonAssignmentOp[EPRECOMP] = MAXEXPR;
- IRO_NonAssignmentOp[ETEMP] = MAXEXPR;
- IRO_NonAssignmentOp[EARGOBJ] = MAXEXPR;
- IRO_NonAssignmentOp[ELOCOBJ] = MAXEXPR;
- IRO_NonAssignmentOp[ELABEL] = MAXEXPR;
- IRO_NonAssignmentOp[ESETCONST] = MAXEXPR;
- IRO_NonAssignmentOp[ENEWEXCEPTION] = MAXEXPR;
- IRO_NonAssignmentOp[ENEWEXCEPTIONARRAY] = MAXEXPR;
- IRO_NonAssignmentOp[EOBJLIST] = MAXEXPR;
- IRO_NonAssignmentOp[EMEMBER] = MAXEXPR;
- IRO_NonAssignmentOp[ETEMPLDEP] = MAXEXPR;
- IRO_NonAssignmentOp[EINSTRUCTION] = MAXEXPR;
- IRO_NonAssignmentOp[EDEFINE] = MAXEXPR;
- IRO_NonAssignmentOp[EREUSE] = MAXEXPR;
- IRO_NonAssignmentOp[EASSBLK] = MAXEXPR;
- IRO_NonAssignmentOp[EVECTOR128CONST] = MAXEXPR;
- IRO_NonAssignmentOp[ECONDASS] = MAXEXPR;
-}
-
-void IRO_InitializeAssignmentFoldingFunctionArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- AssignmentFoldingFunction[i] = NULL;
-
- AssignmentFoldingFunction[EPOSTINC] = NULL;
- AssignmentFoldingFunction[EPOSTDEC] = NULL;
- AssignmentFoldingFunction[EPREINC] = NULL;
- AssignmentFoldingFunction[EPREDEC] = NULL;
- AssignmentFoldingFunction[EINDIRECT] = NULL;
- AssignmentFoldingFunction[EMONMIN] = NULL;
- AssignmentFoldingFunction[EBINNOT] = NULL;
- AssignmentFoldingFunction[ELOGNOT] = NULL;
- AssignmentFoldingFunction[EFORCELOAD] = NULL;
- AssignmentFoldingFunction[EMUL] = NULL;
- AssignmentFoldingFunction[EMULV] = NULL;
- AssignmentFoldingFunction[EDIV] = NULL;
- AssignmentFoldingFunction[EMODULO] = NULL;
- AssignmentFoldingFunction[EADDV] = NULL;
- AssignmentFoldingFunction[ESUBV] = NULL;
- AssignmentFoldingFunction[EADD] = NULL;
- AssignmentFoldingFunction[ESUB] = NULL;
- AssignmentFoldingFunction[ESHL] = NULL;
- AssignmentFoldingFunction[ESHR] = NULL;
- AssignmentFoldingFunction[ELESS] = NULL;
- AssignmentFoldingFunction[EGREATER] = NULL;
- AssignmentFoldingFunction[ELESSEQU] = NULL;
- AssignmentFoldingFunction[EGREATEREQU] = NULL;
- AssignmentFoldingFunction[EEQU] = NULL;
- AssignmentFoldingFunction[ENOTEQU] = NULL;
- AssignmentFoldingFunction[EAND] = NULL;
- AssignmentFoldingFunction[EXOR] = NULL;
- AssignmentFoldingFunction[EOR] = NULL;
- AssignmentFoldingFunction[ELAND] = NULL;
- AssignmentFoldingFunction[ELOR] = NULL;
- AssignmentFoldingFunction[EASS] = NULL;
- AssignmentFoldingFunction[EMULASS] = CInt64_Mul;
- AssignmentFoldingFunction[EDIVASS] = CInt64_Mul;
- AssignmentFoldingFunction[EMODASS] = NULL;
- AssignmentFoldingFunction[EADDASS] = CInt64_Add;
- AssignmentFoldingFunction[ESUBASS] = CInt64_Add;
- AssignmentFoldingFunction[ESHLASS] = CInt64_Add;
- AssignmentFoldingFunction[ESHRASS] = CInt64_Add;
- AssignmentFoldingFunction[EANDASS] = CInt64_And;
- AssignmentFoldingFunction[EXORASS] = CInt64_Xor;
- AssignmentFoldingFunction[EORASS] = CInt64_Or;
- AssignmentFoldingFunction[ECOMMA] = NULL;
- AssignmentFoldingFunction[EPMODULO] = NULL;
- AssignmentFoldingFunction[EROTL] = NULL;
- AssignmentFoldingFunction[EROTR] = NULL;
- AssignmentFoldingFunction[EBCLR] = NULL;
- AssignmentFoldingFunction[EBTST] = NULL;
- AssignmentFoldingFunction[EBSET] = NULL;
- AssignmentFoldingFunction[ETYPCON] = NULL;
- AssignmentFoldingFunction[EBITFIELD] = NULL;
- AssignmentFoldingFunction[EINTCONST] = NULL;
- AssignmentFoldingFunction[EFLOATCONST] = NULL;
- AssignmentFoldingFunction[ESTRINGCONST] = NULL;
- AssignmentFoldingFunction[ECOND] = NULL;
- AssignmentFoldingFunction[EFUNCCALL] = NULL;
- AssignmentFoldingFunction[EFUNCCALLP] = NULL;
- AssignmentFoldingFunction[EOBJREF] = NULL;
- AssignmentFoldingFunction[EMFPOINTER] = NULL;
- AssignmentFoldingFunction[ENULLCHECK] = NULL;
- AssignmentFoldingFunction[EPRECOMP] = NULL;
- AssignmentFoldingFunction[ETEMP] = NULL;
- AssignmentFoldingFunction[EARGOBJ] = NULL;
- AssignmentFoldingFunction[ELOCOBJ] = NULL;
- AssignmentFoldingFunction[ELABEL] = NULL;
- AssignmentFoldingFunction[ESETCONST] = NULL;
- AssignmentFoldingFunction[ENEWEXCEPTION] = NULL;
- AssignmentFoldingFunction[ENEWEXCEPTIONARRAY] = NULL;
- AssignmentFoldingFunction[EOBJLIST] = NULL;
- AssignmentFoldingFunction[EMEMBER] = NULL;
- AssignmentFoldingFunction[ETEMPLDEP] = NULL;
- AssignmentFoldingFunction[EINSTRUCTION] = NULL;
- AssignmentFoldingFunction[EDEFINE] = NULL;
- AssignmentFoldingFunction[EREUSE] = NULL;
- AssignmentFoldingFunction[EASSBLK] = NULL;
- AssignmentFoldingFunction[EVECTOR128CONST] = NULL;
- AssignmentFoldingFunction[ECONDASS] = NULL;
-}
-
-static void UpdateUseForOtherSelfAssignment(IROLinear *a, IROLinear *b, Type *type) {
- CInt64 val;
- IROLinear *father;
- IROLinear *repl;
- IROLinear *newdiadic;
-
- val = IRO_GetSelfAssignmentVal(b);
- if ((father = IRO_LocateFather(a)) && father->type == IROLinearOp2Arg && IRO_IsIntConstant(father->u.diadic.right)) {
- CInt64 var_30 = father->u.diadic.right->u.node->data.intval;
- if (AssignmentFoldingFunction[b->nodetype] && ((father->nodetype == b->nodetype) || (father->nodetype == IRO_NonAssignmentOp[b->nodetype]))) {
- CInt64 v;
- CInt64 folded;
- CInt64_SetLong(&v, b->rtype->size * 8);
- folded = AssignmentFoldingFunction[b->nodetype](var_30, val);
- if (b->nodetype == ESHRASS && !is_unsigned(b->rtype)) {
- if (CInt64_LessU(var_30, v) && CInt64_LessU(val, v)) {
- if (CInt64_GreaterEqualU(folded, v))
- folded = CInt64_Sub(v, cint64_one);
- father->u.diadic.right->u.node->data.intval = folded;
- return;
- }
- } else {
- father->u.diadic.right->u.node->data.intval = folded;
- return;
- }
- } else {
- switch (b->nodetype) {
- case EMULASS:
- if (father->nodetype == ESHL || father->nodetype == ESHLASS) {
- SInt32 powvalue;
- if (IRO_IsPow2(b->u.diadic.right, &powvalue)) {
- if (powvalue > 0) {
- CInt64 v;
- CInt64_SetLong(&v, powvalue);
- father->u.diadic.right->u.node->data.intval = CInt64_Add(v, var_30);
- }
- } else {
- father->nodetype = (father->nodetype == ESHL) ? EMUL : EMULASS;
- var_30 = CInt64_Shl(cint64_one, var_30);
- father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val);
- }
- return;
- }
- break;
- case EDIVASS:
- if ((father->nodetype == ESHR || father->nodetype == ESHRASS) && is_unsigned(father->rtype)) {
- SInt32 powvalue;
- if (IRO_IsPow2(b->u.diadic.right, &powvalue)) {
- if (powvalue > 0) {
- CInt64 v;
- CInt64_SetLong(&v, powvalue);
- father->u.diadic.right->u.node->data.intval = CInt64_Add(v, var_30);
- }
- } else {
- father->nodetype = (father->nodetype == ESHR) ? EDIV : EDIVASS;
- var_30 = CInt64_Shl(cint64_one, var_30);
- father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val);
- }
- return;
- }
- break;
- case ESHLASS:
- if (father->nodetype == EMUL || father->nodetype == EMULASS) {
- SInt32 powvalue;
- if (IRO_IsPow2(father->u.diadic.right, &powvalue)) {
- if (powvalue > 0) {
- CInt64 v;
- father->nodetype = (father->nodetype == EMUL) ? ESHL : ESHLASS;
- CInt64_SetLong(&v, powvalue);
- father->u.diadic.right->u.node->data.intval = CInt64_Add(v, val);
- }
- } else {
- val = CInt64_Shl(cint64_one, val);
- father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val);
- }
- return;
- } else if (father->nodetype == ESHR || father->nodetype == ESHRASS) {
- if (CInt64_Equal(var_30, val) && is_unsigned(father->rtype)) {
- father->nodetype = (father->nodetype == ESHR) ? EAND : EANDASS;
- if (father->rtype->size < 8) {
- CInt64 v;
- CInt64_SetLong(&v, 64 - (father->rtype->size * 8));
- val = CInt64_Add(val, v);
- }
- father->u.diadic.right->u.node->data.intval = CInt64_ShrU(cint64_negone, val);
- return;
- }
- }
- break;
- case ESHRASS:
- if ((father->nodetype == EDIV || father->nodetype == EDIVASS) && is_unsigned(father->rtype)) {
- SInt32 powvalue;
- if (IRO_IsPow2(father->u.diadic.right, &powvalue)) {
- if (powvalue > 0) {
- CInt64 v;
- father->nodetype = (father->nodetype == EDIV) ? ESHR : ESHRASS;
- CInt64_SetLong(&v, powvalue);
- father->u.diadic.right->u.node->data.intval = CInt64_Add(v, val);
- }
- } else {
- val = CInt64_Shl(cint64_one, val);
- father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val);
- }
- return;
- } else if (father->nodetype == ESHL || father->nodetype == ESHLASS) {
- if (CInt64_Equal(var_30, val)) {
- father->nodetype = (father->nodetype == ESHL) ? EAND : EANDASS;
- father->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_negone, val);
- return;
- }
- }
- break;
- }
- }
- }
-
- repl = IRO_NewIntConst(val, type);
- newdiadic = IRO_NewLinear(IROLinearOp2Arg);
- newdiadic->index = ++IRO_NumLinear;
- newdiadic->nodetype = IRO_NonAssignmentOp[b->nodetype];
- newdiadic->u.diadic.left = a;
- newdiadic->u.diadic.right = repl;
- newdiadic->rtype = a->rtype;
- repl->next = newdiadic;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(a, newdiadic);
- IRO_PasteAfter(repl, newdiadic, a);
-}
-
-static Boolean PropagateIncsAndDecs(void) {
- IRODef *def;
- Boolean result;
-
- result = 0;
- def = FirstDef;
- while (def) {
- if (
- def->linear &&
- def->x1C &&
- IsIncOrDec(def->linear) &&
- !(def->linear->flags & IROLF_Reffed) &&
- (IS_TYPE_INT_OR_ENUM(def->linear->rtype) || IS_TYPE_POINTER_ONLY(def->linear->rtype)) &&
- IRO_TypesEqual(def->linear->rtype, def->var->object->type) &&
- !is_volatile_object(def->var->object)
- ) {
- IROUse *use;
- IROUse *use2;
- IROLinear *father;
- CInt64 val;
- SInt32 i;
- Type *type;
-
- for (use = def->var->uses, i = 0; use; use = use->varnext) {
- if (Bv_IsBitSet(def->index, use->x18)) {
- if (
- use->x1C == 1 &&
- use->linear->type == IROLinearOperand &&
- (father = IRO_LocateFather(use->linear)) &&
- IRO_IsVariable(father) &&
- IRO_TypesEqual(def->linear->rtype, father->rtype)
- ) {
- if (use->linear->flags & IROLF_Assigned) {
- if (!((father = IRO_LocateFather(father)) && IsIncOrDec(father) && !(father->flags & IROLF_Reffed)))
- goto nextDef;
- }
- i++;
- } else {
- goto nextDef;
- }
- }
- }
-
- if (i == def->x18) {
- for (use = def->var->uses; use; use = use->varnext) {
- if (Bv_IsBitSet(def->index, use->x18)) {
- IRO_Dump("Propagating inc/dec from %d to %d\n", def->linear->index, use->linear->index);
- father = IRO_LocateFather(use->linear);
- val = IRO_GetSelfAssignmentVal(def->linear);
- type = def->linear->rtype;
- if (IS_TYPE_POINTER_ONLY(def->linear->rtype))
- type = TYPE(&stunsignedlong);
- UpdateUse(father, val, type);
-
- result = 1;
- for (use2 = def->var->uses; use2; use2 = use2->varnext) {
- if (use2->linear == def->linear->u.monadic->u.diadic.left) {
- use->x1C = use2->x1C;
- Bv_Copy(use2->x18, use->x18);
- break;
- }
- }
- }
- }
- def->x18 = 0;
- IRO_NopNonSideEffects(def->linear, -1);
- def->linear->type = IROLinearNop;
- IRO_Dump("Removing deadddd assignment %d\n", def->linear->index);
- }
- }
- nextDef:
- def = def->globalnext;
- }
-
- return result;
-}
-
-static Boolean PropagateOtherSelfAssignments(void) {
- IRODef *def;
- Boolean result;
-
- result = 0;
-
- def = FirstDef;
- while (def) {
- if (
- def->linear &&
- def->x1C &&
- IsOtherSelfAssignment(def->linear) &&
- !(def->linear->flags & IROLF_Reffed) &&
- IS_TYPE_INT_OR_ENUM(def->linear->rtype) &&
- IRO_TypesEqual(def->linear->rtype, def->var->object->type) &&
- !is_volatile_object(def->var->object)
- )
- {
- IROUse *use;
- IROUse *use2;
- IROLinear *father;
- SInt32 i;
- Type *type;
-
- for (use = def->var->uses, i = 0; use; use = use->varnext) {
- if (Bv_IsBitSet(def->index, use->x18)) {
- if (
- use->x1C == 1 &&
- use->linear->type == IROLinearOperand &&
- (father = IRO_LocateFather(use->linear)) &&
- IRO_IsVariable(father) &&
- IRO_TypesEqual(def->linear->rtype, father->rtype)
- ) {
- if (use->linear->flags & IROLF_Assigned) {
- if (!((father = IRO_LocateFather(father)) && IsOtherSelfAssignment(father) && (father->nodetype == def->linear->nodetype) && !(father->flags & IROLF_Reffed)))
- goto nextDef;
- }
- i++;
- } else {
- goto nextDef;
- }
- }
- }
-
- if (i == def->x18) {
- for (use = def->var->uses; use; use = use->varnext) {
- if (Bv_IsBitSet(def->index, use->x18)) {
- IRO_Dump("Propagating self assignment from %d to %d\n", def->linear->index, use->linear->index);
- father = IRO_LocateFather(use->linear);
- UpdateUseForOtherSelfAssignment(father, def->linear, def->linear->rtype);
-
- result = 1;
- for (use2 = def->var->uses; use2; use2 = use2->varnext) {
- if (use2->linear == def->linear->u.monadic->u.diadic.left) {
- use->x1C = use2->x1C;
- Bv_Copy(use2->x18, use->x18);
- break;
- }
- }
- }
- }
- def->x18 = 0;
- IRO_NopNonSideEffects(def->linear, -1);
- def->linear->type = IROLinearNop;
- IRO_Dump("Removing deadddd assignment %d\n", def->linear->index);
- }
- }
- nextDef:
- def = def->globalnext;
- }
-
- return result;
-}
-
-static void MarkUsesByIndirect(IROLinear *linear, BitVector *a, BitVector *b) {
- IROListNode *list;
- IROLinear *nd;
- Object *obj;
- VarRecord *var;
- Boolean foundObjRef;
- IROListNode *scan;
- IRODef *def;
- Boolean found;
-
- found = 0;
-
- if (linear && copts.opt_pointer_analysis && linear->pointsToFunction && FunctionName) {
- IROListNode *resultList;
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, linear, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- found = 1;
- break;
- }
-
- foundObjRef = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- break;
- }
- }
-
- if (!foundObjRef) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- while (list) {
- for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- obj = nd->u.node->data.objref;
- CError_ASSERT(1422, obj != NULL);
- var = IRO_FindVar(obj, 1, 1);
- CError_ASSERT(1424, var != NULL);
-
- for (def = var->defs; def; def = def->varnext) {
- if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
- def->x18++;
- Bv_SetBit(def->index, MightReachAnyUse);
- }
- }
- }
- }
- list = list->nextList;
- }
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- found = 1;
- }
- } else {
- found = 1;
- }
-
- if (found) {
- Bv_Copy(Reaches, a);
- Bv_And(b, a);
- Bv_Or(a, MightReachAnyUse);
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches)))
- def->x18++;
- }
- }
-}
-
-static void MarkUsesByFunctionCall(IROLinear *linear, BitVector *a, BitVector *b) {
- ObjectList *olist;
- IROLinear *funcnd;
- IROListNode *list;
- IROLinear *nd;
- Object *obj;
- VarRecord *var;
- Boolean foundObjRef;
- IROListNode *scan;
- IRODef *def;
- Boolean found;
-
- found = 0;
-
- if ((funcnd = linear->u.funccall.linear8) && copts.opt_pointer_analysis && funcnd->pointsToFunction && FunctionName) {
- IROListNode *resultList;
- ObjectList *depsList;
-
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, funcnd, &resultList);
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- found = 1;
- break;
- }
-
- foundObjRef = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = nd->u.node->data.objref;
- CError_ASSERT(1522, obj != NULL);
-
- depsList = NULL;
- PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList);
- for (olist = depsList; olist; olist = olist->next) {
- if (!olist->object) {
- found = 1;
- break;
- }
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
-
- if (found)
- break;
- }
- }
-
- if (!foundObjRef)
- found = 1;
- if (found)
- break;
- }
-
- if (!found) {
- for (list = resultList; list; list = list->nextList) {
- for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- obj = nd->u.node->data.objref;
- depsList = NULL;
- PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList);
-
- for (olist = depsList; olist; olist = olist->next) {
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(1573, var != NULL);
-
- for (def = var->defs; def; def = def->varnext) {
- if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
- def->x18++;
- Bv_SetBit(def->index, MightReachAnyUse);
- }
- }
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
- }
- }
- }
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- found = 1;
- }
- } else {
- found = 1;
- }
-
- if (found) {
- Bv_Copy(Reaches, a);
- Bv_And(b, a);
- Bv_Or(a, MightReachAnyUse);
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches)))
- def->x18++;
- }
- }
-
- if (linear->stmt && IRO_FunctionCallMightThrowException(linear))
- IRO_WalkExcActions(linear->stmt->dobjstack, MarkUses);
-}
-
-static Boolean UseOfVarIsInsideASimpleDefOfVar(IROUse *use) {
- VarRecord *var;
- VarRecord *varAss;
- IROLinear *nd;
- IROLinear *nd2;
-
- if ((var = use->var)) {
- if ((nd = use->linear) && (nd->flags & IROLF_4000))
- return 0;
-
- while (nd && (nd->flags & IROLF_Reffed))
- nd = nd->next;
-
- if (
- nd &&
- IRO_IsAssignment(nd) &&
- (varAss = IRO_FindAssigned(nd)) &&
- varAss == var &&
- !IRO_HasSideEffect((nd->type == IROLinearOp1Arg) ? nd->u.monadic : nd->u.diadic.left) &&
- (!(nd2 = (nd->type == IROLinearOp1Arg) ? NULL : nd->u.diadic.right) || !IRO_HasSideEffect(nd2))
- ) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static Boolean AllLoopDefUsesAreInSimpleLoopDefs(IRODef *def) {
- VarRecord *var;
- IRODef *scan;
- IROUse *use;
-
- if ((var = def->var)) {
- for (scan = var->defs; scan; scan = scan->varnext) {
- if (scan->node && scan->node->loopdepth) {
- for (use = var->uses; use; use = use->varnext) {
- if (Bv_IsBitSet(scan->index, use->x18)) {
- if (!use->node || !use->node->loopdepth || !UseOfVarIsInsideASimpleDefOfVar(use))
- return 0;
- }
- }
- }
- }
- return 1;
- } else {
- return 0;
- }
-}
-
-static void MarkRemovableLoopDefs(void) {
- IRODef *def;
- IRODef *scan;
-
- for (def = FirstDef; def; def = def->globalnext) {
- if (!def->x1A && !def->x1B && def->node && def->node->loopdepth && !def->x1D &&
- AllLoopDefUsesAreInSimpleLoopDefs(def) && def->var) {
- for (scan = def->var->defs; scan; scan = scan->varnext) {
- if (scan->node && scan->node->loopdepth)
- scan->x1D = 1;
- }
- }
- }
-}
-
-static Boolean EliminateReffedDeadStore(IRODef *def) {
- Boolean isPostIncOrDec;
- IROLinear *nd;
- Boolean result;
-
- nd = def->linear;
- isPostIncOrDec = (nd->type == IROLinearOp1Arg) && (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC);
-
- result = IRO_LocateFather(nd) != NULL;
- if (result && IRO_IsAssignment(nd) && IRO_IsModifyOp[nd->nodetype])
- result = IRO_TransformSelfAssignmentToAssignment(nd);
- result = result && (nd->type == IROLinearOp2Arg) && (nd->nodetype == EASS);
-
- if (result) {
- def->x18 = 0;
- IRO_Dump("Removing referenced dead assignment %d\n", nd->index);
-
- if (isPostIncOrDec) {
- IRO_NopNonSideEffects(nd->u.diadic.right, 0);
- nd->type = IROLinearNop;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, nd->u.diadic.left);
- } else {
- IRO_NopNonSideEffects(nd->u.diadic.left, 0);
- nd->type = IROLinearNop;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, nd->u.diadic.right);
- }
- }
-
- return result;
-}
-
-Boolean IRO_UseDef(Boolean optDeadAssignments, Boolean optPropagation) {
- Boolean result;
- IRODef *gdef;
- IROUse *guse;
- IRODef *def;
- IROUse *use;
- IRONode *node;
- IROLinear *nd;
- VarRecord *var;
- Boolean flag;
- BitVector *bv3;
- BitVector *bv2;
- BitVector *bv;
- int i;
-
- FindDefsAndUses();
-
- IRO_CheckForUserBreak();
-
- for (use = IRO_FirstVarUse; use; use = use->globalnext)
- Bv_AllocVector(&use->x18, NumDefs);
- Bv_AllocVector(&MightReachAnyUse, NumDefs);
- Bv_AllocVector(&bv, NumDefs);
-
- IRO_CheckForUserBreak();
-
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->x1A || def->x1B)
- Bv_SetBit(def->index, bv);
- }
-
- Bv_AllocVector(&bv2, NumDefs);
- gdef = FirstDef;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- Bv_AllocVector(&node->x16, NumDefs);
- Bv_AllocVector(&node->x1E, NumDefs);
- Bv_AllocVector(&node->x22, NumDefs);
- Bv_AllocVector(&node->x1A, NumDefs);
-
- for (nd = node->first; nd; nd = nd->next) {
- while (gdef && gdef->linear == nd) {
- Bv_SetBit(gdef->index, node->x1E);
- if (gdef->x1C) {
- for (def = gdef->var->defs; def; def = def->varnext) {
- if (def != gdef) {
- Bv_SetBit(def->index, node->x22);
- Bv_ClearBit(def->index, node->x1E);
- }
- }
- }
- gdef = gdef->globalnext;
- }
- if (nd == node->last)
- break;
- }
-
- if (node->numpred)
- Bv_Set(node->x16);
- Bv_Copy(node->x1E, node->x1A);
- IRO_CheckForUserBreak();
- }
-
- Bv_AllocVector(&bv3, NumDefs);
-
- do {
- flag = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- Bv_Clear(node->x16);
- if (node->numpred) {
- for (i = 0; i < node->numpred; i++)
- Bv_Or(IRO_NodeTable[node->pred[i]]->x1A, node->x16);
- } else if (node == IRO_FirstNode) {
- for (var = IRO_FirstVar; var; var = var->next)
- Bv_SetBit(var->defs->index, node->x16);
- }
- Bv_Copy(node->x16, bv3);
- Bv_Minus(node->x22, bv3);
- Bv_Or(node->x1E, bv3);
- if (!Bv_Compare(bv3, node->x1A)) {
- Bv_Copy(bv3, node->x1A);
- flag = 1;
- }
- }
-
- IRO_CheckForUserBreak();
- } while (flag);
-
- gdef = FirstDef;
- guse = IRO_FirstVarUse;
- Bv_AllocVector(&Reaches, NumDefs);
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- Bv_Copy(node->x16, Reaches);
- nd = node->first;
- while (1) {
- while (guse && guse->linear == nd) {
- for (def = guse->var->defs; def; def = def->varnext) {
- if (Bv_IsBitSet(def->index, Reaches)) {
- Bv_SetBit(def->index, guse->x18);
- Bv_SetBit(def->index, MightReachAnyUse);
- def->x18++;
- guse->x1C++;
- }
- }
- guse = guse->globalnext;
- }
-
- if (nd->type == IROLinearFunccall) {
- MarkUsesByFunctionCall(nd, bv2, bv);
- } else if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT && !IRO_IsVariable(nd)) {
- MarkUsesByIndirect(nd, bv2, bv);
- } else if ((nd->type == IROLinearFunccall) ||
- (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT && !IRO_IsVariable(nd))) {
- Bv_Copy(Reaches, bv2);
- Bv_And(bv, bv2);
- Bv_Or(bv2, MightReachAnyUse);
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches)))
- def->x18++;
- }
- if (nd->type == IROLinearFunccall && nd->stmt && IRO_FunctionCallMightThrowException(nd))
- IRO_WalkExcActions(nd->stmt->dobjstack, MarkUses);
- }
-
- if (nd->type == IROLinearAsm) {
- IAEffects effects;
- CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects);
- if (effects.x2) {
- Bv_Copy(Reaches, bv2);
- Bv_And(bv, bv2);
- Bv_Or(bv2, MightReachAnyUse);
- }
- }
-
- if (nd->type == IROLinearReturn || nd->type == IROLinearEnd) {
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->x1A && Bv_IsBitSet(def->index, Reaches)) {
- Bv_SetBit(def->index, MightReachAnyUse);
- def->x18++;
- }
- }
- }
-
- while (gdef && gdef->linear == nd) {
- if (gdef->x1C) {
- for (def = gdef->var->defs; def; def = def->varnext)
- Bv_ClearBit(def->index, Reaches);
- }
- Bv_SetBit(gdef->index, Reaches);
- gdef = gdef->globalnext;
- }
-
- if (nd == node->last)
- break;
- nd = nd->next;
- }
- }
-
- IRO_CheckForUserBreak();
-
- result = 0;
-
- if (optDeadAssignments) {
- MarkRemovableLoopDefs();
- for (def = FirstDef; def; def = def->globalnext) {
- if (def->linear &&
- (!Bv_IsBitSet(def->index, MightReachAnyUse) || def->x1D) &&
- (copts.opt_pointer_analysis || !def->x1B) &&
- def->linear->type != IROLinearAsm &&
- (!def->linear->rtype || !CParser_IsVolatile(def->linear->rtype, def->linear->nodeflags & ENODE_FLAG_QUALS)) &&
- !is_volatile_object(def->var->object)
- ) {
- if (!(def->linear->flags & IROLF_Reffed)) {
- def->x18 = 0;
- IRO_NopNonSideEffects(def->linear, -1);
- def->linear->type = IROLinearNop;
- IRO_Dump("Removing dead assignment %d\n", def->linear->index);
- result = 1;
- } else {
- result = EliminateReffedDeadStore(def);
- }
- }
- }
- }
-
- IRO_CheckForUserBreak();
-
- if (optPropagation) {
- while (1) {
- if (PropagateIncsAndDecs() || PropagateOtherSelfAssignments())
- result = 1;
- else
- break;
- }
- }
-
- IRO_CheckForUserBreak();
-
- return result;
-}
-
-static IROLinear *GetOperand(IROLinear *nd) {
- IROLinear *inner;
-
- if (nd->type == IROLinearOperand)
- return nd;
-
- if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD) {
- inner = GetOperand(nd->u.diadic.left);
- if (!inner)
- inner = GetOperand(nd->u.diadic.right);
- return inner;
- }
-
- return NULL;
-}
-
-static IROLinear *GetAssigned(IROLinear *nd) {
- if (!nd)
- return NULL;
-
- if (nd->type == IROLinearOp2Arg)
- nd = nd->u.diadic.left;
- else if (nd->type == IROLinearOp1Arg)
- nd = nd->u.monadic;
- else
- CError_FATAL(2338);
-
- if (nd->type != IROLinearOp1Arg || nd->nodetype != EINDIRECT)
- CError_FATAL(2351);
-
- nd = nd->u.monadic;
-
- if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD)
- nd = GetOperand(nd);
-
- return nd;
-}
-
-static void AddUseToRange(IROUse *use) {
- IRODef *def;
-
- Bv_SetBit(use->index, useset);
- Bv_ClearBit(use->index, alluses);
-
- for (def = use->var->defs; def; def = def->varnext) {
- if (Bv_IsBitSet(def->index, alldefs) && (Bv_IsBitSet(def->index, use->x18) || GetAssigned(def->linear) == use->linear))
- AddDefToRange(def);
- }
-}
-
-static void AddDefToRange(IRODef *def) {
- IROUse *use;
- IROLinear *assigned;
-
- Bv_SetBit(def->index, defset);
- Bv_ClearBit(def->index, alldefs);
-
- for (use = def->var->uses, assigned = GetAssigned(def->linear); use; use = use->varnext) {
- if (Bv_IsBitSet(use->index, alluses) && (Bv_IsBitSet(def->index, use->x18) || assigned == use->linear))
- AddUseToRange(use);
- }
-}
-
-static void ReplaceAssigned(IROLinear *nd, Object *from, Object *to) {
- IROLinear *assigned;
-
- if (
- !(assigned = GetAssigned(nd)) ||
- assigned->type != IROLinearOperand ||
- assigned->u.node->type != EOBJREF ||
- assigned->u.node->data.objref != from
- )
- CError_FATAL(2459);
-
- assigned->u.node->data.objref = to;
-}
-
-static void ReplaceUsed(IROLinear *nd, Object *from, Object *to) {
- CError_ASSERT(2482, nd->type == IROLinearOperand && nd->u.node->type == EOBJREF);
-
- if (nd->u.node->data.objref == from)
- nd->u.node->data.objref = to;
- else if (nd->u.node->data.objref != to)
- CError_FATAL(2494);
-}
-
-static void SplitOffRange(VarRecord *var) {
- Object *newObj;
- IRODef *def;
- IROUse *use;
-
- IRO_Dump("Splitting range for variable: %d\n", var->index);
- IRO_DumpBits("Def set: ", defset);
- IRO_DumpBits("Use set: ", useset);
- IRO_DumpBits("All defs: ", alldefs);
- IRO_DumpBits("All uses: ", alluses);
-
- newObj = create_temp_object(var->object->type);
- IRO_FindVar(newObj, 1, 1);
-
- for (def = var->defs; def; def = def->varnext) {
- if (Bv_IsBitSet(def->index, defset) && def->linear)
- ReplaceAssigned(def->linear, var->object, newObj);
- }
-
- for (use = var->uses; use; use = use->varnext) {
- if (Bv_IsBitSet(use->index, useset))
- ReplaceUsed(use->linear, var->object, newObj);
- }
-}
-
-void IRO_SplitLifetimes(void) {
- VarRecord *var;
- SInt32 numVars;
- IRODef *def;
- IROUse *use;
- Boolean flag;
-
- Bv_AllocVector(&alldefs, NumDefs);
- Bv_AllocVector(&alluses, NumUses);
- Bv_AllocVector(&defset, NumDefs);
- Bv_AllocVector(&useset, NumUses);
-
- var = IRO_FirstVar;
- numVars = IRO_NumVars;
-
- while (var && var->index <= numVars) {
- if (var->object->datatype == DLOCAL && !is_volatile_object(var->object) && !var->xC && !var->xB && !var->x1E) {
- Bv_Clear(alldefs);
- Bv_Clear(alluses);
-
- for (def = var->defs; def; def = def->varnext) {
- if (def->linear && def->linear->type == IROLinearAsm)
- goto skipThisVar;
- Bv_SetBit(def->index, alldefs);
- }
-
- for (use = var->uses; use; use = use->varnext) {
- if (use->linear && use->linear->type == IROLinearAsm)
- goto skipThisVar;
- Bv_SetBit(use->index, alluses);
- }
-
- flag = 1;
- while (1) {
- Bv_Clear(defset);
- Bv_Clear(useset);
-
- def = var->defs;
- while (def && !Bv_IsBitSet(def->index, alldefs))
- def = def->varnext;
-
- if (!def)
- break;
-
- AddDefToRange(def);
- if (Bv_IsEmpty(alldefs))
- break;
-
- if (!flag)
- SplitOffRange(var);
- flag = 0;
- }
- }
-
- skipThisVar:
- var = var->next;
- }
-
- IRO_CheckForUserBreak();
-}
diff --git a/compiler_and_linker/unsorted/InlineAsm.c b/compiler_and_linker/unsorted/InlineAsm.c
deleted file mode 100644
index 46a95d2..0000000
--- a/compiler_and_linker/unsorted/InlineAsm.c
+++ /dev/null
@@ -1,680 +0,0 @@
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/GCCInlineAsm.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInit.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/COptimizer.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/PCode.h"
-#include "compiler/Registers.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-int allow_array_expressions = 1;
-
-int backtracking;
-jmp_buf backtrack;
-jmp_buf InlineAsm_assemblererror;
-static int ASMstmtnb;
-
-void AssemblerError(void) {
- longjmp(InlineAsm_assemblererror, 1);
-}
-
-void InlineAsm_SyntaxError(short code) {
- if (backtracking)
- longjmp(backtrack, 1);
-
- if (tk == TK_EOL || tk == ';')
- code = CErrorStr112;
- CError_Error(code);
-}
-
-CLabel *InlineAsm_LookupLabel(HashNameNode *name) {
- CLabel *label;
-
- for (label = Labels; label; label = label->next) {
- if (name == label->name)
- break;
- }
-
- return label;
-}
-
-CLabel *InlineAsm_DeclareLabel(HashNameNode *name) {
- CLabel *label = newlabel();
- label->name = name;
- label->next = Labels;
- Labels = label;
- return label;
-}
-
-static void InlineAsm_DefineLabel(HashNameNode *name) {
- CLabel *label;
- Statement *stmt;
-
- label = InlineAsm_LookupLabel(name);
- if (!label) {
- label = InlineAsm_DeclareLabel(name);
- } else {
- if (label->stmt)
- CError_Error(CErrorStr171, name->name);
- }
-
- stmt = CFunc_AppendStatement(ST_LABEL);
- stmt->label = label;
- label->stmt = stmt;
-}
-
-Boolean InlineAsm_LookupSymbolOrTag(HashNameNode *name, IALookupResult *result, Boolean allow_tag) {
- ObjBase *obj;
- NameSpace *nspace;
- NameSpaceObjectList *list;
-
- result->name = name;
- result->object = NULL;
- result->label = NULL;
- result->type = NULL;
- result->has_value = 0;
-
- if ((result->label = InlineAsm_LookupLabel(name)))
- return 1;
-
- for (nspace = cscope_current; nspace; nspace = nspace->parent) {
- if ((list = CScope_FindName(nspace, name))) {
- obj = list->object;
- switch (obj->otype) {
- case OT_ENUMCONST:
- result->has_value = 1;
- result->value = OBJ_ENUM_CONST(list->object)->val.lo;
- return 1;
- case OT_OBJECT:
- if (OBJECT(obj)->datatype == DABSOLUTE) {
- result->has_value = 1;
- result->value = OBJECT(obj)->u.address;
- } else {
- if (OBJECT(obj)->datatype == DDATA && (OBJECT(obj)->qual & Q_INLINE_DATA))
- CInit_ExportConst(OBJECT(obj));
- result->object = OBJECT(obj);
- }
- return 1;
- case OT_TYPE:
- result->type = OBJ_TYPE(obj)->type;
- return 1;
- case OT_TYPETAG:
- if (allow_tag) {
- result->type = OBJ_TYPE_TAG(obj)->type;
- return 1;
- }
- case OT_NAMESPACE:
- case OT_MEMBERVAR:
- return 0;
- default:
- CError_FATAL(245);
- }
- }
- }
-
- return 0;
-}
-
-Boolean InlineAsm_LookupSymbol(HashNameNode *name, IALookupResult *result) {
- return InlineAsm_LookupSymbolOrTag(name, result, 0);
-}
-
-static ObjMemberVar *isclassmember(TypeClass *tclass, HashNameNode *name) {
- NameSpaceObjectList *list;
-
- list = CScope_FindName(tclass->nspace, name);
- return (list && list->object->otype == OT_MEMBERVAR) ? OBJ_MEMBER_VAR(list->object) : NULL;
-}
-
-SInt32 InlineAsm_StructMemberOffset(Type *type) {
- StructMember *member;
- ObjMemberVar *ivar;
- SInt32 offset = 0;
-
- do {
- if (IS_TYPE_STRUCT(type)) {
- tk = lex();
- if (tk != TK_IDENTIFIER)
- InlineAsm_SyntaxError(CErrorStr107);
- member = ismember(TYPE_STRUCT(type), tkidentifier);
- if (!member)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset += member->offset;
- type = member->type;
- tk = lex();
- } else if (IS_TYPE_CLASS(type)) {
- tk = lex();
- if (tk != TK_IDENTIFIER)
- InlineAsm_SyntaxError(CErrorStr107);
- ivar = isclassmember(TYPE_CLASS(type), tkidentifier);
- if (!ivar)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset += ivar->offset;
- type = ivar->type;
- tk = lex();
- } else {
- CError_Error(CErrorStr149);
- }
- } while (tk == '.');
-
- return offset;
-}
-
-SInt32 InlineAsm_StructArrayMemberOffset(Type *type) {
- StructMember *member;
- ObjMemberVar *ivar;
- SInt32 offset = 0;
-
- do {
- if (tk == '.') {
- if (IS_TYPE_STRUCT(type)) {
- tk = lex();
- if (tk != TK_IDENTIFIER)
- InlineAsm_SyntaxError(CErrorStr107);
- member = ismember(TYPE_STRUCT(type), tkidentifier);
- if (!member)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset += member->offset;
- type = member->type;
- tk = lex();
- } else if (IS_TYPE_CLASS(type)) {
- tk = lex();
- if (tk != TK_IDENTIFIER)
- InlineAsm_SyntaxError(CErrorStr107);
- ivar = isclassmember(TYPE_CLASS(type), tkidentifier);
- if (!ivar)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset += ivar->offset;
- type = ivar->type;
- tk = lex();
- } else {
- CError_Error(CErrorStr149);
- }
- } else {
- if (IS_TYPE_ARRAY(type)) {
- type = TPTR_TARGET(type);
- tk = lex();
- offset += type->size * InlineAsm_ConstantExpression();
- if (tk != ']')
- InlineAsm_SyntaxError(125);
- tk = lex();
- } else {
- CError_Error(CErrorStr148);
- }
- }
- } while (tk == '.' || tk == '[');
-
- return offset;
-}
-
-SInt32 InlineAsm_StructPointerMemberOffset(Type *type) {
- StructMember *member;
- ObjMemberVar *ivar;
- SInt32 offset;
-
- tk = lex();
- if (tk != TK_IDENTIFIER)
- InlineAsm_SyntaxError(107);
-
- if (IS_TYPE_STRUCT(type)) {
- member = ismember(TYPE_STRUCT(type), tkidentifier);
- if (!member)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset = member->offset;
- type = member->type;
- } else {
- ivar = isclassmember(TYPE_CLASS(type), tkidentifier);
- if (!ivar)
- CError_Error(CErrorStr150, tkidentifier->name);
- offset = ivar->offset;
- type = ivar->type;
- }
-
- tk = lex();
- if (tk == '.' || tk == '[')
- offset += InlineAsm_StructArrayMemberOffset(type);
-
- return offset;
-}
-
-static SInt32 DiadicOperator(SInt32 left, short op, SInt32 right) {
- CInt64 left64;
- CInt64 right64;
- CInt64_SetLong(&left64, left);
- CInt64_SetLong(&right64, right);
- right64 = CMach_CalcIntDiadic(TYPE(&stsignedint), left64, op, right64);
- return CInt64_GetULong(&right64);
-}
-
-static SInt32 PrimaryExpression(void) {
- IALookupResult result;
- SInt32 value;
-
- switch (tk) {
- case TK_IDENTIFIER:
- if (InlineAsm_LookupSymbol(tkidentifier, &result)) {
- if (result.has_value) {
- tk = lex();
- return result.value;
- }
-
- if (result.type && (IS_TYPE_STRUCT(result.type) || IS_TYPE_CLASS(result.type))) {
- tk = lex();
- if (tk != '.')
- InlineAsm_SyntaxError(120);
- if (allow_array_expressions)
- return InlineAsm_StructArrayMemberOffset(result.type);
- else
- return InlineAsm_StructMemberOffset(result.type);
- } else {
- InlineAsm_SyntaxError(124);
- }
- } else {
- InlineAsm_SyntaxError(124);
- }
- break;
- case TK_INTCONST:
- value = tkintconst.lo;
- tk = lex();
- return value;
- case TK_SIZEOF:
- return scansizeof();
- case '+':
- tk = lex();
- return PrimaryExpression();
- case '-':
- tk = lex();
- return -PrimaryExpression();
- case '!':
- tk = lex();
- return PrimaryExpression() == 0;
- case '~':
- tk = lex();
- return ~PrimaryExpression();
- case '(':
- tk = lex();
- value = InlineAsm_ConstantExpression();
- if (tk != ')')
- InlineAsm_SyntaxError(115);
- tk = lex();
- return value;
- default:
- InlineAsm_SyntaxError(120);
- }
-
- return 0;
-}
-
-static SInt32 ConstantExpressionTail(SInt32 value) {
- SInt32 right;
- short left_token;
- short right_prec;
-
- while (1) {
- left_token = tk;
- tk = lex();
- right = PrimaryExpression();
-
- right_prec = GetPrec(tk);
- if (right_prec == 0)
- return DiadicOperator(value, left_token, right);
-
- if (GetPrec(left_token) >= right_prec) {
- value = DiadicOperator(value, left_token, right);
- } else {
- value = DiadicOperator(value, left_token, ConstantExpressionTail(right));
- if (GetPrec(tk) == 0)
- return value;
- }
- }
-}
-
-SInt32 InlineAsm_ConstantExpression(void) {
- SInt32 value = PrimaryExpression();
-
- if (GetPrec(tk) == 0)
- return value;
- else
- return ConstantExpressionTail(value);
-}
-
-HashNameNode *MakeLocalLabel(CInt64 num) {
- char buf[80];
- sprintf(buf, "@%i_%i", ASMstmtnb, CInt64_GetULong(&num));
- return GetHashNameNodeExport(buf);
-}
-
-static void ScanOptionalLabel(void) {
- if (tk == TK_INTCONST) {
- if (lookahead() == ':') {
- InlineAsm_DefineLabel(MakeLocalLabel(tkintconst));
- tk = lex();
- tk = lex();
- }
- } else {
- if (tkidentifier->name[0] == '@') {
- InlineAsm_DefineLabel(tkidentifier);
- tk = lex();
- if (tk == ':')
- tk = lex();
- } else {
- HashNameNode *name = tkidentifier;
- short t = lookahead();
- tkidentifier = name;
- if (t == ':') {
- InlineAsm_DefineLabel(name);
- tk = lex();
- tk = lex();
- }
- }
- }
-}
-
-static void ScanStatements(volatile short endToken, AssemblerType mode) {
- if (setjmp(InlineAsm_assemblererror)) {
- while (tk != TK_EOL && tk != endToken && tk != '}' && tk)
- tk = lex();
- if (tk == ';' || tk == TK_EOL)
- tk = lex();
- } else {
- InlineAsm_Initialize(mode);
- InlineAsm_gccmode = 0;
- if (setjmp(InlineAsm_assemblererror)) {
- while (tk != ';' && tk != TK_EOL && tk != endToken && tk != '}' && tk)
- tk = lex();
- if (tk == ';' || tk == TK_EOL)
- tk = lex();
- }
-
- while (tk && tk != endToken) {
- backtracking = 0;
- sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset);
- if (tk == '"') {
- if (InlineAsm_gccmode) {
- tk = lex();
- InlineAsm_gcc_parse();
- } else {
- InlineAsm_gccmode = 1;
- copts.cplusplus = 0;
- copts.asmpoundcomment = 1;
- tk = lex();
- }
- }
-
- if (tk == '.') {
- InlineAsm_ScanAssemblyDirective();
- } else if (tk == TK_IDENTIFIER) {
- ScanOptionalLabel();
- if (tk == TK_IDENTIFIER)
- InlineAsm_ScanAssemblyInstruction();
- } else if (tk == TK_INTCONST) {
- ScanOptionalLabel();
- if (tk == TK_IDENTIFIER)
- InlineAsm_ScanAssemblyInstruction();
- }
-
- if (InlineAsm_gccmode && tk == '"') {
- tk = lex();
- InlineAsm_gcc_parse();
- }
-
- if (tk == ';' || tk == TK_EOL) {
- CPrep_TokenStreamFlush();
- tk = lex();
- } else if (tk != endToken) {
- if (endToken == ')')
- CError_Error(CErrorStr115);
- else
- CError_Error(CErrorStr113);
- }
- }
- }
-}
-
-void InlineAsm_ScanStatements(volatile short endToken) {
- ScanStatements(endToken, AssemblerType_0);
-}
-
-void InlineAsm_ScanFunction(volatile short endToken) {
- ScanStatements(endToken, AssemblerType_1);
-}
-
-void InlineAsm_Assemble(void) {
- short token = (tk == '(') ? ')' : '}';
- char save_pc = copts.asmpoundcomment;
- char save_cpp = copts.cplusplus;
-
- cprep_nostring = 1;
- CFunc_AppendStatement(ST_NOP);
- first_ST_ASM = curstmt;
- ASMstmtnb++;
-
- cprep_eoltokens = 1;
- in_assembler = 1;
- tk = lex();
- InlineAsm_ScanStatements(token);
- in_assembler = 0;
- cprep_eoltokens = 0;
- cprep_nostring = 0;
-
- copts.asmpoundcomment = save_pc;
- copts.cplusplus = save_cpp;
-}
-
-void InlineAsm_PackAsmStatement(Statement *stmt, Statement *first, void **output, SInt32 *outsize) {
- InlineAsm *src;
- InlineAsm *dest;
- IAOperand *op;
- SInt32 i;
- SInt32 size;
-
- src = (InlineAsm *) stmt->expr;
- size = sizeof(InlineAsm) + sizeof(IAOperand) * src->argcount;
- dest = galloc(size);
- memcpy(dest, src, size);
-
- for (i = 0, op = dest->args; i < dest->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_0:
- break;
- case IAOpnd_Reg:
- case IAOpnd_4:
- op->u.reg.object = (Object *) CInline_GetLocalID(op->u.reg.object);
- break;
- case IAOpnd_Lab:
- op->u.lab.label = (CLabel *) CInline_GetStatementNumber(first, op->u.lab.label->stmt);
- break;
- case IAOpnd_LabDiff:
- op->u.labdiff.label1 = (CLabel *) CInline_GetStatementNumber(first, op->u.labdiff.label1->stmt);
- op->u.labdiff.label2 = (CLabel *) CInline_GetStatementNumber(first, op->u.labdiff.label2->stmt);
- break;
- }
- }
-
- *output = dest;
- *outsize = size;
-}
-
-void InlineAsm_UnpackAsmStatement(Statement *stmt, CLabel **labelArray, Boolean flag, void *data, SInt32 size) {
- InlineAsm *ia;
- IAOperand *op;
- SInt32 i;
-
- ia = galloc(size);
- memcpy(ia, data, size);
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_0:
- break;
- case IAOpnd_Reg:
- case IAOpnd_4:
- op->u.reg.object = CInline_GetLocalObj((SInt32) op->u.reg.object, flag);
- break;
- case IAOpnd_Lab:
- op->u.lab.label = labelArray[(SInt16) op->u.lab.label];
- break;
- case IAOpnd_LabDiff:
- op->u.labdiff.label1 = labelArray[(SInt16) op->u.labdiff.label1];
- op->u.labdiff.label2 = labelArray[(SInt16) op->u.labdiff.label2];
- break;
- }
- }
-
- stmt->expr = (ENode *) ia;
-}
-
-void InlineAsm_CheckLocalUsage(Statement *stmt) {
- InlineAsm *ia = (InlineAsm *) stmt->expr;
- IAOperand *op;
- SInt32 i;
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_Reg:
- if (op->u.reg.object)
- SetVarUsage(op->u.reg.object, 0);
- break;
- case IAOpnd_4:
- SetVarUsage(op->u.obj.obj, 1);
- break;
- }
- }
-}
-
-CLabel *InlineAsm_GetReferencedLabel(Statement *stmt) {
- InlineAsm *ia = (InlineAsm *) stmt->expr;
- IAOperand *op;
- SInt32 i;
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- if (op->type == IAOpnd_Lab)
- return op->u.lab.label;
- if (op->type == IAOpnd_LabDiff)
- return op->u.labdiff.label1;
- }
-
- return NULL;
-}
-
-CLabel *InlineAsm_GetReferencedLabel2(Statement *stmt) {
- InlineAsm *ia = (InlineAsm *) stmt->expr;
- IAOperand *op;
- SInt32 i;
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- if (op->type == IAOpnd_LabDiff)
- return op->u.labdiff.label2;
- }
-
- return NULL;
-}
-
-Object *InlineAsm_GetObjectOffset(InlineAsm *ia, SInt32 index, SInt32 *offset) {
- IAOperand *op;
- SInt32 i;
- SInt32 counter;
-
- for (i = 0, counter = 0, op = ia->args; i < ia->argcount; i++, op++) {
- if (op->type == IAOpnd_3) {
- if (counter++ == index) {
- *offset = ((intptr_t) &op->u.obj.obj) - ((intptr_t) ia);
- return op->u.obj.obj;
- }
- }
- }
-
- return NULL;
-}
-
-char *InlineAsm_DumpStatement(Statement *stmt) {
- static char buffer[1024];
- InlineAsm *ia;
- IAOperand *arg;
- int i;
- char ch;
- SInt32 offset;
-
- ia = (InlineAsm *) stmt->expr;
-
- strcpy(buffer, "\"");
- strcat(buffer, InlineAsm_GetMnemonic(ia));
- strcat(buffer, "\"");
-
- for (i = 0, arg = ia->args; i < ia->argcount; i++, arg++) {
- char argbuf[1024];
-
- switch (arg->type) {
- case IAOpnd_Imm:
- sprintf(argbuf, " imm(%ld)", arg->u.imm.value);
- break;
- case IAOpnd_Reg:
- ch = ' ';
- if (arg->u.reg.effect & EffectWrite) {
- if (arg->u.reg.effect & EffectRead)
- ch = '+';
- else
- ch = '=';
- } else {
- if (!(arg->u.reg.effect & EffectRead))
- ch = '0';
- }
-
- if (arg->u.reg.object) {
- sprintf(argbuf,
- "%creg(%s)",
- ch,
- arg->u.reg.object->name->name);
- } else {
- sprintf(argbuf,
- "%creg(%s%d)",
- ch,
- register_class_name[arg->u.reg.rclass],
- arg->u.reg.num);
- }
- break;
-
- case IAOpnd_3:
- case IAOpnd_4:
- if (arg->u.obj.offset > 0)
- sprintf(argbuf, " obj(%s+%ld)", arg->u.obj.obj->name->name, arg->u.obj.offset);
- else if (arg->u.obj.offset < 0)
- sprintf(argbuf, " obj(%s-%ld)", arg->u.obj.obj->name->name, -arg->u.obj.offset);
- else
- sprintf(argbuf, " obj(%s)", arg->u.obj.obj->name->name);
- break;
-
- case IAOpnd_Lab:
- sprintf(argbuf, " lab(%s)", arg->u.lab.label->uniquename->name);
- break;
-
- case IAOpnd_LabDiff:
- offset = !arg->negated ? 0 : arg->u.labdiff.offset;
- sprintf(argbuf,
- " labdiff(%s-%s%c%d)",
- arg->u.labdiff.label1->uniquename->name,
- arg->u.labdiff.label2->uniquename->name,
- (arg->negated == 1) ? '-' : '+',
- offset
- );
- break;
- }
-
- strcat(buffer, argbuf);
- }
-
- return buffer;
-}
diff --git a/compiler_and_linker/unsorted/InlineAsmPPC.c b/compiler_and_linker/unsorted/InlineAsmPPC.c
deleted file mode 100644
index 464f9f9..0000000
--- a/compiler_and_linker/unsorted/InlineAsmPPC.c
+++ /dev/null
@@ -1,2586 +0,0 @@
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInt64.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/Alias.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CodeGenOptPPC.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/FuncLevelAsmPPC.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmMnemonicsPPC.h"
-#include "compiler/InlineAsmRegisters.h"
-#include "compiler/InlineAsmRegistersPPC.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/PPCError.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/objects.h"
-
-char asm_alloc_flags[10];
-Section sm_section;
-UInt32 cpu;
-SInt32 fralloc_parameter_area_size;
-Boolean user_responsible_for_frame;
-Boolean supports_hardware_fpu;
-UInt32 assembledinstructions;
-AssemblerType assembler_type;
-char volatileasm;
-Boolean InlineAsm_gccmode;
-Boolean InlineAsm_labelref;
-CLabel *pic_base_label;
-
-// forward decls
-static SInt32 InlineAsm_ConstantExpressionPPC(SInt32 value);
-static Object *isvariableoperand(void);
-static Object *isregisterstructpointeroperand(void);
-static void registeroperand(IAOperand *op, char rclass, short effect);
-static void DiadicOperatorPPC(IAExpr *left, short token, IAExpr *right);
-static void InlineAsm_ExpressionPPC(IAExpr *expr, SInt32 value);
-static void savepicbase(short reg, HashNameNode *name);
-
-CW_INLINE SInt32 ExtractValue(CInt64 value) {
- return (SInt32) CInt64_GetULong(&value);
-}
-
-static void IllegalObjectOperator(HashNameNode *name1, HashNameNode *name2, short token) {
- char *opstr;
- switch (token) {
- case '*': opstr = "*"; break;
- case '/': opstr = "/"; break;
- case '%': opstr = "%"; break;
- case '+': opstr = "+"; break;
- case '-': opstr = "-"; break;
- case TK_SHL: opstr = "<<"; break;
- case TK_SHR: opstr = ">>"; break;
- case '<': opstr = "<"; break;
- case '>': opstr = ">"; break;
- // bug? these two seem swapped
- case TK_LESS_EQUAL: opstr = ">="; break;
- case TK_GREATER_EQUAL: opstr = "<="; break;
- case TK_LOGICAL_EQ: opstr = "=="; break;
- case TK_LOGICAL_NE: opstr = "!="; break;
- case '&': opstr = "&"; break;
- case '^': opstr = "^"; break;
- case '|': opstr = "|"; break;
- case TK_LOGICAL_AND: opstr = "&&"; break;
- case TK_LOGICAL_OR: opstr = "||"; break;
- default: opstr = "???";
- }
-
- if (!name2) {
- PPCError_Error(PPCErrorStr119, opstr, name1->name);
- } else if (!name1) {
- PPCError_Error(PPCErrorStr120, opstr, name2->name);
- } else {
- PPCError_Error(PPCErrorStr118, name1->name, opstr, name2->name);
- }
-}
-
-static void IllegalObjectInConst(IAExpr *expr) {
- if (expr->xC) {
- PPCError_Error(PPCErrorStr122, expr->xC->name->name);
- } else if (expr->object) {
- PPCError_Error(PPCErrorStr122, expr->object->name->name);
- } else if (expr->label) {
- PPCError_Error(PPCErrorStr166, expr->label->name->name);
- }
-}
-
-static void NotInRegisterError(char *name, char rclass) {
- PPCError_Error(PPCErrorStr167, name, register_class_name[rclass]);
-}
-
-static int isregisteroperand(char rclass) {
- IARegister *reg;
-
- return (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass);
-}
-
-static SInt32 getcroperand(char rclass) {
- SInt32 value;
- IARegister *reg;
-
- value = 0;
- if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass) {
- value = reg->num;
- } else {
- PPCError_Error(PPCErrorStr167, tkidentifier->name);
- }
-
- tk = lex();
- return value;
-}
-
-static SInt32 getimmediateoperand(SInt32 minimum, SInt32 maximum) {
- SInt32 value = InlineAsm_ConstantExpressionPPC(0);
- if (value < minimum || value > maximum)
- CError_Error(CErrorStr154);
- return value;
-}
-
-static void PrimaryExpressionPPC(IAExpr *expr, SInt32 value) {
- Object *obj;
- IALookupResult result;
- IAExpr subexpr;
- IAExprType type = IAExpr_0;
- SInt32 v;
-
- switch (tk) {
- case TK_IDENTIFIER:
- if ((obj = isregisterstructpointeroperand())) {
- tk = lex();
- InlineAsm_InitExpr5(expr, InlineAsm_StructPointerMemberOffset(TPTR_TARGET(obj->type)));
- expr->object = obj;
- return;
- }
-
- if ((obj = isvariableoperand())) {
- short reg;
- InlineAsm_InitExpr5(expr, 0);
- expr->xC = obj;
-
- if (obj->datatype == DLOCAL)
- reg = 1;
- else
- reg = pic_base_reg;
-
- tk = lex();
- if (tk == '.' || tk == '[') {
- InlineAsm_InitExpr5(&subexpr, InlineAsm_StructArrayMemberOffset(obj->type));
- DiadicOperatorPPC(expr, '+', &subexpr);
- }
-
- if (tk == '+') {
- tk = lex();
- InlineAsm_ExpressionPPC(&subexpr, value);
- DiadicOperatorPPC(expr, '+', &subexpr);
- } else if (tk == '-') {
- tk = lex();
- InlineAsm_ExpressionPPC(&subexpr, value);
- DiadicOperatorPPC(expr, '-', &subexpr);
- } else if (!strcmp(tkidentifier->name, "@loword")) {
- tk = lex();
- if (low_offset) {
- InlineAsm_InitExpr5(&subexpr, low_offset);
- DiadicOperatorPPC(expr, '+', &subexpr);
- }
- } else if (!strcmp(tkidentifier->name, "@hiword")) {
- tk = lex();
- if (high_offset) {
- InlineAsm_InitExpr5(&subexpr, high_offset);
- DiadicOperatorPPC(expr, '+', &subexpr);
- }
- }
- expr->reg = reg;
- return;
- }
-
- if (InlineAsm_LookupSymbolOrTag(tkidentifier, &result, 1)) {
- if (result.has_value) {
- tk = lex();
- InlineAsm_InitExpr5(expr, result.value);
- return;
- }
-
- if (result.type && (IS_TYPE_STRUCT(result.type) || IS_TYPE_CLASS(result.type))) {
- tk = lex();
- if (tk != '.')
- CError_Error(CErrorStr120);
-
- if (allow_array_expressions) {
- InlineAsm_InitExpr5(expr, InlineAsm_StructArrayMemberOffset(result.type));
- return;
- }
-
- InlineAsm_InitExpr5(expr, InlineAsm_StructMemberOffset(result.type));
- return;
- }
-
- if (result.object && result.object->datatype == DABSOLUTE) {
- tk = lex();
- InlineAsm_InitExpr5(expr, result.object->u.address);
- return;
- }
- } else if (value) {
- if (isregisteroperand(RegClass_CRFIELD)) {
- InlineAsm_InitExpr5(expr, getcroperand(RegClass_CRFIELD));
- return;
- }
- if (isregisteroperand(RegClass_6)) {
- InlineAsm_InitExpr5(expr, getcroperand(RegClass_6));
- return;
- }
- if (strlen(tkidentifier->name) == 6 && !strncmp(tkidentifier->name, "cr", 2) && tkidentifier->name[3] == '_') {
- IARegister *reg;
- char regname[4];
- regname[0] = tkidentifier->name[0];
- regname[1] = tkidentifier->name[1];
- regname[2] = tkidentifier->name[2];
- regname[3] = 0;
- if ((reg = InlineAsm_LookupRegisterPPC(regname)) && reg->rclass == RegClass_CRFIELD) {
- SInt32 v = reg->num * 4;
- regname[0] = tkidentifier->name[4];
- regname[1] = tkidentifier->name[5];
- regname[2] = 0;
- if ((reg = InlineAsm_LookupRegisterPPC(regname)) && reg->rclass == RegClass_6) {
- tk = lex();
- InlineAsm_InitExpr5(expr, v + reg->num);
- return;
- }
- }
- }
- }
-
- if (!strcmp("ha16", tkidentifier->name))
- type = IAExpr_8;
- else if (!strcmp("hi16", tkidentifier->name))
- type = IAExpr_7;
- else if (!strcmp("lo16", tkidentifier->name))
- type = IAExpr_6;
-
- if (type != IAExpr_0) {
- tk = lex();
- if (tk == '(') {
- SInt32 v;
- tk = lex();
- PrimaryExpressionPPC(expr, value);
- expr->type = type;
- if (tk != ')')
- CError_Error(CErrorStr115);
-
- tk = lex();
- if (InlineAsm_CheckExpr(expr)) {
- expr->value = InlineAsm_GetExprValue(expr);
- expr->type = IAExpr_5;
- }
- return;
- }
-
- CError_Error(CErrorStr114);
- } else {
- if (!result.label)
- result.label = InlineAsm_DeclareLabel(tkidentifier);
-
- InlineAsm_InitExpr5(expr, 0);
- expr->flags |= IAFlag1;
- expr->label = result.label;
- tk = lex();
- return;
- }
- break;
-
- case TK_INTCONST:
- v = CInt64_GetULong(&tkintconst);
- tk = lex();
- InlineAsm_InitExpr5(expr, v);
- return;
-
- case TK_SIZEOF:
- InlineAsm_InitExpr5(expr, scansizeof());
- return;
-
- case '+':
- tk = lex();
- PrimaryExpressionPPC(expr, value);
- return;
-
- case '-':
- tk = lex();
- PrimaryExpressionPPC(expr, value);
- if (InlineAsm_CheckExpr(expr))
- expr->value = -expr->value;
- else
- CError_Error(CErrorStr124);
- return;
-
- case '!':
- tk = lex();
- PrimaryExpressionPPC(expr, value);
- if (InlineAsm_CheckExpr(expr))
- expr->value = !expr->value;
- else
- CError_Error(CErrorStr124);
- return;
-
- case '~':
- tk = lex();
- PrimaryExpressionPPC(expr, value);
- if (InlineAsm_CheckExpr(expr))
- expr->value = ~expr->value;
- else
- CError_Error(CErrorStr124);
- return;
-
- case '(':
- tk = lex();
- InlineAsm_ExpressionPPC(expr, value);
- if (tk != ')')
- CError_Error(CErrorStr115);
- tk = lex();
- return;
-
- default:
- CError_Error(CErrorStr120);
- }
-
- InlineAsm_InitExpr5(expr, 0);
-}
-
-static void DiadicOperatorPPC(IAExpr *left, short token, IAExpr *right) {
- CInt64 leftval;
- CInt64 rightval;
-
- CInt64_SetLong(&leftval, left->value);
- CInt64_SetLong(&rightval, right->value);
- rightval = CMach_CalcIntDiadic(TYPE(&stsignedint), leftval, token, rightval);
-
- if (left->xC) {
- if (right->label)
- PPCError_Error(PPCErrorStr124, left->xC->name->name, right->label->name->name);
-
- if (right->xC) {
- if (left->x10) {
- PPCError_Error(PPCErrorStr121, left->xC->name->name, left->x10->name->name, right->xC->name->name);
- } else if (right->x10) {
- PPCError_Error(PPCErrorStr121, left->xC->name->name, right->xC->name->name, right->x10->name->name);
- } else if (token == '-') {
- left->value = CInt64_GetULong(&rightval);
- left->x10 = right->xC;
- } else {
- IllegalObjectOperator(left->xC->name, right->xC->name, token);
- }
- } else if (token == '-' || token == '+') {
- left->value = CInt64_GetULong(&rightval);
- } else {
- IllegalObjectOperator(left->xC->name, NULL, token);
- }
- } else if (right->xC) {
- if (right->label)
- PPCError_Error(PPCErrorStr124, right->xC->name->name, right->label->name->name);
-
- if (token == '+') {
- left->xC = right->xC;
- left->x10 = right->x10;
- left->value = CInt64_GetULong(&rightval);
- } else {
- IllegalObjectOperator(NULL, right->xC->name, token);
- }
- } else if (left->label) {
- if (left->xC)
- PPCError_Error(PPCErrorStr124, left->label->name->name, left->xC->name->name);
-
- if (right->label) {
- if (left->x18) {
- PPCError_Error(PPCErrorStr121, left->label->name->name, left->x18->name->name, right->label->name->name);
- } else if (right->x18) {
- PPCError_Error(PPCErrorStr121, left->label->name->name, right->label->name->name, right->x18->name->name);
- } else if (token == '-') {
- left->value = CInt64_GetULong(&rightval);
- left->x18 = right->label;
- } else {
- IllegalObjectOperator(left->label->name, right->label->name, token);
- }
- } else if (token == '+' || token == '-') {
- left->value = CInt64_GetULong(&rightval);
- } else {
- IllegalObjectOperator(NULL, left->label->name, token);
- }
- } else if (right->label) {
- if (token == '+') {
- left->label = right->label;
- left->x18 = right->x18;
- left->value = CInt64_GetULong(&rightval);
- } else {
- IllegalObjectOperator(NULL, right->label->name, token);
- }
- } else {
- left->value = CInt64_GetULong(&rightval);
- }
-
- left->flags |= right->flags;
- if (left->type == IAOpnd_Lab) {
- if (right->type != IAOpnd_Lab)
- left->type = right->type;
- } else {
- if (right->type != IAOpnd_Lab && right->type != left->type)
- PPCError_Error(PPCErrorStr126);
- }
-}
-
-static void ExpressionTailPPC(IAExpr *left, SInt32 value) {
- IAExpr right;
- short left_tk;
- short right_prec;
-
- while (1) {
- left_tk = tk;
- tk = lex();
-
- PrimaryExpressionPPC(&right, value);
- right_prec = GetPrec(tk);
- if (right_prec == 0) {
- DiadicOperatorPPC(left, left_tk, &right);
- break;
- }
-
- if (GetPrec(left_tk) >= right_prec) {
- DiadicOperatorPPC(left, left_tk, &right);
- } else {
- ExpressionTailPPC(&right, value);
- DiadicOperatorPPC(left, left_tk, &right);
- if (GetPrec(tk) == 0)
- break;
- }
- }
-}
-
-static void immediateoperand(IAOperand *op, SInt32 minval, SInt32 maxval) {
- SInt32 value;
- if (InlineAsm_gccmode && tk == '%') {
- tk = lex();
- if (tk != TK_INTCONST) {
- CError_Error(CErrorStr144);
- } else {
- CInt64 c = tkintconst;
- value = CInt64_GetULong(&c);
- if (value < 0)
- CError_Error(CErrorStr144);
- }
- op->type = IAOpnd_7;
- op->u.unk7.value = value;
- op->u.unk7.unk1 = 1;
- op->u.unk7.unk2 = 0;
- op->u.unk7.unk3 = 0;
- tk = lex();
- } else {
- value = InlineAsm_ConstantExpressionPPC(0);
- if (value < minval || value > maxval)
- CError_Error(CErrorStr154);
- op->type = IAOpnd_Imm;
- op->u.imm.value = value;
- }
-}
-
-static SInt32 immediatevalue(IAOperand *op, SInt32 minval, SInt32 maxval) {
- SInt32 value;
- if (InlineAsm_gccmode && tk == '%') {
- CError_Error(CErrorStr144);
- return 0;
- } else {
- value = InlineAsm_ConstantExpressionPPC(0);
- if (value < minval || value > maxval)
- CError_Error(CErrorStr154);
- op->type = IAOpnd_Imm;
- op->u.imm.value = value;
- return value;
- }
-}
-
-static void InlineAsm_ExpressionPPC(IAExpr *expr, SInt32 value) {
- PrimaryExpressionPPC(expr, value);
- if (GetPrec(tk))
- ExpressionTailPPC(expr, value);
- if (GetPrec(tk))
- ExpressionTailPPC(expr, value);
-
- if (expr->type == IAExpr_5 && tk == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "@l")) {
- expr->type = IAExpr_6;
- tk = lex();
- } else if (!strcmp(tkidentifier->name, "@ha")) {
- expr->type = IAExpr_8;
- tk = lex();
- } else if (!strcmp(tkidentifier->name, "@h")) {
- expr->type = IAExpr_7;
- tk = lex();
- }
- }
-}
-
-static SInt32 InlineAsm_ConstantExpressionPPC(SInt32 value) {
- IAExpr expr;
-
- InlineAsm_ExpressionPPC(&expr, value);
- if (!InlineAsm_CheckExpr(&expr)) {
- IllegalObjectInConst(&expr);
- return 0;
- } else {
- return InlineAsm_GetExprValue(&expr);
- }
-}
-
-static SInt32 crbitoperand(void) {
- SInt32 value = InlineAsm_ConstantExpressionPPC(1);
- if (value < 0 || value > 31)
- CError_Error(CErrorStr154);
- return value;
-}
-
-static void floatoperand(IAOperand *op, InlineAsm *ia, Type *type) {
- Object *obj;
-
- obj = createfloatconstant(type, &tkfloatconst);
- op[0].type = IAOpnd_Reg;
- op[0].u.reg.rclass = RegClass_GPR;
- op[0].u.reg.object = NULL;
- op[0].u.reg.effect = EffectRead;
- op[0].u.reg.num = pic_base_reg;
-
- ia->argcount++;
- op[1].type = IAOpnd_4;
- op[1].u.obj.obj = obj;
- PPCError_Error(PPCErrorStr179);
- op[1].u.obj.unk = IAExpr_2;
- op[1].u.obj.offset = 0;
- tk = lex();
-}
-
-static Object *isvariableoperand(void) {
- IALookupResult result;
- Object *obj;
-
- if (tk == TK_IDENTIFIER) {
- InlineAsm_LookupSymbol(tkidentifier, &result);
- if ((obj = result.object)) {
- if (obj->datatype == DLOCAL) {
- if (OBJECT_REG(obj))
- return NULL;
- return obj;
- }
-
- if (obj->datatype == DFUNC || obj->datatype == DVFUNC)
- return obj;
-
- if (obj->datatype == DDATA) {
- createIndirect(obj, 0, 0);
- return obj;
- }
- }
- }
-
- return NULL;
-}
-
-static Object *isregisterstructpointeroperand(void) {
- IALookupResult result;
- Object *obj;
-
- if (tk != TK_IDENTIFIER)
- return NULL;
-
- InlineAsm_LookupSymbol(tkidentifier, &result);
- if ((obj = result.object)) {
- if (obj->datatype != DLOCAL)
- return NULL;
- if (!OBJECT_REG(obj) && !is_register_object(obj))
- return NULL;
- if (!IS_TYPE_POINTER(obj->type))
- return NULL;
- if (!IS_TYPE_STRUCT(TPTR_TARGET(obj->type)) && !IS_TYPE_CLASS(TPTR_TARGET(obj->type)))
- return NULL;
- return obj;
- }
-
- return NULL;
-}
-
-static void memoryoperand(IAOperand *op, InlineAsm *ia, Boolean flag, short effect) {
- IAExpr expr;
-
- InlineAsm_ExpressionPPC(&expr, 0);
- if (expr.object) {
- if (!flag)
- CError_Error(CErrorStr155);
- if (expr.xC)
- PPCError_Error(PPCErrorStr122, expr.xC);
-
- op[0].type = IAOpnd_Reg;
- op[0].u.reg.rclass = RegClass_GPR;
- op[0].u.reg.object = expr.object;
- op[0].u.reg.num = 0;
- op[0].u.reg.effect = effect;
- if (expr.object || expr.reg)
- op[0].u.reg.effect = effect;
- else
- op[0].u.reg.effect = 0;
-
- ia->argcount++;
- op[1].type = IAOpnd_Imm;
- switch (expr.type) {
- case IAExpr_5:
- expr.type = IAExpr_6;
- if (expr.object->datatype != DLOCAL || !OBJECT_REG(expr.object))
- PPCError_Error(PPCErrorStr180);
- case IAExpr_2:
- case IAExpr_6:
- case IAExpr_7:
- case IAExpr_8:
- op[1].u.imm.value = InlineAsm_GetExprValue(&expr);
- break;
- default:
- CError_Error(CErrorStr155);
- }
-
- expr.object->flags |= OBJECT_USED;
- return;
- }
-
- if (expr.xC) {
- if (expr.x10)
- PPCError_Error(PPCErrorStr123, expr.xC->name->name, expr.x10->name->name);
-
- if (flag) {
- if (tk == '(') {
- if (flag) {
- tk = lex();
- registeroperand(op, RegClass_GPR, effect);
- if ((expr.type == IAExpr_8 || expr.type == IAExpr_7) && copts.codegen_pic && pic_base_reg)
- CError_Error(CErrorStr155);
- if (tk != ')')
- CError_Error(CErrorStr115);
- tk = lex();
- }
- } else {
- op[0].type = IAOpnd_Reg;
- op[0].u.reg.rclass = RegClass_GPR;
- op[0].u.reg.object = expr.object;
- op[0].u.reg.num = expr.reg;
- }
-
- if (expr.object || expr.reg)
- op[0].u.reg.effect = effect;
- else
- op[0].u.reg.effect = 0;
-
- ia->argcount++;
- op++;
- }
-
- if (expr.xC->datatype == DLOCAL) {
- op[0].type = IAOpnd_4;
- op[0].u.obj.unk = IAExpr_1;
- } else {
- op[0].type = IAOpnd_3;
- if (expr.type == IAExpr_5) {
- expr.type = IAExpr_6;
- PPCError_Error(PPCErrorStr180);
- }
- op[0].u.obj.unk = expr.type;
- }
-
- op[0].u.obj.obj = expr.xC;
- op[0].u.obj.offset = expr.value;
- expr.xC->flags |= OBJECT_USED;
- return;
- }
-
- if (flag) {
- if (tk == '(') {
- tk = lex();
- registeroperand(op, RegClass_GPR, effect);
- ia->argcount++;
- op++;
- if (tk != ')')
- CError_Error(CErrorStr115);
- tk = lex();
- } else {
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_GPR;
- op->u.reg.object = expr.object;
- op->u.reg.num = expr.reg;
- ia->argcount++;
- op++;
- }
- }
-
- if (expr.label) {
- if (expr.x18) {
- op->type = IAOpnd_LabDiff;
- op->negated = 0;
- op->u.labdiff.label1 = expr.label;
- op->u.labdiff.label2 = expr.x18;
- op->u.labdiff.offset = expr.value;
- } else {
- PPCError_Error(PPCErrorStr125, expr.label->name->name);
- }
- } else {
- op->type = IAOpnd_Imm;
- op->u.imm.value = InlineAsm_GetExprValue(&expr);
- }
-}
-
-static void registeroperand(IAOperand *op, char rclass, short effect) {
- IARegister *reg;
- Object *obj;
-
- if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass) {
- SInt32 num;
- obj = reg->object;
- num = reg->num;
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = rclass;
- op->u.reg.object = obj;
- op->u.reg.num = num;
- op->u.reg.effect = effect;
- if (obj) {
- reg->object->flags |= OBJECT_USED;
- Registers_GetVarInfo(obj)->flags |= VarInfoFlag40;
- }
- } else if (rclass == RegClass_CRFIELD) {
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_CRFIELD;
- op->u.reg.object = NULL;
- op->u.reg.num = getimmediateoperand(0, 7);
- op->u.reg.effect = effect;
- return;
- } else if (rclass == RegClass_SPR) {
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.object = NULL;
- op->u.reg.num = getimmediateoperand(0, 1024);
- op->u.reg.effect = effect;
- return;
- } else if (tk == '%' && InlineAsm_gccmode) {
- SInt32 num;
- tk = lex();
- if (tk != TK_INTCONST) {
- CError_Error(CErrorStr144);
- } else {
- num = ExtractValue(tkintconst);
- if (num < 0)
- CError_Error(CErrorStr144);
- }
-
- op->type = IAOpnd_6;
- op->u.unk6.num = num;
- op->u.unk6.unk4 = 2;
- op->u.unk6.effect = effect;
- op->u.unk6.rclass = rclass;
- tk = lex();
- return;
- } else if (tk == TK_IDENTIFIER) {
- NotInRegisterError(tkidentifier->name, rclass);
- } else {
- PPCError_Error(PPCErrorStr171);
- }
-
- tk = lex();
- if (!strcmp(tkidentifier->name, "@loword")) {
- tk = lex();
- } else if (!strcmp(tkidentifier->name, "@hiword")) {
- if (reg->object)
- op->u.reg.num = 1;
- else
- PPCError_Error(PPCErrorStr168);
- tk = lex();
- } else if (rclass == RegClass_GPR) {
- if (reg->object && reg->object->type->size == 8) {
- HashNameNode *name = reg->object->name;
- PPCError_Error(PPCErrorStr127, name->name, name->name, name->name);
- }
- }
-}
-
-static void cr0_operand(IAOperand *op, short effect) {
- IARegister *reg;
-
- if ((reg = InlineAsm_LookupRegisterPPC("cr0"))) {
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_CRFIELD;
- op->u.reg.object = reg->object;
- op->u.reg.num = reg->num;
- op->u.reg.effect = effect;
- } else {
- NotInRegisterError("cr0", RegClass_CRFIELD);
- }
-}
-
-static void r0_operand(IAOperand *op) {
- IARegister *reg;
-
- if ((reg = InlineAsm_LookupRegisterPPC("r0"))) {
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_GPR;
- op->u.reg.object = reg->object;
- op->u.reg.num = reg->num;
- op->u.reg.effect = 0;
- tk = lex();
- } else {
- NotInRegisterError("r0", RegClass_GPR);
- }
-}
-
-static void labeloperand(InlineAsm *ia, IAOperand *op, Boolean flag1, Boolean flag2, Boolean flag3) {
- IALookupResult result;
-
- if (tk == TK_IDENTIFIER) {
- if (!InlineAsm_LookupSymbol(tkidentifier, &result))
- result.label = InlineAsm_DeclareLabel(tkidentifier);
-
- if (result.label) {
- op->type = IAOpnd_Lab;
- op->u.lab.label = result.label;
- } else if (result.object && result.object->datatype == DFUNC) {
- if (flag3)
- ia->flags |= IAFlag2;
- op->type = IAOpnd_3;
- op->u.obj.obj = result.object;
- op->u.obj.offset = 0;
-
- if (flag1) {
- op->u.obj.unk = IAExpr_4;
- if (flag2)
- CError_Error(CErrorStr261);
- } else {
- op->u.obj.unk = IAExpr_2;
- if (flag2)
- op->u.obj.unk = IAExpr_10;
- op->u.obj.unk = IAExpr_6;
- PPCError_Error(PPCErrorStr180);
- }
- } else {
- CError_Error(CErrorStr144);
- }
-
- tk = lex();
- } else if (tk == '*') {
- if (!flag2) {
- tk = lex();
- if (tk == '+') {
- tk = lex();
- if (flag1)
- immediateoperand(op, -0x2000000, 0x1FFFFFF);
- else
- immediateoperand(op, -0x8000, 0xFFFF);
- } else if (tk == '-') {
- tk = lex();
- op->u.imm.value = flag1 ? -immediatevalue(op, -0x1FFFFFF, 0x2000000) : -immediatevalue(op, -0x7FFF, 0x10000);
- } else {
- CError_Error(CErrorStr144);
- }
- } else {
- CError_Error(CErrorStr144);
- }
- } else {
- if (flag2) {
- if (flag1)
- immediateoperand(op, -0x2000000, 0x1FFFFFF);
- else
- immediateoperand(op, -0x8000, 0xFFFF);
- } else {
- CError_Error(CErrorStr144);
- }
- }
-}
-
-static void imm_or_labeldiff_operand(InlineAsm *ia, IAOperand *op, SInt32 minimum, SInt32 maximum, Boolean negate) {
- IAExpr expr;
- Object *obj;
- SInt32 value;
-
- InlineAsm_ExpressionPPC(&expr, 0);
-
- if ((obj = expr.xC) && !expr.x10 && expr.type == IAExpr_5 && obj->datatype == DDATA && IS_TYPE_INT_OR_ENUM(obj->type) && (obj->qual & Q_INLINE_DATA)) {
- switch (ia->opcode) {
- case PC_ADDI:
- case PC_ADDIC:
- case PC_ADDICR:
- case PC_ADDIS:
- case PC_ORI:
- case PC_ORIS:
- if (ia->args[1].u.imm.value) {
- SInt32 cmp;
- if (obj->datatype != DLOCAL) {
- cmp = copts.codegen_pic ? INVALID_PIC_REG : NO_REG;
- } else {
- cmp = local_base_register(obj);
- }
- if (ia->args[1].u.imm.value == cmp)
- break;
- }
- case PC_LI:
- case PC_LIS:
- case PC_TWI:
- case PC_OPWORD:
- InlineAsm_InitExpr5(&expr, expr.value + CInt64_GetULong(&obj->u.data.u.intconst));
- break;
- }
- }
-
- if (expr.label) {
- if (expr.x18) {
- op->type = IAOpnd_LabDiff;
- if (negate)
- op->negated = 1;
- else
- op->negated = 0;
- op->u.labdiff.label1 = expr.label;
- op->u.labdiff.label2 = expr.x18;
- op->u.labdiff.offset = expr.value;
- } else {
- PPCError_Error(PPCErrorStr125, expr.label->name->name);
- }
- return;
- }
-
- if (expr.xC) {
- if (!expr.x10) {
- if (ia->opcode != PC_OPWORD && expr.type == IAExpr_5) {
- IllegalObjectInConst(&expr);
- return;
- }
-
- if (expr.xC->datatype == DLOCAL) {
- op->type = IAOpnd_4;
- op->u.obj.unk = IAExpr_1;
- } else {
- op->type = IAOpnd_3;
- if (expr.type == IAExpr_5) {
- expr.type = IAExpr_6;
- PPCError_Error(PPCErrorStr180);
- }
- op->u.obj.unk = expr.type;
- }
- op->u.obj.obj = expr.xC;
- op->u.obj.offset = expr.value;
- } else {
- PPCError_Error(PPCErrorStr123, expr.xC->name->name, expr.x10->name->name);
- }
- return;
- }
-
- value = InlineAsm_GetExprValue(&expr);
- if (value < minimum || value > maximum)
- CError_Error(CErrorStr154);
-
- op->type = IAOpnd_Imm;
- if (negate)
- op->u.imm.value = -value;
- else
- op->u.imm.value = value;
-}
-
-static void eatcommatoken(void) {
- if (tk == ',')
- tk = lex();
- else
- CError_Error(CErrorStr116);
-}
-
-static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
- OpcodeInfo *info;
- InlineAsm *ia;
- SInt32 buffersize;
- IAOperand *op;
- int argcount;
- char *format;
- IARegister *reg;
-
- char code;
- short effect;
- Boolean has_excl;
- Boolean has_question;
- Boolean negate;
- UInt32 t;
-
- info = &opcodeinfo[mnemonic->x4];
- argcount = info->x8;
- if (PCODE_FLAG_SET_F(info) & fCanSetRecordBit)
- argcount++;
- if (!(PCODE_FLAG_SET_F(info) & fSetsCarry) && (PCODE_FLAG_SET_F(info) & fCanSetCarry))
- argcount++;
- if (PCODE_FLAG_SET_T(info) & fCanLink)
- argcount++;
-
- buffersize = sizeof(InlineAsm) + sizeof(IAOperand) * argcount;
- ia = galloc(buffersize);
- memset(ia, 0, buffersize);
-
- ia->opcode = mnemonic->x4;
- ia->flags = 0;
- ia->argcount = 0;
-
- op = ia->args;
- for (format = mnemonic->format; *format; format++) {
- CError_ASSERT(1664, ia->argcount < argcount);
-
- if (*format == ',') {
- eatcommatoken();
- format++;
- } else if (*format == ';') {
- format++;
- }
-
- if (*format == '[' || *format == '(')
- format++;
-
- effect = EffectRead;
- has_excl = 0;
- has_question = 0;
- negate = 0;
- if (*format == '=') {
- effect = EffectWrite;
- format++;
- } else if (*format == '+') {
- effect = EffectRead | EffectWrite;
- format++;
- }
-
- if (*format == '-') {
- negate = 1;
- format++;
- }
-
- if (*format == '?') {
- has_question = 1;
- format++;
- }
-
- if (*format == '!') {
- has_excl = 1;
- format++;
- }
-
- switch (*format) {
- case 'p':
- continue;
- case '&':
- if (format[1] == '2') {
- op[0] = op[-2];
- format++;
- if (op->type == IAOpnd_Reg)
- op->u.reg.effect = effect;
- ia->argcount++;
-
- op[1] = op[-1];
- op++;
- if (op->type == IAOpnd_Reg)
- op->u.reg.effect = effect;
- } else {
- op[0] = op[-1];
- if (op->type == IAOpnd_Reg)
- op->u.reg.effect = effect;
- }
- break;
-
- case '%': {
- SInt32 value;
- format += pcode_const_from_format(format + 1, &value);
- op->type = IAOpnd_Imm;
- op->u.imm.value = value;
- break;
- }
-
- case 'b':
- if (!isregisteroperand(RegClass_GPR)) {
- if (tk == TK_INTCONST && tkintconst.lo == 0)
- r0_operand(op);
- } else {
- registeroperand(op, RegClass_GPR, effect);
- if (op->u.reg.object == NULL && op->u.reg.num == 0)
- op->u.reg.effect = 0;
- }
- break;
-
- case 'r':
- registeroperand(op, RegClass_GPR, effect);
- break;
-
- case 'B':
- case 'a':
- case 'i':
- case 't':
- case 'u':
- case 'x':
- {
- SInt32 value, hi, lo;
- code = *format;
- value = 16;
- if (code == 'a') {
- if (isdigit(format[1]))
- code = *(++format);
- else
- CError_FATAL(1804);
- }
-
- if (isdigit(format[1])) {
- format += pcode_const_from_format(format + 1, &value);
- } else if (code == 't' || code == 'B') {
- code = 'u';
- value = 5;
- }
-
- pcode_get_hi_lo(value, code, &hi, &lo);
- if (!has_question || tk == ',') {
- if (has_question)
- tk = lex();
- if (has_excl)
- getimmediateoperand(lo, hi);
- else
- immediateoperand(op, lo, hi);
- } else {
- op->type = IAOpnd_Imm;
- op->u.imm.value = 0;
- }
-
- if (code == 'i' && value == 16)
- op->u.imm.value = (short) op->u.imm.value;
- if (negate)
- op->u.imm.value = -op->u.imm.value;
-
- if (pcode_check_imm_bits(op->u.imm.value, value, code))
- CError_FATAL(1838);
-
- break;
- }
-
- case 'O':
- if (tk == TK_INTCONST && tkintconst.lo == 0) {
- getimmediateoperand(0, 0);
- eatcommatoken();
- }
- continue;
-
- case 'f':
- registeroperand(op, RegClass_FPR, effect);
- break;
-
- case 'v':
- registeroperand(op, RegClass_VR, effect);
- break;
-
- case 'T':
- if (!has_question || tk == ',') {
- if (has_question)
- tk = lex();
-
- immediateoperand(op, 268, 269);
- if (op->u.reg.num == 268)
- op->u.reg.num = 284;
- else
- op->u.reg.num = 285;
- } else {
- op->u.reg.num = 284;
- }
-
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.effect = effect;
- break;
-
- case 'S':
- {
- SInt32 value;
- format += pcode_const_from_format(format + 1, &value);
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.num = value;
- op->u.reg.effect = effect;
- break;
- }
-
- case 'c':
- if (has_question) {
- if (isregisteroperand(RegClass_CRFIELD) || tk == TK_INTCONST) {
- registeroperand(op, RegClass_CRFIELD, effect);
- } else {
- cr0_operand(op, effect);
- if (format[1] == ',')
- format++;
- }
- } else {
- registeroperand(op, RegClass_CRFIELD, effect);
- }
- break;
-
- case 'l':
- switch (ia->opcode) {
- case PC_B:
- case PC_BL:
- labeloperand(ia, op, 1, mnemonic->x10 & 2, mnemonic->x10 & 1);
- break;
- default:
- labeloperand(ia, op, 0, mnemonic->x10 & 2, mnemonic->x10 & 1);
- break;
- }
- break;
-
- case 'w':
- imm_or_labeldiff_operand(ia, op, -0x80000000, 0x7FFFFFFF, negate);
- break;
-
- case 'M':
- case 'm':
- case 'n':
- imm_or_labeldiff_operand(ia, op, -0x8000, 0xFFFF, negate);
- break;
-
- case 'Q':
- {
- SInt32 cr = crbitoperand();
- op->type = IAOpnd_Reg;
- op->u.reg.num = cr >> 2;
- op->u.reg.rclass = RegClass_CRFIELD;
- op->u.reg.effect = effect;
-
- ia->argcount++;
- op[1].type = IAOpnd_Imm;
- op[1].u.imm.value = cr % 4;
- op++;
- break;
- }
-
- case 'd': {
- short effect2;
- CError_ASSERT(1971, format[1] == '(');
- format++;
- effect2 = EffectRead;
- if (format[1] == '=') {
- effect2 = EffectWrite;
- format++;
- } else if (format[1] == '+') {
- effect2 = EffectRead | EffectWrite;
- format++;
- }
-
- CError_ASSERT(1983, format[1] == 'b');
- CError_ASSERT(1985, format[2] == ')');
- format += 2;
-
- switch (ia->opcode) {
- case PC_LFS:
- if (tk == TK_FLOATCONST)
- floatoperand(op, ia, TYPE(&stfloat));
- else
- memoryoperand(op, ia, 1, effect2);
- break;
- case PC_LFD:
- if (tk == TK_FLOATCONST)
- floatoperand(op, ia, TYPE(&stdouble));
- else
- memoryoperand(op, ia, 1, effect2);
- break;
- default:
- memoryoperand(op, ia, 1, effect2);
- }
-
- break;
- }
-
- case 'N':
- immediateoperand(op, 1, 32);
- break;
-
- case 's':
- registeroperand(op, RegClass_SPR, effect);
- break;
-
- case 'D':
- if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupDCRRegister(tkidentifier->name))) {
- op->type = IAOpnd_Imm;
- op->u.imm.value = reg->num;
- } else {
- immediateoperand(op, 0, 1023);
- }
- break;
-
- case 'Y':
- {
- SInt32 mask = 255;
- SInt32 i;
- if (ia->opcode == PC_MTCRF) {
- if (ia->args[0].type != IAOpnd_Imm)
- CError_Error(CErrorStr144);
- mask = ia->args[0].u.imm.value;
- }
- for (i = 0; i < 8; i++) {
- if ((0x80 >> i) & mask) {
- op->type = IAOpnd_Reg;
- op->u.reg.num = i;
- op->u.reg.rclass = RegClass_CRFIELD;
- op->u.reg.effect = effect;
- ia->argcount++;
- op++;
- }
- }
- ia->argcount--;
- op--;
- break;
- }
-
- case 'P':
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.object = NULL;
- if (format[1] == '3') {
- format++;
- op->u.reg.num = getimmediateoperand(0, 7);
- } else {
- op->u.reg.num = getimmediateoperand(0, 3);
- }
- op->u.reg.effect = effect;
- break;
-
- case 'C':
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.object = NULL;
- op->u.reg.num = 9;
- op->u.reg.effect = effect;
- break;
-
- case 'L':
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.object = NULL;
- op->u.reg.num = 8;
- op->u.reg.effect = effect;
- break;
-
- case 'X':
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_SPR;
- op->u.reg.object = NULL;
- op->u.reg.num = 1;
- op->u.reg.effect = effect;
- break;
-
- case 'Z':
- op->type = IAOpnd_Reg;
- op->u.reg.rclass = RegClass_CRFIELD;
- op->u.reg.object = NULL;
- t = info->flags & 0xC0000000;
- if (t == 0x40000000) {
- op->u.reg.num = 1;
- } else if (t == 0xC0000000) {
- op->u.reg.num = 6;
- } else {
- op->u.reg.num = 0;
- }
- op->u.reg.effect = effect;
- break;
-
- default:
- CError_FATAL(2266);
- }
-
- while (format[1] && strchr("/<>|*", format[1])) {
- int index;
- SInt32 value;
- SInt32 value2;
- IAOperand tmp;
- switch ((code = *(++format))) {
- case '/':
- index = -1;
- if (format[1] == '2') {
- index = -2;
- format++;
- }
-
- tmp = op[index];
- op[index] = op[0];
- op[0] = tmp;
- break;
- case '*':
- case '<':
- case '>':
- case '|':
- if (op->type == IAOpnd_Imm)
- value = op->u.imm.value;
- else if (op->type == IAOpnd_Reg)
- value = op->u.reg.num;
- else
- CError_FATAL(2312);
-
- if (format[1] == 'p') {
- format++;
- if (op[-1].type == IAOpnd_Imm)
- value2 = op[-1].u.imm.value;
- else if (op[-1].type == IAOpnd_Reg)
- value2 = op[-1].u.reg.num;
- else
- CError_FATAL(2322);
- } else if (isdigit(format[1])) {
- format += pcode_const_from_format(format + 1, &value2);
- } else {
- CError_FATAL(2327);
- }
-
- switch (code) {
- case '<':
- value = value2 - value;
- break;
- case '>':
- value = value - value2;
- break;
- case '|':
- value = value + value2;
- break;
- case '*':
- value = value * value2;
- break;
- default:
- CError_FATAL(2348);
- }
-
- if (op->type == IAOpnd_Imm)
- op->u.imm.value = value;
- else if (op->type == IAOpnd_Reg)
- op->u.reg.num = value;
- else
- CError_FATAL(2355);
- break;
- }
- }
-
- ia->argcount++;
- op++;
- if (format[1] == ']' || format[1] == ')')
- format++;
- }
-
- return ia;
-}
-
-static int mnemonic_has_overflow(char *buf) {
- int result = 0;
-
- if (buf[strlen(buf) - 1] == 'o') {
- if (!strcmp(buf, "bso"))
- return 0;
- if (!strcmp(buf, "fcmpo"))
- return 0;
- if (!strcmp(buf, "eieio"))
- return 0;
- if (!strcmp(buf, "vslo"))
- return 0;
- if (!strcmp(buf, "vsro"))
- return 0;
- result = 1;
- }
-
- return result;
-}
-
-static int mnemonic_has_absolute(const char *buf) {
- int result = 0;
- char last = buf[strlen(buf) - 1];
-
- if (buf[0] == 'b' && last == 'a')
- result = 1;
-
- return result;
-}
-
-static int mnemonic_has_linkregister(const char *buf) {
- int result = 0;
- char last = buf[strlen(buf) - 1];
-
- if (buf[0] == 'b' && last == 'l')
- result = 1;
-
- return result;
-}
-
-static int mnemonic_has_record(char *buf) {
- int result = 0;
-
- if (lookahead() == '.') {
- tk = lex();
- result = 1;
- strcat(buf, ".");
- }
-
- return result;
-}
-
-static void installregistervariables(void) {
-}
-
-void InlineAsm_InitializePPC(void) {
- Test_Version_Numbers();
- allow_array_expressions = 1;
- supports_hardware_fpu = 1;
- assembledinstructions = 0;
-
- switch (copts.processor) {
- case CPU_PPC401: cpu = CPUMask_401; break;
- case CPU_PPC403: cpu = CPUMask_403; break;
- case CPU_PPC505: cpu = CPUMask_50x; break;
- case CPU_PPC509: cpu = CPUMask_50x; break;
- case CPU_PPC555: cpu = CPUMask_55x_56x; break;
- case CPU_PPC556: cpu = CPUMask_55x_56x; break;
- case CPU_PPC565: cpu = CPUMask_55x_56x; break;
- case CPU_PPC601: cpu = CPUMask_601; break;
- case CPU_PPC602: cpu = CPUMask_602; break;
- case CPU_PPC8240: cpu = CPUMask_8240; break;
- case CPU_PPC8260: cpu = CPUMask_8260; break;
- case CPU_PPC603: cpu = CPUMask_603; break;
- case CPU_PPC603e: cpu = CPUMask_603; break;
- case CPU_PPC604: cpu = CPUMask_604; break;
- case CPU_PPC604e: cpu = CPUMask_604; break;
- case CPU_PPC740: cpu = CPUMask_740_750; break;
- case CPU_PPC750: cpu = CPUMask_740_750; break;
- case CPU_PPC801: cpu = CPUMask_801_821_860; break;
- case CPU_PPC821: cpu = CPUMask_801_821_860; break;
- case CPU_PPC823: cpu = CPUMask_823_850; break;
- case CPU_PPC850: cpu = CPUMask_823_850; break;
- case CPU_PPC860: cpu = CPUMask_801_821_860; break;
- case CPU_PPC7400: case CPU_PPC7450: cpu = CPUMask_74xx; break;
- case CPU_Generic: cpu = CPUMask_Generic; break;
- default:
- CError_FATAL(2613);
- }
-
- if (copts.altivec_model)
- cpu |= 0x40000000;
-}
-
-void InlineAsm_Initialize(AssemblerType assemblertype) {
- assembler_type = assemblertype;
-
- if (assembler_type == 0) {
- InlineAsm_InitializePPC();
- pic_base_reg = INVALID_PIC_REG;
- } else {
- pic_base_reg = 0;
- pic_base_label = NULL;
- }
-
- InlineAsm_InitializeMnemonicsPPC();
- InlineAsm_InitializeRegisters();
- InlineAsm_InitializeRegistersPPC();
-
- if (assembler_type == 0) {
- installregistervariables();
- } else {
- process_arguments(setup_assembly_argument, 0);
- assign_local_addresses();
- }
-}
-
-static IAEntryPoint *InlineAsm_CreateEntryPoint(HashNameNode *name, Boolean flag) {
- Object *obj;
- IAEntryPoint *ep;
- IALookupResult result;
-
- if (InlineAsm_LookupSymbol(name, &result) && (obj = result.object)) {
- if (!(obj->datatype == DFUNC && !(obj->flags & OBJECT_DEFINED)))
- CError_Error(CErrorStr122, name->name);
-
- obj->flags |= OBJECT_DEFINED;
- obj->sclass = flag ? TK_STATIC : TK_EXTERN;
-
- ep = lalloc(sizeof(IAEntryPoint));
- memclrw(ep, sizeof(IAEntryPoint));
- ep->x0 = IADirective_Entry;
- ep->x2 = 1;
- ep->x8 = obj;
- ep->size = assembledinstructions * 4;
- } else {
- CError_Error(CErrorStr140, name->name);
- }
-
- return ep;
-}
-
-static InlineAsm *InlineAsm_CreateFrFree(void) {
- InlineAsm *ia = lalloc(sizeof(InlineAsm));
- memclrw(ia, sizeof(InlineAsm));
- ia->opcode = IADirective_FrFree;
- ia->flags = IAFlag1;
- return ia;
-}
-
-SInt32 InlineAsm_IsDirective(AssemblerType assemblertype) {
- char *name;
- SInt32 directive = IADirective_Null;
-
- if (tk == '.')
- tk = lex();
-
- if (tk == TK_IDENTIFIER) {
- name = tkidentifier->name;
- if (!strcmp(name, "machine")) {
- directive = IADirective_Machine;
- } else if (assemblertype == AssemblerType_1) {
- if (!strcmp(name, "entry")) {
- directive = IADirective_Entry;
- } else if (!strcmp(name, "fralloc")) {
- directive = IADirective_FrAlloc;
- } else if (!strcmp(name, "nofralloc")) {
- directive = IADirective_NoFrAlloc;
- } else if (!strcmp(name, "frfree")) {
- directive = IADirective_FrFree;
- } else if (!strcmp(name, "smclass")) {
- directive = IADirective_SmClass;
- } else if (!strcmp(name, "picbase")) {
- directive = IADirective_PicBase;
- } else {
- directive = IADirective_Null;
- }
- }
- }
-
- return directive;
-}
-
-void InlineAsm_ProcessDirective(SInt32 directive) {
- Boolean flag;
- Statement *stmt;
- IAOperand op;
-
- switch (directive) {
- case IADirective_Entry:
- flag = 0;
- tk = lex();
- if (tk == TK_STATIC) {
- flag = 1;
- tk = lex();
- } else if (tk == TK_EXTERN) {
- tk = lex();
- }
-
- if (tk != TK_IDENTIFIER)
- CError_Error(CErrorStr107);
-
- stmt = CFunc_AppendStatement(ST_ASM);
- stmt->expr = NULL;
- stmt->expr = (ENode *) InlineAsm_CreateEntryPoint(tkidentifier, flag);
- stmt->sourceoffset = -1;
- tk = lex();
- break;
-
- case IADirective_FrAlloc:
- if (assembledinstructions)
- CError_Error(CErrorStr166);
- if (asm_alloc_flags[0])
- CError_Error(CErrorStr165);
- if (asm_alloc_flags[1] || asm_alloc_flags[2])
- CError_Error(CErrorStr166);
-
- tk = lex();
- if (tk != TK_EOL && tk != ';')
- fralloc_parameter_area_size = getimmediateoperand(0x20, 0x7FFE);
-
- requires_frame = 1;
- asm_alloc_flags[0] = 1;
- break;
-
- case IADirective_NoFrAlloc:
- if (asm_alloc_flags[0] || asm_alloc_flags[1])
- CError_Error(CErrorStr165);
- if (asm_alloc_flags[2])
- CError_Error(CErrorStr166);
- if (assembledinstructions)
- CError_Error(CErrorStr166);
- tk = lex();
-
- asm_alloc_flags[1] = 1;
- user_responsible_for_frame = 1;
- break;
-
- case IADirective_FrFree:
- if (asm_alloc_flags[1] || asm_alloc_flags[2])
- CError_Error(CErrorStr166);
-
- asm_alloc_flags[2] = 1;
- stmt = CFunc_AppendStatement(ST_ASM);
- stmt->expr = NULL;
- stmt->expr = (ENode *) InlineAsm_CreateFrFree();
- if (copts.filesyminfo)
- stmt->sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset);
- else
- stmt->sourceoffset = -1;
- tk = lex();
- break;
-
- case IADirective_Machine:
- tk = lex();
- if (tk == TK_INTCONST) {
- switch (tkintconst.lo) {
- case 401: cpu = CPUMask_401; break;
- case 403: cpu = CPUMask_403; break;
- case 505: cpu = CPUMask_50x; break;
- case 509: cpu = CPUMask_50x; break;
- case 555: cpu = CPUMask_55x_56x; break;
- case 556: cpu = CPUMask_55x_56x; break;
- case 565: cpu = CPUMask_55x_56x; break;
- case 601: cpu = CPUMask_601; break;
- case 602: cpu = CPUMask_602; break;
- case 8240: cpu = CPUMask_8240; break;
- case 8260: cpu = CPUMask_8260; break;
- case 603: cpu = CPUMask_603; break;
- case 604: cpu = CPUMask_604; break;
- case 740: cpu = CPUMask_740_750; break;
- case 750: cpu = CPUMask_740_750; break;
- case 801: cpu = CPUMask_801_821_860; break;
- case 821: cpu = CPUMask_801_821_860; break;
- case 823: cpu = CPUMask_823_850; break;
- case 850: cpu = CPUMask_823_850; break;
- case 860: cpu = CPUMask_801_821_860; break;
- case 7400: cpu = CPUMask_74xx; break;
- default:
- CError_Error(CErrorStr144);
- }
- } else if (tk == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "all")) {
- cpu = CPUMask_All;
- } else if (!strcmp(tkidentifier->name, "generic")) {
- cpu = CPUMask_Generic;
- } else if (!strcmp(tkidentifier->name, "603e")) {
- cpu = CPUMask_603;
- } else if (!strcmp(tkidentifier->name, "604e")) {
- cpu = CPUMask_604;
- } else if (!strcmp(tkidentifier->name, "PPC603e")) {
- cpu = CPUMask_603;
- } else if (!strcmp(tkidentifier->name, "PPC604e")) {
- cpu = CPUMask_604;
- } else if (!strcmp(tkidentifier->name, "altivec")) {
- cpu = CPUMask_74xx;
- } else {
- CError_Error(CErrorStr144);
- }
- } else {
- CError_Error(CErrorStr144);
- }
- tk = lex();
- break;
-
- case IADirective_SmClass:
- tk = lex();
- if (tk == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "PR"))
- sm_section = SECT_TEXT;
- else
- CError_Error(CErrorStr144);
- } else {
- CError_Error(CErrorStr144);
- }
- tk = lex();
- break;
-
- case IADirective_PicBase:
- tk = lex();
- registeroperand(&op, RegClass_GPR, EffectRead);
-
- if (!(op.type == IAOpnd_Reg && op.u.reg.object == NULL))
- CError_Error(CErrorStr144);
-
- tk = lex();
- if (tk == TK_IDENTIFIER) {
- savepicbase(op.u.reg.num, tkidentifier);
- tk = lex();
- } else {
- CError_Error(CErrorStr144);
- }
- break;
-
- default:
- CError_Error(CErrorStr261);
- }
-}
-
-void InlineAsm_ScanAssemblyDirective(void) {
- SInt32 directive;
-
- if ((directive = InlineAsm_IsDirective(assembler_type)) != IADirective_Null)
- InlineAsm_ProcessDirective(directive);
-}
-
-void InlineAsm_ScanAssemblyInstruction(void) {
- Statement *stmt;
- InlineAsm *ia;
- IAMnemonic *mnemonic;
- Boolean record_flag;
- Boolean flag3;
- Boolean flag4;
- Boolean flag5;
- Boolean flag1;
- Boolean flag2;
- SInt32 directive;
- OpcodeInfo *info;
- char buf[20];
-
- flag1 = 0;
- flag2 = 0;
- if ((directive = InlineAsm_IsDirective(assembler_type)) != IADirective_Null) {
- InlineAsm_ProcessDirective(directive);
- return;
- }
-
- stmt = CFunc_AppendStatement(ST_ASM);
- stmt->expr = NULL;
- if (copts.filesyminfo)
- stmt->sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset);
- else
- stmt->sourceoffset = -1;
-
- strncpy(buf, tkidentifier->name, sizeof(buf));
- record_flag = mnemonic_has_record(buf);
- mnemonic = InlineAsm_LookupMnemonicPPC(buf);
- if (!mnemonic)
- CError_Error(CErrorStr261);
-
- info = &opcodeinfo[mnemonic->x4];
- flag3 = (FLAG_SET_F(info->flags) & fCanSetCarry) && (mnemonic->x10 & 0x400);
- flag4 = (FLAG_SET_T(info->flags) & fCanBeAbsolute) && (mnemonic->x10 & 2);
- flag5 = (FLAG_SET_T(info->flags) & fCanLink) && (mnemonic->x10 & 1);
-
- if ((cpu == CPUMask_Generic) && (cpu & CPUFLAG_LOW_MASK) != ((cpu & mnemonic->cpu) & CPUFLAG_LOW_MASK)) {
- CError_Error(CErrorStr152);
- } else if (((cpu & mnemonic->cpu) & CPUFLAG_LOW_MASK) == 0) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_10000000) && !(cpu & CPUFLAG_10000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_8000000) && !(cpu & CPUFLAG_8000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_2000000) && !(cpu & CPUFLAG_2000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_4000000) && !(cpu & CPUFLAG_4000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_1000000) && !(cpu & CPUFLAG_1000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_40000000) && !(cpu & CPUFLAG_40000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_20000000) && !(cpu & CPUFLAG_20000000)) {
- CError_Error(CErrorStr152);
- } else if ((mnemonic->cpu & CPUFLAG_800000) && !(cpu & CPUFLAG_800000)) {
- CError_Error(CErrorStr152);
- }
-
- tk = lex();
- if (tk == '+' || tk == '-') {
- if (
- ((OPCODE_PART_1(mnemonic->x10) == 16) && (OPCODE_PART_2(mnemonic->x10) != 20)) ||
- ((OPCODE_PART_1(mnemonic->x10) == 19) && (OPCODE_PART_3(mnemonic->x10) == 528) && (OPCODE_PART_2(mnemonic->x10) != 20)) ||
- ((OPCODE_PART_1(mnemonic->x10) == 19) && (OPCODE_PART_3(mnemonic->x10) == 16) && (OPCODE_PART_2(mnemonic->x10) != 20))
- ) {
- if (tk == '+')
- flag1 = 1;
- else if (tk == '-')
- flag2 = 1;
- tk = lex();
- } else {
- CError_Error(CErrorStr120);
- }
- }
-
- stmt->expr = (ENode *) InlineAsm_ScanAssemblyOperands(mnemonic);
-
- ia = (InlineAsm *) stmt->expr;
- if (record_flag)
- ia->flags2 |= IAFlagsB_1;
- if (flag3)
- ia->flags2 |= IAFlagsB_2;
- if (flag4)
- ia->flags2 |= IAFlagsB_4;
- if (flag5)
- ia->flags2 |= IAFlagsB_8;
- if (flag1)
- ia->flags2 |= IAFlagsB_10;
- if (flag2)
- ia->flags2 |= IAFlagsB_20;
- if (volatileasm)
- ia->flags2 |= IAFlagsB_40;
-
- ++assembledinstructions;
-}
-
-static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, AssemblerType assemblertype) {
- PCode *pc;
- int index;
- int extra_args;
- int reg;
- int newargcount;
- SInt32 buffersize;
- IAOperand *src;
- PCodeArg *dest;
- OpcodeInfo *info;
-
- info = &opcodeinfo[ia->opcode];
- index = 0;
- extra_args = 0;
- reg = 0;
-
- if ((PCODE_FLAG_SET_F(info) & fCanSetRecordBit) && !(PCODE_FLAG_SET_F(info) & fRecordBit))
- extra_args++;
-
- if (!(PCODE_FLAG_SET_F(info) & fSetsCarry) && (PCODE_FLAG_SET_F(info) & fCanSetCarry))
- extra_args++;
-
- if (argcount < ia->argcount) {
- if ((argcount + extra_args) >= ia->argcount) {
- extra_args -= (ia->argcount - argcount);
- argcount = ia->argcount;
- } else {
- CError_FATAL(3317);
- }
- }
-
- if (ia->opcode == PC_B && ia->args[0].type == IAOpnd_Imm)
- ia->flags2 |= IAFlagsB_40;
-
- if (ia->opcode == PC_TWI || ia->opcode == PC_TW || ia->opcode == PC_TRAP || ia->opcode == PC_SC)
- ia->flags |= IAFlag2;
-
- if (ia->flags & IAFlag2) {
- newargcount = argcount + branch_count_volatiles();
- if (copts.exceptions && current_statement && assembler_type == 0)
- newargcount += countexceptionactionregisters(current_statement->dobjstack);
-
- buffersize = sizeof(PCode) + sizeof(PCodeArg) * (newargcount + extra_args);
- pc = lalloc(buffersize);
- memset(pc, 0, buffersize);
- pc->argCount = newargcount;
- } else if (ia->opcode == PC_STMW || ia->opcode == PC_LMW) {
- reg = ia->args[0].u.reg.object ? OBJECT_REG(ia->args[0].u.reg.object) : ia->args[0].u.reg.num;
- newargcount = argcount + (32 - reg);
-
- buffersize = sizeof(PCode) + sizeof(PCodeArg) * newargcount;
- pc = lalloc(buffersize);
- memset(pc, 0, buffersize);
- pc->argCount = newargcount;
- } else {
- buffersize = sizeof(PCode) + sizeof(PCodeArg) * (argcount + extra_args);
- pc = lalloc(buffersize);
- memset(pc, 0, buffersize);
- pc->argCount = (ia->argcount > argcount) ? ia->argcount : argcount;
- }
-
- pc->op = ia->opcode;
- pc->flags = info->flags;
- pc->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
-
- dest = pc->args;
- src = ia->args;
- argcount += extra_args;
- while (index < argcount) {
- if (index >= ia->argcount) {
- dest->kind = PCOp_PLACEHOLDEROPERAND;
- } else {
- switch (src->type) {
- case IAOpnd_0:
- dest->kind = PCOp_PLACEHOLDEROPERAND;
- break;
-
- case IAOpnd_Imm:
- dest->kind = PCOp_IMMEDIATE;
- dest->data.imm.value = src->u.imm.value;
- if (pc->flags & (fIsRead | fIsWrite))
- pc->flags |= fIsPtrOp;
- dest->data.imm.obj = NULL;
- break;
-
- case IAOpnd_Reg: {
- int r20;
- r20 = 0;
- if (src->u.reg.object) {
- if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag2) {
- if (src->u.reg.num == 1)
- r20 = OBJECT_REG_HI(src->u.reg.object);
- else
- r20 = OBJECT_REG(src->u.reg.object);
- } else {
- if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag40)
- PPCError_Error(PPCErrorStr172, src->u.reg.object->name->name);
- else
- PPCError_Error(PPCErrorStr167, src->u.reg.object->name->name);
- }
- } else if (src->u.reg.num == INVALID_PIC_REG) {
- r20 = pic_base_reg;
- } else {
- r20 = src->u.reg.num;
- }
-
- dest->kind = PCOp_REGISTER;
- dest->arg = src->u.reg.rclass;
- dest->data.reg.reg = r20;
- dest->data.reg.effect = src->u.reg.effect;
- if (pc->op == PC_RLWIMI && (dest->data.reg.effect & EffectWrite) && dest->arg == RegClass_GPR && !(dest->data.reg.effect & EffectRead))
- CError_FATAL(3442);
-
- if (dest->arg == RegClass_SPR) {
- int i;
- dest->kind = PCOp_SYSREG;
- for (i = 0; i < 4; i++) {
- if (dest->data.reg.reg == spr_to_sysreg[i]) {
- dest->kind = PCOp_REGISTER;
- dest->arg = RegClass_SPR;
- dest->data.reg.reg = i;
- break;
- }
- }
- pcsetsideeffects(pc);
- } else if (dest->arg == RegClass_6 || dest->arg == RegClass_DCR) {
- short save = dest->data.reg.reg;
- dest->kind = PCOp_IMMEDIATE;
- dest->data.imm.value = save;
- dest->data.imm.obj = NULL;
- break;
- }
-
- if ((src->u.reg.effect & EffectWrite) && dest->data.reg.reg < n_real_registers[dest->arg]) {
- if (src->u.reg.object) {
- if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag4) {
- int reg, regHi;
- CError_ASSERT(3474, dest->arg == RegClass_GPR);
-
- regHi = OBJECT_REG_HI(src->u.reg.object);
- reg = OBJECT_REG(src->u.reg.object);
- retain_GPR_pair(src->u.reg.object, reg, regHi);
- } else {
- retain_register(src->u.reg.object, dest->arg, dest->data.reg.reg);
- }
- } else {
- retain_register(NULL, dest->arg, dest->data.reg.reg);
- }
- }
-
- break;
- }
-
- case IAOpnd_Lab:
- if (!src->u.lab.label->pclabel)
- src->u.lab.label->pclabel = makepclabel();
- dest->kind = PCOp_LABEL;
- dest->data.label.label = src->u.lab.label->pclabel;
- break;
-
- case IAOpnd_3:
- case IAOpnd_4:
- dest->kind = PCOp_MEMORY;
- dest->arg = src->u.obj.unk;
- dest->data.mem.obj = src->u.obj.obj;
- dest->data.mem.offset = src->u.obj.offset;
- if (pc->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- pc->alias = make_alias(dest->data.mem.obj, dest->data.mem.offset, nbytes_loaded_or_stored_by(pc));
- if (is_volatile_object(dest->data.mem.obj))
- pc->flags |= fIsVolatile;
- if (OBJ_GET_TARGET_CONST(dest->data.mem.obj))
- pc->flags |= fIsConst;
- }
- break;
-
- case IAOpnd_LabDiff:
- if (src->u.labdiff.label1->pclabel == NULL)
- src->u.labdiff.label1->pclabel = makepclabel();
- if (src->u.labdiff.label2->pclabel == NULL)
- src->u.labdiff.label2->pclabel = makepclabel();
- if (pc->flags & (fIsRead | fIsWrite))
- pc->flags |= fIsPtrOp;
- dest->kind = PCOp_LABELDIFF;
- dest->data.labeldiff.labelA = src->u.labdiff.label1->pclabel;
- dest->data.labeldiff.labelB = src->u.labdiff.label2->pclabel;
- dest->arg = src->negated;
- dest->data.labeldiff.offset = src->u.labdiff.offset;
- break;
-
- default:
- CError_FATAL(3528);
- }
- }
-
- index++;
- dest++;
- src++;
- }
-
- if (ia->opcode == PC_STMW || ia->opcode == PC_LMW) {
- int i;
- for (i = reg; i < 32; i++, dest++) {
- dest->kind = PCOp_REGISTER;
- dest->arg = RegClass_GPR;
- dest->data.reg.reg = i;
- dest->data.reg.effect = ((ia->opcode == PC_LMW) ? EffectWrite : EffectRead);
- }
- }
-
- if (ia->flags & IAFlag2) {
- UInt32 masks[5] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
- branch_record_volatiles(dest, masks);
- if (copts.exceptions && current_statement && assembler_type == 0)
- noteexceptionactionregisters(current_statement->dobjstack, dest);
- }
-
- return pc;
-}
-
-void InlineAsm_TranslateIRtoPCode(Statement *stmt) {
- InlineAsm *ia;
- PCode *pc;
-
- ia = (InlineAsm *) stmt->expr;
- pc = InlineAsm_TranslateIRtoPCodePPC(ia, opcodeinfo[ia->opcode].x8, assembler_type);
- appendpcode(pclastblock, pc);
-
- if ((ia->flags2 & IAFlagsB_40) || !copts.optimizewithasm)
- setpcodeflags(fSideEffects);
-
- if (ia->flags2 & IAFlagsB_1) {
- if (PCODE_FLAG_SET_F(pc) & fCanSetRecordBit)
- pcsetrecordbit(pclastblock->lastPCode);
- else
- CError_Error(CErrorStr261);
- }
-
- if (ia->flags2 & IAFlagsB_2) {
- if (PCODE_FLAG_SET_F(pc) & fCanSetCarry)
- setpcodeflags(fOverflow); // idk?
- else
- CError_Error(CErrorStr261);
- }
-
- if (ia->flags2 & IAFlagsB_4) {
- if (PCODE_FLAG_SET_T(pc) & fCanBeAbsolute) {
- int i;
- for (i = 0; i < pc->argCount; i++) {
- if (pc->args[i].kind == PCOp_LABEL || pc->args[i].kind == PCOp_MEMORY) {
- PPCError_Error(PPCErrorStr177);
- break;
- }
- }
- setpcodeflags(fAbsolute);
- } else {
- CError_Error(CErrorStr261);
- }
- }
-
- if (ia->flags2 & IAFlagsB_8) {
- if (PCODE_FLAG_SET_T(pc) & fCanLink) {
- pcsetlinkbit(pclastblock->lastPCode);
- if (!(ia->flags & IAFlag2)) {
- pclastblock->lastPCode->flags &= ~fIsCall;
- pclastblock->lastPCode->flags |= fIsBranch;
- }
- makes_call = 1;
- } else {
- CError_Error(CErrorStr261);
- }
- }
-
- if (ia->flags2 & IAFlagsB_10)
- setpcodeflags(fCanSetRecordBit);
- if (ia->flags2 & IAFlagsB_20)
- setpcodeflags(fCanSetCarry);
-
- if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 16) {
- PCodeLabel *dest = NULL;
- PCodeLabel *src = makepclabel();
- switch (pc->op) {
- case PC_BC:
- if (pc->args[3].kind == PCOp_LABEL)
- dest = pc->args[3].data.label.label;
- break;
- case PC_BT:
- case PC_BF:
- case PC_BDNZT:
- case PC_BDNZF:
- case PC_BDZT:
- case PC_BDZF:
- if (pc->args[2].kind == PCOp_LABEL)
- dest = pc->args[2].data.label.label;
- break;
- case PC_BDNZ:
- case PC_BDZ:
- if (pc->args[0].kind == PCOp_LABEL)
- dest = pc->args[0].data.label.label;
- break;
- default:
- CError_FATAL(3715);
- }
-
- if (dest) {
- pcbranch(pclastblock, dest);
- pcbranch(pclastblock, src);
- makepcblock();
- pclabel(pclastblock, src);
- }
- return;
- }
-
- if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 18) {
- PCodeLabel *label;
- if (ia->flags2 & IAFlagsB_8) {
- label = makepclabel();
- pcbranch(pclastblock, label);
- }
- if (pc->args[0].kind == PCOp_LABEL)
- pcbranch(pclastblock, pc->args[0].data.label.label);
- makepcblock();
- if (ia->flags2 & IAFlagsB_8) {
- pclabel(pclastblock, label);
- }
- return;
- }
-
- if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 19) {
- switch (pc->op) {
- case PC_BLR:
- case PC_RFI:
- if (asm_alloc_flags[3])
- asm_alloc_flags[9] = 1;
- else
- asm_alloc_flags[8] = 1;
-
- if (asm_alloc_flags[4])
- asm_alloc_flags[5] = 1;
-
- if (pc->op == PC_BLR)
- asm_alloc_flags[6] = 1;
- else
- asm_alloc_flags[7] = 1;
- break;
- }
- }
-}
-
-const char *InlineAsm_GetMnemonic(InlineAsm *ia) {
- return opcodeinfo[ia->opcode].name;
-}
-
-static void savepicbase(short reg, HashNameNode *name) {
- IALookupResult result;
-
- if (!InlineAsm_LookupSymbol(name, &result))
- result.label = InlineAsm_DeclareLabel(name);
-
- pic_base_label = result.label;
- pic_base_reg = reg;
- uses_globals = 1;
-}
-
-static SInt32 InlineAsm_OpcodeSize(InlineAsm *ia) {
- if (opcodeinfo[ia->opcode].flags & (fIsRead | fIsWrite)) {
- switch (ia->opcode) {
- case PC_LBZ:
- case PC_LBZU:
- case PC_LBZX:
- case PC_LBZUX:
- case PC_STB:
- case PC_STBU:
- case PC_STBX:
- case PC_STBUX:
- return 1;
- case PC_LHZ:
- case PC_LHZU:
- case PC_LHZX:
- case PC_LHZUX:
- case PC_LHA:
- case PC_LHAU:
- case PC_LHAX:
- case PC_LHAUX:
- case PC_LHBRX:
- case PC_STH:
- case PC_STHU:
- case PC_STHX:
- case PC_STHUX:
- case PC_STHBRX:
- return 2;
- case PC_LWZ:
- case PC_LWZU:
- case PC_LWZX:
- case PC_LWZUX:
- case PC_LWBRX:
- case PC_STW:
- case PC_STWU:
- case PC_STWX:
- case PC_STWUX:
- case PC_STWBRX:
- case PC_LFS:
- case PC_LFSU:
- case PC_LFSX:
- case PC_LFSUX:
- case PC_STFS:
- case PC_STFSU:
- case PC_STFSX:
- case PC_STFSUX:
- case PC_LWARX:
- case PC_STFIWX:
- case PC_STWCX:
- case PC_ECIWX:
- case PC_ECOWX:
- case PC_MFROM:
- case PC_LSCBX:
- return 4;
- case PC_LMW:
- case PC_STMW:
- if (ia->args[0].type == IAOpnd_Reg && ia->args[0].u.reg.object == NULL)
- return (32 - ia->args[0].u.reg.num) * 4;
- else
- return 128;
- case PC_LFD:
- case PC_LFDU:
- case PC_LFDX:
- case PC_LFDUX:
- case PC_STFD:
- case PC_STFDU:
- case PC_STFDX:
- case PC_STFDUX:
- return 8;
- case PC_LSWI:
- case PC_STSWI:
- return ia->args[2].u.imm.value;
- case PC_LSWX:
- case PC_STSWX:
- return 128;
- case PC_LVEBX:
- case PC_STVEBX:
- return 1;
- case PC_LVEHX:
- case PC_STVEHX:
- return 2;
- case PC_LVEWX:
- case PC_STVEWX:
- return 4;
- case PC_LVSL:
- case PC_LVSR:
- case PC_LVX:
- case PC_LVXL:
- case PC_STVX:
- case PC_STVXL:
- return 16;
- default:
- CError_FATAL(3924);
- }
- } else {
- if (opcodeinfo[ia->opcode].flags & fOpTypeGPR)
- return 4;
- if (opcodeinfo[ia->opcode].flags & fOpTypeFPR)
- return 8;
- if (opcodeinfo[ia->opcode].flags & fOpTypeVR)
- return 16;
-
- if (opcodeinfo[ia->opcode].flags & fSideEffects) {
- switch (ia->opcode) {
- case PC_TLBIE:
- case PC_TLBLD:
- case PC_TLBLI:
- return 4;
- default:
- CError_FATAL(3941);
- }
- }
- }
-
- CError_FATAL(3944);
- return 0;
-}
-
-void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) {
- InlineAsm *ia;
- OpcodeInfo *info;
- int i;
- IAOperand *op;
- VarInfo *vi;
-
- ia = (InlineAsm *) stmt->expr;
- info = &opcodeinfo[ia->opcode];
-
- effects->numoperands = 0;
- effects->numlabels = 0;
- effects->x1 = 0;
- effects->x2 = 0;
- effects->x3 = 0;
- effects->x4 = 0;
- effects->x0 = 0;
- effects->x5 = 0;
-
- if (info->flags & fIsPtrOp) {
- if (info->flags & fIsRead)
- effects->x1 = 1;
- if (info->flags & fIsWrite)
- effects->x2 = 1;
- }
-
- if (PCODE_FLAG_SET_T(info) & fCanLink) {
- if (ia->flags2 & IAFlagsB_8)
- effects->x4 = 1;
- else if ((info->flags & fIsCall) || (info->flags & fIsWrite))
- effects->x3 = 1;
-
- if (ia->opcode == PC_B) {
- if (ia->args[0].type == IAOpnd_Imm)
- effects->x0 = 1;
- effects->x5 = 1;
- }
- }
-
- if (info->flags & fSideEffects)
- effects->x0 = 1;
-
- if (ia->opcode == PC_BC && (ia->flags2 & IAFlagsB_8))
- effects->x4 = 1;
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_0:
- case IAOpnd_Imm:
- break;
- case IAOpnd_Reg:
- if (op->u.reg.object) {
- if ((vi = Registers_GetVarInfo(op->u.reg.object)))
- vi->flags |= VarInfoFlag40;
- if (op->u.reg.effect & EffectRead) {
- if (
- TYPE_FITS_IN_REGISTER(op->u.reg.object->type) ||
- IS_TYPE_FLOAT(op->u.reg.object->type) ||
- IS_TYPE_VECTOR(op->u.reg.object->type)
- ) {
- effects->operands[effects->numoperands].type = IAEffect_0;
- effects->operands[effects->numoperands].object = op->u.reg.object;
- effects->operands[effects->numoperands].offset = 0;
- effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
- effects->numoperands++;
- } else {
- CError_FATAL(4051);
- }
- }
- }
- break;
- case IAOpnd_3:
- case IAOpnd_4:
- if (op->u.obj.obj) {
- if (info->flags & fIsRead) {
- effects->operands[effects->numoperands].type = IAEffect_0;
- effects->operands[effects->numoperands].object = op->u.obj.obj;
- effects->operands[effects->numoperands].offset = op->u.obj.offset;
- effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia);
- effects->numoperands++;
- } else if (!(info->flags & (fIsBranch | fIsCall))) {
- effects->operands[effects->numoperands].type = IAEffect_3;
- effects->operands[effects->numoperands].object = op->u.obj.obj;
- effects->operands[effects->numoperands].offset = op->u.obj.offset;
- effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia);
- effects->numoperands++;
- }
- }
- break;
- case IAOpnd_Lab:
- effects->labels[effects->numlabels] = op->u.lab.label;
- effects->numlabels++;
- break;
- case IAOpnd_LabDiff:
- effects->labels[effects->numlabels] = op->u.labdiff.label1;
- effects->numlabels++;
- effects->labels[effects->numlabels] = op->u.labdiff.label2;
- effects->numlabels++;
- effects->x3 = 1;
- break;
- default:
- CError_FATAL(4087);
- }
-
- CError_ASSERT(4090, (UInt32) effects->numoperands <= IAMaxOperands);
- CError_ASSERT(4093, (UInt32) effects->numlabels <= IAMaxLabels);
- }
-
- for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
- switch (op->type) {
- case IAOpnd_Reg:
- if (op->u.reg.object) {
- if ((vi = Registers_GetVarInfo(op->u.reg.object)))
- vi->flags |= VarInfoFlag40;
- if (op->u.reg.effect & EffectWrite) {
- if (
- TYPE_FITS_IN_REGISTER(op->u.reg.object->type) ||
- IS_TYPE_FLOAT(op->u.reg.object->type) ||
- IS_TYPE_VECTOR(op->u.reg.object->type)
- ) {
- effects->operands[effects->numoperands].type = IAEffect_1;
- effects->operands[effects->numoperands].object = op->u.reg.object;
- effects->operands[effects->numoperands].offset = 0;
- effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
- effects->numoperands++;
- } else {
- CError_FATAL(4132);
- }
- }
- }
- break;
- case IAOpnd_3:
- case IAOpnd_4:
- if (op->u.obj.obj) {
- if (info->flags & fIsWrite) {
- effects->operands[effects->numoperands].type = IAEffect_1;
- effects->operands[effects->numoperands].object = op->u.obj.obj;
- effects->operands[effects->numoperands].offset = op->u.obj.offset;
- effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia);
- effects->numoperands++;
- }
- }
- break;
- }
-
- CError_ASSERT(4151, (UInt32) effects->numoperands <= IAMaxOperands);
- }
-
- if ((info->flags & (fIsBranch | fIsCall)) && (SInt32)effects->numlabels == 0)
- effects->x3 = 1;
-}
-
-void CodeGen_PropagateIntoAsm(Statement *stmt, Object *obj, ENode *expr) {
- InlineAsm *ia;
- Object *newobj;
-
- ia = (InlineAsm *) stmt->expr;
- if (ENODE_IS(expr, EOBJREF)) {
- newobj = expr->data.objref;
- if (obj->otype == newobj->otype && obj->datatype == newobj->datatype) {
- int i;
- for (i = 0; i < ia->argcount; i++) {
- switch (ia->args[i].type) {
- case IAOpnd_Reg:
- if (ia->args[i].u.reg.object == obj &&
- (ia->args[i].u.reg.effect & (EffectRead | EffectWrite)) == EffectRead) {
- if (TYPE_FITS_IN_REGISTER(newobj->type) &&
- ia->args[i].u.reg.rclass == RegClass_GPR) {
- ia->args[i].u.reg.object = newobj;
- } else if (IS_TYPE_FLOAT(newobj->type) &&
- ia->args[i].u.reg.rclass == RegClass_FPR) {
- ia->args[i].u.reg.object = newobj;
- } else if (IS_TYPE_VECTOR(newobj->type) &&
- ia->args[i].u.reg.rclass == RegClass_VR) {
- ia->args[i].u.reg.object = newobj;
- }
- }
- break;
- case IAOpnd_3:
- case IAOpnd_4:
- if (!(opcodeinfo[ia->opcode].flags & (fIsWrite | fPCodeFlag40000)) &&
- ia->args[i].u.obj.obj == obj)
- ia->args[i].u.obj.obj = newobj;
- break;
- }
- }
- }
- }
-}
-
-Statement *CodeGen_CopyAsmStat(Statement *stmt) {
- Statement *copy;
- SInt32 size;
- InlineAsm *ia;
- InlineAsm *iacopy;
-
- copy = galloc(sizeof(Statement));
- *copy = *stmt;
-
- ia = (InlineAsm *) stmt->expr;
- size = sizeof(InlineAsm) + sizeof(IAOperand) * ia->argcount;
- iacopy = galloc(size);
- memcpy(iacopy, ia, size);
- copy->expr = (ENode *) iacopy;
-
- return copy;
-}
-
diff --git a/compiler_and_linker/unsorted/InstrSelection.c b/compiler_and_linker/unsorted/InstrSelection.c
deleted file mode 100644
index 359c980..0000000
--- a/compiler_and_linker/unsorted/InstrSelection.c
+++ /dev/null
@@ -1,5348 +0,0 @@
-#include "compiler/InstrSelection.h"
-#include "compiler/CError.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/FunctionCalls.h"
-#include "compiler/Intrinsics.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StructMoves.h"
-#include "compiler/TOC.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-PrecomputedOperand *precomputedoperands;
-void (*cgdispatch[MAXEXPR + 1])(ENode *, short, short, Operand *);
-
-// forward decls
-static int ispowerof2(SInt32 val);
-static void binary_immediate(Opcode opcode, ENode *left, SInt32 value, short outputReg, Operand *output);
-static void shift_left_immediate(ENode *expr, short shift, short negate, short outputReg, Operand *output);
-static void shift_right_immediate(ENode *expr, Type *type, short shift, short outputReg, Operand *output);
-static void or_xor_immediate(Opcode opcode, ENode *expr, SInt32 value, short outputReg, Operand *output);
-static void signed_divide_by_power_of_2(ENode *expr, int shift, int negate, short outputReg, Operand *output);
-static void signed_mod_by_power_of_2(ENode *expr, int shift, int negate, short outputReg, Operand *output);
-static void fp_binary_operator(Opcode opcode, ENode *left, ENode *right, short outputReg, Operand *output);
-static void logical_expression_nobranch(ENode *cond, Boolean invert, Operand *output);
-static void shift_and_mask(ENode *expr, short a, short b, short c, short outputReg, Operand *output);
-static ENodeType invert_relop(ENodeType nt);
-
-#define IS_INT_CONST(node) ( ENODE_IS((node), EINTCONST) && IS_TYPE_INT((node)->rtype) && (node)->rtype->size <= 4 )
-#define IS_INT_CONST_ZERO(node) ( IS_INT_CONST(node) && (node)->data.intval.lo == 0 )
-
-void init_cgdispatch(void) {
- ENodeType t;
-
- for (t = 0; t <= MAXEXPR; t++)
- cgdispatch[t] = gen_UNEXPECTED;
-
- cgdispatch[EPOSTINC] = gen_POSTINCDEC;
- cgdispatch[EPOSTDEC] = gen_POSTINCDEC;
- cgdispatch[EINDIRECT] = gen_INDIRECT;
- cgdispatch[EMONMIN] = gen_MONMIN;
- cgdispatch[EBINNOT] = gen_BINNOT;
- cgdispatch[ELOGNOT] = gen_LOGICAL;
- cgdispatch[EFORCELOAD] = gen_FORCELOAD;
- cgdispatch[EMUL] = gen_MUL;
- cgdispatch[EDIV] = gen_DIV;
- cgdispatch[EMODULO] = gen_MODULO;
- cgdispatch[EADD] = gen_ADD;
- cgdispatch[ESUB] = gen_SUB;
- cgdispatch[ESHL] = gen_SHL;
- cgdispatch[ESHR] = gen_SHR;
- cgdispatch[ELESS] = gen_COMPARE;
- cgdispatch[EGREATER] = gen_COMPARE;
- cgdispatch[ELESSEQU] = gen_COMPARE;
- cgdispatch[EGREATEREQU] = gen_COMPARE;
- cgdispatch[EEQU] = gen_COMPARE;
- cgdispatch[ENOTEQU] = gen_COMPARE;
- cgdispatch[EAND] = gen_AND;
- cgdispatch[EXOR] = gen_XOR;
- cgdispatch[EOR] = gen_OR;
- cgdispatch[ELAND] = gen_LOGICAL;
- cgdispatch[ELOR] = gen_LOGICAL;
- cgdispatch[EASS] = gen_ASS;
- cgdispatch[ECOMMA] = gen_COMMA;
- cgdispatch[ETYPCON] = gen_TYPCON;
- cgdispatch[EBITFIELD] = gen_BITFIELD;
- cgdispatch[EINTCONST] = gen_INTCONST;
- cgdispatch[EFLOATCONST] = gen_FLOATCONST;
- cgdispatch[ESTRINGCONST] = gen_STRINGCONST;
- cgdispatch[ECOND] = gen_COND;
- cgdispatch[EFUNCCALL] = gen_FUNCCALL;
- cgdispatch[EFUNCCALLP] = gen_FUNCCALL;
- cgdispatch[EOBJREF] = gen_OBJREF;
- cgdispatch[ENULLCHECK] = gen_NULLCHECK;
- cgdispatch[EPRECOMP] = gen_PRECOMP;
- cgdispatch[EDEFINE] = gen_DEFINE;
- cgdispatch[EREUSE] = gen_REUSE;
- cgdispatch[EVECTOR128CONST] = gen_VECTOR128CONST;
- cgdispatch[ECONDASS] = gen_CONDASS;
-}
-
-void gen_DEFINE(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Operand *op;
-
- if (!expr->data.diadic.right) {
- op = lalloc(sizeof(Operand));
- memclrw(op, sizeof(Operand));
- expr->data.diadic.right = (ENode *) op;
- GEN_NODE(expr->data.diadic.left, op);
- }
-
- op = (Operand *) expr->data.diadic.right;
- *output = *op;
-}
-
-void gen_REUSE(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner = expr->data.monadic;
- CError_ASSERT(250, ENODE_IS(inner, EDEFINE));
- gen_DEFINE(inner, outputReg, outputRegHi, output);
-}
-
-void gen_POSTINCDEC(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- TypeBitfield *tbitfield;
- ENode *inner;
- Type *type;
- Operand a;
- Operand b;
- Operand c;
- Float fval;
- int objReg;
- int constReg;
- int finalReg;
- SInt32 incval;
-
- inner = expr->data.monadic->data.monadic;
- type = expr->rtype;
- tbitfield = NULL;
-
- memclrw(&a, sizeof(Operand));
- memclrw(&b, sizeof(Operand));
- memclrw(&c, sizeof(Operand));
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_POSTINCDEC(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- if (ENODE_IS(inner, EOBJREF) && (objReg = OBJECT_REG(inner->data.objref))) {
- output->optype = OpndType_FPR;
- output->reg = (outputReg && outputReg != objReg) ? outputReg : ALLOC_FPR();
- emitpcode(PC_FMR, output->reg, objReg);
- fval = one_point_zero;
- load_floating_constant(constReg = ALLOC_FPR(), type, &fval);
-
- if (ENODE_IS(expr, EPOSTINC)) {
- emitpcode((type->size == 4) ? PC_FADDS : PC_FADD, objReg, objReg, constReg);
- } else {
- emitpcode((type->size == 4) ? PC_FSUBS : PC_FSUB, objReg, objReg, constReg);
- }
- } else {
- GEN_NODE(inner, &a);
- indirect(&a, inner);
- b = a;
- ENSURE_FPR(&b, type, 0);
-
- output->optype = OpndType_FPR;
- output->reg = ALLOC_FPR();
- emitpcode(PC_FMR, output->reg, b.reg);
-
- fval = one_point_zero;
- load_floating_constant(constReg = ALLOC_FPR(), type, &fval);
-
- finalReg = ALLOC_FPR();
- if (ENODE_IS(expr, EPOSTINC))
- emitpcode((type->size == 4) ? PC_FADDS : PC_FADD, finalReg, b.reg, constReg);
- else
- emitpcode((type->size == 4) ? PC_FSUBS : PC_FSUB, finalReg, b.reg, constReg);
-
- store_fp(finalReg, &a, type);
- }
- } else {
- if (IS_TYPE_POINTER(type)) {
- if (ENODE_IS(expr, EPOSTINC))
- incval = TPTR_TARGET(type)->size;
- else
- incval = -TPTR_TARGET(type)->size;
- } else {
- if (ENODE_IS(expr, EPOSTINC))
- incval = 1;
- else
- incval = -1;
- }
-
- if (ENODE_IS(inner, EOBJREF) && (objReg = OBJECT_REG(inner->data.objref))) {
- output->optype = OpndType_GPR;
- output->reg = (outputReg && outputReg != objReg) ? outputReg : ALLOC_GPR();
- emitpcode(PC_MR, output->reg, objReg);
- add_register_immediate(objReg, objReg, incval);
- } else {
- if (ENODE_IS(inner, EBITFIELD)) {
- tbitfield = TYPE_BITFIELD(TPTR_TARGET(inner));
- inner = inner->data.monadic;
- }
- GEN_NODE(inner, &a);
- indirect(&a, inner);
- b = a;
- ENSURE_GPR(&b, type, 0);
-
- if (tbitfield) {
- c = b;
- extract_bitfield(&c, tbitfield, 0, &b);
- }
- output->optype = OpndType_GPR;
-
- output->reg = ALLOC_GPR();
- emitpcode(PC_MR, output->reg, b.reg);
-
- finalReg = ALLOC_GPR();
- add_register_immediate(finalReg, b.reg, incval);
-
- if (tbitfield) {
- insert_bitfield(finalReg, &c, tbitfield);
- finalReg = c.reg;
- }
-
- store(finalReg, &a, type);
- }
- }
-}
-
-void gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *inner;
- VarInfo *vi;
- SInt32 postincvalue;
- Operand op;
-
- type = expr->rtype;
- inner = expr->data.monadic;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_INDIRECT(expr, outputReg, outputRegHi, output);
- return;
- }
-
- memclrw(&op, sizeof(Operand));
- if (ENODE_IS(inner, EOBJREF) && OBJECT_REG(inner->data.objref)) {
- vi = Registers_GetVarInfo(inner->data.objref);
- switch (vi->rclass) {
- case RegClass_GPR:
- output->optype = OpndType_GPR;
- break;
- case RegClass_FPR:
- output->optype = OpndType_FPR;
- break;
- case RegClass_VR:
- output->optype = OpndType_VR;
- break;
- case RegClass_CRFIELD:
- output->optype = OpndType_CRField;
- break;
- default:
- CError_FATAL(456);
- }
- output->reg = vi->reg;
- output->object = NULL;
- return;
- }
-
- if (ENODE_IS(inner, EBITFIELD)) {
- GEN_NODE(inner->data.monadic, &op);
- indirect(&op, expr);
- ENSURE_GPR(&op, type, 0);
- extract_bitfield(&op, TYPE_BITFIELD(inner->rtype), outputReg, output);
- return;
- }
-
- if (ispostincrementopportunity(inner, &op, &postincvalue) && (TYPE_FITS_IN_REGISTER(type) || IS_TYPE_FLOAT(type) || IS_TYPE_VECTOR(type))) {
- indirect(&op, expr);
- *output = op;
- if (TYPE_FITS_IN_REGISTER(type)) {
- ENSURE_GPR(output, type, outputReg);
- } else if (IS_TYPE_FLOAT(type)) {
- ENSURE_FPR(output, type, outputReg);
- } else {
- ENSURE_VR(output, type, outputReg);
- }
-
- add_register_immediate(op.reg, op.reg, postincvalue);
- return;
- }
-
- GEN_NODE(inner, output);
- indirect(output, expr);
-}
-
-void gen_MONMIN(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Type *type;
- ENode *scan;
-
- inner = expr->data.monadic;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_MONMIN(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- if (ENODE_IS(inner, EADD) && ENODE_IS(inner->data.diadic.left, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FNMADDS : PC_FNMADD,
- inner->data.diadic.left->data.diadic.left,
- inner->data.diadic.left->data.diadic.right,
- inner->data.diadic.right,
- outputReg,
- output);
- } else if (ENODE_IS(inner, EADD) && ENODE_IS(inner->data.diadic.right, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FNMADDS : PC_FNMADD,
- inner->data.diadic.right->data.diadic.left,
- inner->data.diadic.right->data.diadic.right,
- inner->data.diadic.left,
- outputReg,
- output);
- } else if (ENODE_IS(inner, ESUB) && ENODE_IS(inner->data.diadic.left, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FNMSUBS : PC_FNMSUB,
- inner->data.diadic.left->data.diadic.left,
- inner->data.diadic.left->data.diadic.right,
- inner->data.diadic.right,
- outputReg,
- output);
- } else {
- fp_unary_operator(PC_FNEG, inner, outputReg, output);
- }
- return;
- }
-
- scan = inner;
- while (ENODE_IS(scan, ETYPCON) && IS_TYPE_INT_OR_ENUM(type) && !is_unsigned(type))
- scan = scan->data.monadic;
-
- switch (scan->type) {
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- if (TYPE_FITS_IN_REGISTER(scan->data.diadic.left->rtype) && TYPE_FITS_IN_REGISTER(scan->data.diadic.right->rtype)) {
- gen_negated_condition_gpr(scan, output, outputReg);
- return;
- }
- }
- unary_operator(PC_NEG, inner, outputReg, output);
-}
-
-void gen_BINNOT(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Type *type;
-
- inner = expr->data.monadic;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_BINNOT(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(inner, EAND))
- binary_operator(PC_NAND, inner->data.diadic.left, inner->data.diadic.right, outputReg, output);
- else if (ENODE_IS(inner, EOR))
- binary_operator(PC_NOR, inner->data.diadic.left, inner->data.diadic.right, outputReg, output);
- else if (ENODE_IS(inner, EXOR))
- binary_operator(PC_EQV, inner->data.diadic.left, inner->data.diadic.right, outputReg, output);
- else
- unary_operator(PC_NOT, inner, outputReg, output);
-}
-
-void gen_FORCELOAD(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
-
- inner = expr->data.monadic;
- GEN_NODE(inner, output);
-
- if (IS_TYPE_FLOAT(inner->rtype)) {
- ENSURE_FPR(output, inner->rtype, outputReg);
- } else if (IS_TYPE_VECTOR(inner->rtype)) {
- ENSURE_VR(output, inner->rtype, outputReg);
- } else if (TYPE_FITS_IN_REGISTER(inner->rtype)) {
- if (TYPE_IS_8BYTES(inner->rtype))
- coerce_to_register_pair(output, inner->rtype, outputReg, outputRegHi);
- else
- ENSURE_GPR(output, inner->rtype, outputReg);
- } else if (!IS_TYPE_VOID(inner->rtype)) {
- CError_FATAL(681);
- }
-}
-
-void gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- Type *type;
- int tmp;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_MUL(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- fp_binary_operator((type->size == 4) ? PC_FMULS : PC_FMUL, left, right, outputReg, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(right->data.intval.lo))) {
- shift_left_immediate(left, tmp, 0, outputReg, output);
- } else if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(-right->data.intval.lo))) {
- shift_left_immediate(left, tmp, 1, outputReg, output);
- } else if (ENODE_IS(left, EINTCONST) && (tmp = ispowerof2(left->data.intval.lo))) {
- shift_left_immediate(right, tmp, 0, outputReg, output);
- } else if (ENODE_IS(left, EINTCONST) && (tmp = ispowerof2(-left->data.intval.lo))) {
- shift_left_immediate(right, tmp, 1, outputReg, output);
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT(right->data.intval.lo)) {
- binary_immediate(PC_MULLI, left, right->data.intval.lo, outputReg, output);
- } else if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT(left->data.intval.lo)) {
- binary_immediate(PC_MULLI, right, left->data.intval.lo, outputReg, output);
- } else {
- binary_operator(PC_MULLW, left, right, outputReg, output);
- }
-}
-
-struct ms {
- SInt32 m;
- int s;
-};
-static void create_signed_magic(SInt32 val, struct ms *output) {
- // PowerPC CWG page 57-58
- int p;
- UInt32 ad, anc, delta, q1, r1, q2, r2, t;
-
- ad = abs(val);
- t = 0x80000000U + ((UInt32) val >> 31);
- anc = t - 1 - t % ad;
- p = 31;
- q1 = 0x80000000U / anc;
- r1 = 0x80000000U - q1 * anc;
- q2 = 0x80000000U / ad;
- r2 = 0x80000000U - q2 * ad;
-
- do {
- p = p + 1;
- q1 = 2 * q1;
- r1 = 2 * r1;
- if (r1 >= anc) {
- q1 = q1 + 1;
- r1 = r1 - anc;
- }
- q2 = 2 * q2;
- r2 = 2 * r2;
- if (r2 >= ad) {
- q2 = q2 + 1;
- r2 = r2 - ad;
- }
- delta = ad - r2;
- } while (q1 < delta || (q1 == delta && r1 == 0));
-
- // after loop
- output->m = q2 + 1;
- if (val < 0)
- output->m = -output->m;
- output->s = p - 32;
-}
-
-struct mu {
- UInt32 m;
- int a;
- int s;
-};
-static void create_unsigned_magic(UInt32 val, struct mu *output) {
- // PowerPC CWG page 58-59
- int p;
- UInt32 nc, delta, q1, r1, q2, r2;
-
- output->a = 0;
- nc = - 1 - (-val) % val;
- p = 31;
- q1 = 0x80000000U / nc;
- r1 = 0x80000000U - q1 * nc;
- q2 = 0x7FFFFFFFU / val;
- r2 = 0x7FFFFFFFU - q2 * val;
- do {
- p = p + 1;
- if (r1 >= nc - r1) {
- q1 = 2 * q1 + 1;
- r1 = 2 * r1 - nc;
- } else {
- q1 = 2 * q1;
- r1 = 2 * r1;
- }
- if (r2 + 1 >= val - r2) {
- if (q2 >= 0x7FFFFFFFU)
- output->a = 1;
- q2 = 2 * q2 + 1;
- r2 = 2 * r2 + 1 - val;
- } else {
- if (q2 >= 0x80000000U)
- output->a = 1;
- q2 = 2 * q2;
- r2 = 2 * r2 + 1;
- }
- delta = val - 1 - r2;
- } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
-
- output->m = q2 + 1;
- output->s = p - 32;
-}
-
-void gen_DIV(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- Type *type;
- int tmp;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_DIV_MOD(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- fp_binary_operator((type->size == 4) ? PC_FDIVS : PC_FDIV, left, right, outputReg, output);
- return;
- }
-
- if (is_unsigned(type)) {
- if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(right->data.intval.lo))) {
- shift_right_immediate(left, type, tmp, outputReg, output);
- } else if (!copts.optimizesize && ENODE_IS(right, EINTCONST) && right->data.intval.lo != 1) {
- SInt32 value;
- int tmpreg1;
- int tmpreg2;
- int tmpreg3;
- int tmpreg4;
- int tmpreg5;
- int tmpreg6;
- int finalReg;
- struct mu u_magicoutput;
- Operand op1;
- value = right->data.intval.lo;
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- memclrw(&op1, sizeof(Operand));
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
-
- tmpreg3 = op1.reg;
- create_unsigned_magic(value, &u_magicoutput);
- load_immediate(tmpreg2, u_magicoutput.m);
- emitpcode(PC_MULHWU, tmpreg1, tmpreg2, tmpreg3);
- if (u_magicoutput.a == 0) {
- if (u_magicoutput.s)
- emitpcode(PC_RLWINM, finalReg, tmpreg1, (32 - u_magicoutput.s) & 31, u_magicoutput.s, 31);
- else
- emitpcode(PC_MR, finalReg, tmpreg1);
- } else if (u_magicoutput.a == 1) {
- tmpreg4 = ALLOC_GPR();
- if (copts.optimizationlevel > 1) {
- tmpreg5 = ALLOC_GPR();
- tmpreg6 = ALLOC_GPR();
- } else {
- tmpreg5 = tmpreg4;
- tmpreg6 = tmpreg4;
- }
-
- emitpcode(PC_SUBF, tmpreg4, tmpreg1, tmpreg3);
- emitpcode(PC_RLWINM, tmpreg5, tmpreg4, 31, 1, 31);
- emitpcode(PC_ADD, tmpreg6, tmpreg5, tmpreg1);
- emitpcode(PC_RLWINM, finalReg, tmpreg6, (32 - (u_magicoutput.s - 1)) & 31, u_magicoutput.s - 1, 31);
- }
-
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- } else {
- binary_operator(PC_DIVWU, left, right, outputReg, output);
- }
- } else {
- SInt32 value;
- if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(right->data.intval.lo))) {
- signed_divide_by_power_of_2(left, tmp, 0, outputReg, output);
- } else if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(-right->data.intval.lo))) {
- signed_divide_by_power_of_2(left, tmp, 1, outputReg, output);
- } else if (!copts.optimizesize && ENODE_IS(right, EINTCONST) && (value = right->data.intval.lo) != 1u && value != -1) {
- int tmpreg2;
- int tmpreg3;
- int tmpreg1;
- int tmpreg4;
- int finalReg;
- struct ms s_magicoutput;
- Operand op2;
- value = right->data.intval.lo;
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- memclrw(&op2, sizeof(Operand));
- GEN_NODE(left, &op2);
- ENSURE_GPR(&op2, left->rtype, 0);
-
- tmpreg4 = op2.reg;
- create_signed_magic(value, &s_magicoutput);
- load_immediate(tmpreg2, s_magicoutput.m);
- emitpcode(PC_MULHW, tmpreg1, tmpreg2, tmpreg4);
- if (value > 0 && s_magicoutput.m < 0) {
- int t = ALLOC_GPR();
- emitpcode(PC_ADD, t, tmpreg1, tmpreg4);
- tmpreg1 = t;
- } else if (value < 0 && s_magicoutput.m > 0) {
- int t = ALLOC_GPR();
- emitpcode(PC_SUBF, t, tmpreg4, tmpreg1);
- tmpreg1 = t;
- }
-
- if (s_magicoutput.s) {
- int t = ALLOC_GPR();
- emitpcode(PC_SRAWI, t, tmpreg1, s_magicoutput.s);
- tmpreg1 = t;
- }
-
- emitpcode(PC_RLWINM, tmpreg3, tmpreg1, 1, 31, 31);
- emitpcode(PC_ADD, finalReg, tmpreg1, tmpreg3);
-
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- } else {
- binary_operator(PC_DIVW, left, right, outputReg, output);
- }
- }
-}
-
-void gen_MODULO(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- int tmp;
- struct mu u_magicoutput;
- struct ms s_magicoutput;
- Operand op1;
- Operand op2;
- SInt32 value;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
-
- if (TYPE_IS_8BYTES(expr->rtype)) {
- I8_gen_DIV_MOD(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST) && (tmp = ispowerof2(right->data.intval.lo))) {
- if (is_unsigned(expr->rtype))
- shift_and_mask(left, 0, 32 - tmp, 31, outputReg, output);
- else
- signed_mod_by_power_of_2(left, tmp, 0, outputReg, output);
- } else if (!copts.optimizesize && ENODE_IS(right, EINTCONST) && (value = right->data.intval.lo) != 1u && value != -1) {
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
-
- if (is_unsigned(expr->rtype)) {
- int tmpreg1;
- int tmpreg2;
- int tmpreg3;
- int tmpreg4;
- int tmpreg5;
- int tmpreg6;
- int tmpreg7;
- int tmpreg8;
- int finalReg;
-
- tmpreg1 = op1.reg;
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- create_unsigned_magic(right->data.intval.lo, &u_magicoutput);
- load_immediate(tmpreg3, u_magicoutput.m);
- emitpcode(PC_MULHWU, tmpreg2, tmpreg3, tmpreg1);
-
- if (u_magicoutput.a == 0 && u_magicoutput.s != 0)
- emitpcode(PC_RLWINM, tmpreg2, tmpreg2, (32 - u_magicoutput.s) & 31, u_magicoutput.s, 31);
-
- if (u_magicoutput.a == 1) {
- tmpreg5 = ALLOC_GPR();
- if (copts.optimizationlevel > 1) {
- tmpreg6 = ALLOC_GPR();
- tmpreg7 = ALLOC_GPR();
- tmpreg8 = ALLOC_GPR();
- } else {
- tmpreg6 = tmpreg5;
- tmpreg7 = tmpreg5;
- tmpreg8 = tmpreg5;
- }
- emitpcode(PC_SUBF, tmpreg5, tmpreg2, tmpreg1);
- emitpcode(PC_RLWINM, tmpreg6, tmpreg5, 31, 1, 31);
- emitpcode(PC_ADD, tmpreg7, tmpreg6, tmpreg2);
- emitpcode(PC_RLWINM, tmpreg8, tmpreg7, (32 - (u_magicoutput.s - 1)) & 31, u_magicoutput.s - 1, 31);
- tmpreg2 = tmpreg8;
- }
-
- if (value > 0 && value < 0x7FFF) {
- emitpcode(PC_MULLI, tmpreg4, tmpreg2, value);
- } else {
- GEN_NODE(right, &op2);
- ENSURE_GPR(&op2, right->rtype, 0);
- emitpcode(PC_MULLW, tmpreg4, tmpreg2, op2.reg);
- }
-
- emitpcode(PC_SUBF, finalReg, tmpreg4, tmpreg1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- } else {
- int tmpreg1;
- int tmpreg2;
- int tmpreg3;
- int tmpreg4;
- int tmpreg5;
- int tmpreg6;
- int finalReg;
-
- tmpreg1 = op1.reg;
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- tmpreg5 = ALLOC_GPR();
- tmpreg6 = ALLOC_GPR();
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- create_signed_magic(right->data.intval.lo, &s_magicoutput);
- load_immediate(tmpreg3, s_magicoutput.m);
- emitpcode(PC_MULHW, tmpreg2, tmpreg3, tmpreg1);
-
- if (value > 0 && s_magicoutput.m < 0) {
- int tmp = ALLOC_GPR();
- emitpcode(PC_ADD, tmp, tmpreg2, tmpreg1);
- tmpreg2 = tmp;
- } else if (value < 0 && s_magicoutput.m > 0) {
- int tmp = ALLOC_GPR();
- emitpcode(PC_SUBF, tmp, tmpreg1, tmpreg2);
- tmpreg2 = tmp;
- }
-
- if (s_magicoutput.s != 0) {
- int tmp = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmp, tmpreg2, s_magicoutput.s);
- tmpreg2 = tmp;
- }
-
- emitpcode(PC_RLWINM, tmpreg4, tmpreg2, 1, 31, 31);
- emitpcode(PC_ADD, tmpreg5, tmpreg2, tmpreg4);
-
- if (value < 0x7FFF && value > -0x4000) {
- emitpcode(PC_MULLI, tmpreg6, tmpreg5, value);
- } else {
- GEN_NODE(right, &op2);
- ENSURE_GPR(&op2, right->rtype, 0);
-
- emitpcode(PC_MULLW, tmpreg6, tmpreg5, op2.reg);
- }
-
- emitpcode(PC_SUBF, finalReg, tmpreg6, tmpreg1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- }
- } else {
- int tmpreg1;
- int tmpreg2;
- int finalReg;
-
- if (right->hascall) {
- GEN_NODE(right, &op2);
- ENSURE_GPR(&op2, right->rtype, 0);
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
- } else {
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
- GEN_NODE(right, &op2);
- ENSURE_GPR(&op2, right->rtype, 0);
- }
-
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- emitpcode(is_unsigned(expr->rtype) ? PC_DIVWU : PC_DIVW, tmpreg1, op1.reg, op2.reg);
- emitpcode(PC_MULLW, tmpreg2, tmpreg1, op2.reg);
- emitpcode(PC_SUBF, finalReg, tmpreg2, op1.reg);
-
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- }
-}
-
-void gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- Type *type;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_ADD(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- if (ENODE_IS(left, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FMADDS : PC_FMADD,
- left->data.diadic.left,
- left->data.diadic.right,
- right,
- outputReg, output);
- } else if (ENODE_IS(right, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FMADDS : PC_FMADD,
- right->data.diadic.left,
- right->data.diadic.right,
- left,
- outputReg, output);
- } else {
- fp_binary_operator(
- (type->size == 4) ? PC_FADDS : PC_FADD,
- left, right,
- outputReg, output);
- }
- return;
- }
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (opright.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&opright, right->rtype, 0);
-
- GEN_NODE(left, &opleft);
- if (opleft.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&opleft, left->rtype, 0);
- } else {
- GEN_NODE(left, &opleft);
- if (opleft.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&opleft, left->rtype, 0);
-
- GEN_NODE(right, &opright);
- if (opright.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&opright, right->rtype, 0);
- }
-
- if (IS_TYPE_POINTER(expr->rtype)) {
- if (TYPE_IS_8BYTES(expr->data.diadic.left->rtype)) {
- opleft.optype = OpndType_GPR;
- opleft.regHi = 0;
- }
- if (TYPE_IS_8BYTES(expr->data.diadic.right->rtype)) {
- opright.optype = OpndType_GPR;
- opright.regHi = 0;
- }
- }
-
- combine(&opleft, &opright, outputReg, output);
-}
-
-void gen_SUB(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- Type *type;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_SUB(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- if (ENODE_IS(left, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FMSUBS : PC_FMSUB,
- left->data.diadic.left,
- left->data.diadic.right,
- right,
- outputReg, output);
- } else if (ENODE_IS(right, EMUL) && copts.fp_contract) {
- fp_multiply_add(
- (type->size == 4) ? PC_FNMSUBS : PC_FNMSUB,
- right->data.diadic.left,
- right->data.diadic.right,
- left,
- outputReg, output);
- } else {
- fp_binary_operator(
- (type->size == 4) ? PC_FSUBS : PC_FSUB,
- left, right,
- outputReg, output);
- }
- return;
- }
-
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT(left->data.intval.lo))
- binary_immediate(PC_SUBFIC, right, left->data.intval.lo, outputReg, output);
- else
- binary_operator(PC_SUBF, right, left, outputReg, output);
-}
-
-void gen_SHL(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_SHL_SHR(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST))
- shift_left_immediate(left, right->data.intval.lo, 0, outputReg, output);
- else
- binary_operator(PC_SLW, left, right, outputReg, output);
-}
-
-void gen_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_SHL_SHR(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST))
- shift_right_immediate(left, type, right->data.intval.lo, outputReg, output);
- else
- binary_operator(is_unsigned(type) ? PC_SRW : PC_SRAW, left, right, outputReg, output);
-}
-
-void gen_AND(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
- short first;
- short last;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_AND(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST) && ismaskconstant(right->data.intval.lo, &first, &last)) {
- if (ENODE_IS(left, ESHL) && ENODE_IS(left->data.diadic.right, EINTCONST) && (int)(left->data.diadic.right->data.intval.lo + last) < 32) {
- shift_and_mask(
- left->data.diadic.left,
- left->data.diadic.right->data.intval.lo,
- first, last,
- outputReg, output);
- } else if (ENODE_IS(left, ESHR) && ENODE_IS(left->data.diadic.right, EINTCONST) && (int)left->data.diadic.right->data.intval.lo <= first && last >= first) {
- if (left->data.diadic.right->data.intval.lo == 0)
- shift_and_mask(left->data.diadic.left, 0, first, last, outputReg, output);
- else
- shift_and_mask(left->data.diadic.left, 32 - left->data.diadic.right->data.intval.lo, first, last, outputReg, output);
- } else {
- shift_and_mask(left, 0, first, last, outputReg, output);
- }
- return;
- }
-
- if (ENODE_IS(right, EINTCONST) && FITS_IN_USHORT(right->data.intval.lo)) {
- binary_immediate(PC_ANDI, left, right->data.intval.lo, outputReg, output);
- return;
- }
- if (ENODE_IS(right, EINTCONST) && FITS_IN_HI_SHORT(right->data.intval.lo)) {
- binary_immediate(PC_ANDIS, left, right->data.intval.lo >> 16, outputReg, output);
- return;
- }
-
- if (ENODE_IS(left, EINTCONST) && ismaskconstant(left->data.intval.lo, &first, &last)) {
- if (ENODE_IS(right, ESHL) && ENODE_IS(right->data.diadic.right, EINTCONST) && (int)(right->data.diadic.right->data.intval.lo + last) < 32) {
- shift_and_mask(
- right->data.diadic.left,
- right->data.diadic.right->data.intval.lo,
- first, last,
- outputReg, output);
- } else if (ENODE_IS(right, ESHR) && ENODE_IS(right->data.diadic.right, EINTCONST) && (int)right->data.diadic.right->data.intval.lo <= first) {
- if (right->data.diadic.right->data.intval.lo == 0)
- shift_and_mask(right->data.diadic.left, 0, first, last, outputReg, output);
- else
- shift_and_mask(right->data.diadic.left, 32 - right->data.diadic.right->data.intval.lo, first, last, outputReg, output);
- } else {
- shift_and_mask(right, 0, first, last, outputReg, output);
- }
- return;
- }
-
- if (ENODE_IS(left, EINTCONST) && FITS_IN_USHORT(left->data.intval.lo)) {
- binary_immediate(PC_ANDI, right, left->data.intval.lo, outputReg, output);
- return;
- }
- if (ENODE_IS(left, EINTCONST) && FITS_IN_HI_SHORT(left->data.intval.lo)) {
- binary_immediate(PC_ANDIS, right, left->data.intval.lo >> 16, outputReg, output);
- return;
- }
-
- if (ENODE_IS(right, EBINNOT))
- binary_operator(PC_ANDC, left, right->data.monadic, outputReg, output);
- else if (ENODE_IS(left, EBINNOT))
- binary_operator(PC_ANDC, right, left->data.monadic, outputReg, output);
- else
- binary_operator(PC_AND, left, right, outputReg, output);
-}
-
-void gen_XOR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_XOR(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(left, EINTCONST))
- or_xor_immediate(PC_XORI, right, left->data.intval.lo, outputReg, output);
- else if (ENODE_IS(right, EINTCONST))
- or_xor_immediate(PC_XORI, left, right->data.intval.lo, outputReg, output);
- else if (ENODE_IS(right, EBINNOT))
- binary_operator(PC_EQV, left, right->data.monadic, outputReg, output);
- else if (ENODE_IS(left, EBINNOT))
- binary_operator(PC_EQV, left->data.monadic, right, outputReg, output);
- else
- binary_operator(PC_XOR, left, right, outputReg, output);
-}
-
-void gen_OR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- type = expr->rtype;
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_OR(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(left, EINTCONST))
- or_xor_immediate(PC_ORI, right, left->data.intval.lo, outputReg, output);
- else if (ENODE_IS(right, EINTCONST))
- or_xor_immediate(PC_ORI, left, right->data.intval.lo, outputReg, output);
- else if (ENODE_IS(right, EBINNOT))
- binary_operator(PC_ORC, left, right->data.monadic, outputReg, output);
- else if (ENODE_IS(left, EBINNOT))
- binary_operator(PC_ORC, right, left->data.monadic, outputReg, output);
- else
- binary_operator(PC_OR, left, right, outputReg, output);
-}
-
-void gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- Operand op2;
- VarInfo *vi;
- SInt32 incval;
- short align;
- short align2;
-
- type = expr->rtype;
- if (ENODE_IS(expr, ECONDASS)) {
- left = expr->data.cond.expr1;
- if (ENODE_IS(left, EINDIRECT)) {
- left = left->data.monadic;
- } else {
- CError_FATAL(1759);
- }
- right = expr->data.cond.expr2;
- } else {
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- }
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
-
- if (TYPE_IS_8BYTES(type)) {
- I8_gen_ASS(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (ENODE_IS(left, EOBJREF) && OBJECT_REG(left->data.objref)) {
- vi = Registers_GetVarInfo(left->data.objref);
- GEN_NODE_TO_REG(right, vi->reg, 0, &opright);
- switch (vi->rclass) {
- case RegClass_GPR:
- ENSURE_GPR(&opright, type, vi->reg);
- output->optype = OpndType_GPR;
- break;
- case RegClass_FPR:
- ENSURE_FPR(&opright, type, vi->reg);
- output->optype = OpndType_FPR;
- break;
- case RegClass_VR:
- ENSURE_VR(&opright, type, vi->reg);
- output->optype = OpndType_VR;
- break;
- default:
- CError_FATAL(1810);
- }
- if (opright.reg != vi->reg) {
- PCodeArg a, b;
- a.kind = PCOp_REGISTER;
- a.arg = vi->rclass;
- a.data.reg.reg = vi->reg;
- a.data.reg.effect = EffectWrite;
- b.kind = PCOp_REGISTER;
- b.arg = vi->rclass;
- b.data.reg.reg = opright.reg;
- b.data.reg.effect = EffectRead;
- appendpcode(pclastblock, makecopyinstruction(&b, &a));
- }
- output->reg = vi->reg;
- return;
- }
-
- if (IS_TYPE_FLOAT(type)) {
- GEN_NODE_TO_FPR(right, &opright, right->rtype, 0);
- if (ispostincrementopportunity(left, &opleft, &incval)) {
- indirect(&opleft, expr);
- store_fp(opright.reg, &opleft, type);
- add_register_immediate(opleft.reg, opleft.reg, incval);
- } else {
- GEN_NODE(left, &opleft);
- indirect(&opleft, expr);
- store_fp(opright.reg, &opleft, type);
- }
- output->optype = OpndType_FPR;
- output->reg = opright.reg;
- return;
- }
-
- if (IS_TYPE_VECTOR(type)) {
- GEN_NODE(right, &opright);
- if (opright.optype == OpndType_Absolute)
- ENSURE_VR(&opright, type, 0);
- else
- ENSURE_VR(&opright, right->rtype, 0);
-
- if (ispostincrementopportunity(left, &opleft, &incval)) {
- indirect(&opleft, expr);
- store_v(opright.reg, &opleft, type);
- add_register_immediate(opleft.reg, opleft.reg, incval);
- } else {
- GEN_NODE(left, &opleft);
- indirect(&opleft, expr);
- store_v(opright.reg, &opleft, type);
- }
- output->optype = OpndType_VR;
- output->reg = opright.reg;
- return;
- }
-
- if (TYPE_FITS_IN_REGISTER(type)) {
- GEN_NODE_TO_GPR(right, &opright, right->rtype, 0);
-
- if (ENODE_IS(left, EBITFIELD)) {
- GEN_NODE(left->data.monadic, &opleft);
- indirect(&opleft, expr);
-
- op2 = opleft;
- ENSURE_GPR(&op2, type, 0);
- insert_bitfield(opright.reg, &op2, TYPE_BITFIELD(left->rtype));
- store(op2.reg, &opleft, type);
-
- if (!expr->ignored)
- extract_bitfield(&op2, TYPE_BITFIELD(left->rtype), opright.reg, &opleft);
- } else if (ispostincrementopportunity(left, &opleft, &incval)) {
- indirect(&opleft, expr);
- store(opright.reg, &opleft, type);
- add_register_immediate(opleft.reg, opleft.reg, incval);
- } else {
- GEN_NODE(left, &opleft);
- indirect(&opleft, expr);
- store(opright.reg, &opleft, type);
- }
-
- output->optype = OpndType_GPR;
- output->reg = opright.reg;
- return;
- }
-
- GEN_NODE(right, &opright);
- GEN_NODE(left, output);
-
- indirect(output, expr);
- if (output->object) {
- if (output->object->datatype == DLOCAL && (output->object->u.var.info->flags & VarInfoFlag1))
- align = CMach_ArgumentAlignment(type);
- else
- align = CMach_AllocationAlignment(type, output->object->qual);
- } else {
- align = CMach_AllocationAlignment(type, 0);
- }
- if (opright.object) {
- if (opright.object->datatype == DLOCAL && (opright.object->u.var.info->flags & VarInfoFlag1))
- align2 = CMach_ArgumentAlignment(type);
- else
- align2 = CMach_AllocationAlignment(type, opright.object->qual);
- } else {
- align2 = CMach_AllocationAlignment(type, 0);
- }
-
- if (align2 < align)
- align = align2;
-
- move_block(output, &opright, type->size, align);
-}
-
-ENode *evaluate_and_skip_comma(ENode *expr) {
- Operand op;
- ENode *inner;
-
- memclrw(&op, sizeof(Operand));
- while (ENODE_IS(expr, ECOMMA)) {
- inner = expr->data.diadic.left;
- GEN_NODE(inner, &op);
- if (ENODE_IS(inner, EINDIRECT) && (op.flags & OpndFlags_Volatile)) {
- if (TYPE_FITS_IN_REGISTER_2(inner->rtype)) {
- ENSURE_GPR(&op, inner->rtype, 0);
- } else if (IS_TYPE_FLOAT(inner->rtype)) {
- ENSURE_FPR(&op, inner->rtype, 0);
- }
- }
- expr = expr->data.diadic.right;
- }
- return expr;
-}
-
-void gen_COMMA(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- GEN_NODE(left, output);
-
- if (ENODE_IS(left, EINDIRECT) && (output->flags & OpndFlags_Volatile)) {
- if (TYPE_FITS_IN_REGISTER_2(left->rtype)) {
- ENSURE_GPR(output, left->rtype, 0);
- } else if (IS_TYPE_FLOAT(left->rtype)) {
- ENSURE_FPR(output, left->rtype, 0);
- }
- }
-
- GEN_NODE_TO_REG(right, outputReg, 0, output);
-}
-
-void gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Type *srctype;
- Type *dsttype;
-
- inner = expr->data.monadic;
- srctype = inner->rtype;
- dsttype = expr->rtype;
-
- if (TYPE_IS_8BYTES(srctype) || TYPE_IS_8BYTES(dsttype)) {
- I8_gen_TYPCON(expr, outputReg, outputRegHi, output);
- return;
- }
-
- if (IS_TYPE_VOID(dsttype)) {
- GEN_NODE(inner, output);
- if (ENODE_IS(inner, EINDIRECT) && (output->flags & OpndFlags_Volatile)) {
- if (TYPE_FITS_IN_REGISTER_2(srctype)) {
- ENSURE_GPR(output, srctype, 0);
- } else if (IS_TYPE_FLOAT(srctype)) {
- ENSURE_FPR(output, srctype, 0);
- }
- }
- } else if (IS_TYPE_INT_OR_ENUM(srctype)) {
- if (IS_TYPE_FLOAT(dsttype)) {
- GEN_NODE(inner, output);
- if (srctype->size < 4)
- extend32(output, srctype, 0);
- ENSURE_GPR(output, srctype, 0);
-
- if (is_unsigned(srctype))
- convert_unsigned_to_floating(output, dsttype->size == 4, outputReg);
- else
- convert_integer_to_floating(output, dsttype->size == 4, outputReg);
- } else if (IS_TYPE_VECTOR(dsttype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- ENSURE_VR(output, dsttype, outputReg);
- } else if (
- srctype->size < dsttype->size &&
- !ENODE_IS_INDIRECT_TO(inner, EBITFIELD) &&
- !ENODE_IS_ASSIGN_TO(inner, EBITFIELD) &&
- !(ENODE_IS_RANGE(inner, EPOSTINC, EPREDEC) && ENODE_IS(inner->data.monadic->data.monadic, EBITFIELD))
- ) {
- GEN_NODE(inner, output);
- extend32(output, srctype, outputReg);
- } else if (dsttype->size < srctype->size || dsttype->size < 4) {
- GEN_NODE(inner, output);
- ENSURE_GPR(output, srctype, 0);
- extend32(output, dsttype, outputReg);
- } else {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- }
- } else if (IS_TYPE_POINTER(srctype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- if (dsttype->size < srctype->size)
- ENSURE_GPR(output, srctype, outputReg);
- } else if (IS_TYPE_FLOAT(srctype)) {
- if (IS_TYPE_FLOAT(dsttype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- ENSURE_FPR(output, srctype, outputReg);
-
- if (dsttype->size == 4 && srctype->size != 4) {
- int tmp = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(PC_FRSP, tmp, output->reg);
- output->optype = OpndType_FPR;
- output->reg = tmp;
- }
- } else if (is_unsigned(dsttype) && dsttype->size == 4) {
- GEN_NODE_TO_REG(inner, 1, 0, output);
- ENSURE_FPR(output, srctype, 1);
- convert_floating_to_unsigned(output, outputReg);
- } else {
- GEN_NODE_TO_REG(inner, 0, 0, output);
- ENSURE_FPR(output, srctype, 0);
- convert_floating_to_integer(output, outputReg);
- }
- } else if (IS_TYPE_VECTOR(srctype) && IS_TYPE_VECTOR(dsttype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- ENSURE_VR(output, srctype, outputReg);
- } else if (srctype->size == dsttype->size) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- } else {
- CError_FATAL(2224);
- }
-}
-
-void gen_BITFIELD(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- CError_FATAL(2238);
-}
-
-void gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- if (TYPE_IS_8BYTES(expr->rtype)) {
- I8_gen_INTCONST(expr, outputReg, outputRegHi, output);
- return;
- }
-
- output->optype = OpndType_Absolute;
- output->immediate = CInt64_GetULong(&expr->data.intval);
-}
-
-void gen_FLOATCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- CError_FATAL(2294);
-}
-
-void gen_STRINGCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- CError_FATAL(2308);
-}
-
-static Boolean COND_is_ABS_MatchNodes(ENode *cond, ENode *expr1, ENode *expr2) {
- if (cond->type != expr1->type || cond->type != expr2->type)
- return 0;
-
- if (!(TYPE_FITS_IN_REGISTER(cond->rtype) && TYPE_FITS_IN_REGISTER(expr1->rtype) && TYPE_FITS_IN_REGISTER(expr2->rtype)))
- return 0;
-
- if (cond->rtype->size != expr1->rtype->size || cond->rtype->size != expr2->rtype->size)
- return 0;
-
- switch (cond->type) {
- case EOBJREF:
- if (cond->data.objref != expr1->data.objref || cond->data.objref != expr2->data.objref)
- return 0;
- return 1;
- case EINDIRECT:
- case ETYPCON:
- return COND_is_ABS_MatchNodes(cond->data.monadic, expr1->data.monadic, expr2->data.monadic);
- default:
- return 0;
- }
-}
-
-static ENode *COND_is_ABS(ENode *cond, ENode *expr1, ENode *expr2) {
- ENode *tmp;
-
- int parity = 0;
- while (ENODE_IS(cond, ELOGNOT)) {
- parity = (parity + 1) & 1;
- cond = cond->data.monadic;
- }
-
- if (parity) {
- tmp = expr1;
- expr1 = expr2;
- expr2 = tmp;
- }
-
- switch (cond->type) {
- case ELESS:
- case ELESSEQU:
- tmp = expr1;
- expr1 = expr2;
- expr2 = tmp;
- break;
- case EGREATER:
- case EGREATEREQU:
- break;
- default:
- return NULL;
- }
-
- if (IS_INT_CONST_ZERO(cond->data.diadic.right)) {
- cond = cond->data.diadic.left;
- } else if (IS_INT_CONST_ZERO(cond->data.diadic.left)) {
- cond = cond->data.diadic.left;
- tmp = expr1;
- expr1 = expr2;
- expr2 = tmp;
- } else {
- return NULL;
- }
-
- if (ENODE_IS(expr1, EADD) && ENODE_IS(expr2, ESUB)) {
- if (COND_is_ABS_MatchNodes(cond, expr1->data.diadic.right, expr2->data.diadic.right))
- return expr1;
- else
- return NULL;
- }
-
- if (!ENODE_IS(expr2, EMONMIN))
- return NULL;
-
- expr2 = expr2->data.monadic;
- if (COND_is_ABS_MatchNodes(cond, expr1, expr2))
- return expr1;
-
- return NULL;
-}
-
-static int COND_has_const(ENode *expr1, ENode *expr2) {
- SInt32 diff;
- int result = 0;
-
- if (IS_INT_CONST(expr1))
- result += 1;
- if (IS_INT_CONST(expr2))
- result += 2;
-
- if (result & 1) {
- if (IS_INT_CONST_ZERO(expr1))
- return 5;
- }
- if (result & 2) {
- if (IS_INT_CONST_ZERO(expr2))
- return 6;
- }
-
- if (result == 3) {
- diff = expr1->data.intval.lo - expr2->data.intval.lo;
- if (diff == 1 || diff == -1)
- return 4;
- }
-
- return result;
-}
-
-static Boolean COND_is_COMPARE(ENode *cond, ENode *expr1, ENode *expr2, short outputReg, Operand *output) {
- SInt32 left;
- SInt32 right;
- int parity;
- int negate;
- ENodeType nt;
-
- while (ENODE_IS(expr1, ETYPCON) && TYPE_FITS_IN_REGISTER(expr1->rtype))
- expr1 = expr1->data.monadic;
- while (ENODE_IS(expr2, ETYPCON) && TYPE_FITS_IN_REGISTER(expr2->rtype))
- expr2 = expr2->data.monadic;
-
- if (!(ENODE_IS(expr1, EINTCONST) && TYPE_FITS_IN_REGISTER(expr1->rtype) && CInt64_IsInRange(expr1->data.intval, 4)))
- return 0;
- if (!(ENODE_IS(expr2, EINTCONST) && TYPE_FITS_IN_REGISTER(expr2->rtype) && CInt64_IsInRange(expr2->data.intval, 4)))
- return 0;
-
- left = CInt64_GetULong(&expr1->data.intval);
- right = CInt64_GetULong(&expr2->data.intval);
- parity = 0;
- negate = 0;
- switch (left) {
- case 1:
- if (right != 0)
- return 0;
- break;
- case 0:
- parity = 1;
- if (right == -1)
- negate = 1;
- else if (right != 1)
- return 0;
- break;
- case -1:
- if (right != 0)
- return 0;
- negate = 1;
- break;
- default:
- return 0;
- }
-
- while (ENODE_IS(cond, ELOGNOT)) {
- parity = (parity + 1) & 1;
- cond = cond->data.monadic;
- }
-
- if (parity) {
- nt = invert_relop(cond->type);
- if (nt == cond->type)
- return 0;
- cond->type = nt;
- }
-
- if (negate)
- gen_negated_condition_gpr(cond, output, outputReg);
- else
- gen_condition_gpr(cond, output, outputReg);
-
- return 1;
-}
-
-void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *cond;
- ENode *expr1;
- ENode *expr2;
- Type *type;
- PCodeLabel *label1;
- PCodeLabel *label2;
- PCodeLabel *label3;
- Operand op1;
- Operand op2;
- int has_const;
- int reg1;
- int reg2;
- int reg3;
- short align;
- short max_align;
-
- expr1 = expr->data.cond.expr1;
- expr2 = expr->data.cond.expr2;
- type = expr->rtype;
-
- label1 = makepclabel();
- label2 = makepclabel();
- label3 = makepclabel();
-
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
-
- cond = evaluate_and_skip_comma(expr->data.cond.cond);
-
- if (TOC_use_fsel(expr)) {
- ENode *left;
- ENode *right;
- ENode *tmp;
- ENodeType nt;
- Boolean flag;
- Operand op;
- int fneg_reg;
- int fneg_reg2;
- int fneg_reg3;
- int fsel_reg;
- int final_reg;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- nt = cond->type;
- flag = 0;
- memclrw(&op, sizeof(Operand));
-
- switch (nt) {
- case EGREATEREQU:
- case EEQU:
- break;
- case EGREATER:
- tmp = left;
- left = right;
- right = tmp;
- case ELESS:
- case ENOTEQU:
- tmp = expr1;
- expr1 = expr2;
- expr2 = tmp;
- break;
- case ELESSEQU:
- tmp = left;
- left = right;
- right = tmp;
- break;
- default:
- CError_FATAL(2780);
- }
-
- if (ENODE_IS(left, EFLOATCONST) && CMach_FloatIsZero(left->data.floatval)) {
- GEN_NODE(right, &op);
- ENSURE_FPR(&op, right->rtype, 0);
- flag = 1;
- } else if (ENODE_IS(right, EFLOATCONST) && CMach_FloatIsZero(right->data.floatval)) {
- GEN_NODE(left, &op);
- ENSURE_FPR(&op, left->rtype, 0);
- } else {
- fp_binary_operator((type->size == 4) ? PC_FSUBS : PC_FSUB, left, right, 0, &op);
- }
-
- switch (cond->type) {
- case EEQU:
- case ENOTEQU:
- if (flag) {
- GEN_NODE_TO_FPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0);
-
- fneg_reg = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg, op.reg);
- fsel_reg = ALLOC_FPR();
- emitpcode(PC_FSEL, fsel_reg, op.reg, op1.reg, op2.reg);
- final_reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(PC_FSEL, final_reg, fneg_reg, fsel_reg, op2.reg);
- } else {
- GEN_NODE_TO_FPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0);
-
- fneg_reg2 = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg2, op.reg);
- fsel_reg = ALLOC_FPR();
- emitpcode(PC_FSEL, fsel_reg, op.reg, op1.reg, op2.reg);
- final_reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(PC_FSEL, final_reg, fneg_reg2, fsel_reg, op2.reg);
- }
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- GEN_NODE_TO_FPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0);
-
- fneg_reg3 = op.reg;
- if (flag) {
- fneg_reg3 = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg3, op.reg);
- }
-
- final_reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(PC_FSEL, final_reg, fneg_reg3, op1.reg, op2.reg);
- break;
- default:
- CError_FATAL(2862);
- }
-
- output->optype = OpndType_FPR;
- output->reg = final_reg;
- return;
- }
-
- if (TOC_use_isel(expr, 1)) {
- Operand isel_op1;
- Operand isel_op2;
- ENode *x;
- ENode *y;
- ENode *abs_expr;
-
- memclrw(&isel_op1, sizeof(Operand));
- memclrw(&isel_op2, sizeof(Operand));
-
- if (COND_is_COMPARE(cond, expr1, expr2, outputReg, output))
- return;
-
- if ((abs_expr = COND_is_ABS(cond, expr1, expr2))) {
- if (ENODE_IS(expr1, EADD) && ENODE_IS(expr2, ESUB)) {
- x = expr1->data.diadic.left;
- y = expr2->data.diadic.right;
- if (y->hascall) {
- GEN_NODE(y, &op2);
- ENSURE_GPR(&op2, y->rtype, 0);
-
- GEN_NODE(x, &op1);
- if (op1.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&op1, x->rtype, 0);
- } else {
- GEN_NODE(x, &op1);
- if (op1.optype >= OpndType_IndirectGPR_ImmOffset)
- ENSURE_GPR(&op1, x->rtype, 0);
-
- GEN_NODE(y, &op2);
- ENSURE_GPR(&op2, y->rtype, 0);
- }
-
- reg1 = ALLOC_GPR();
- emitpcode(PC_SRAWI, reg1, op2.reg, 31);
- reg2 = ALLOC_GPR();
- emitpcode(PC_XOR, reg2, reg1, op2.reg);
- reg3 = ALLOC_GPR();
- emitpcode(PC_SUBF, reg3, reg1, reg2);
- op2.optype = OpndType_GPR;
- op2.reg = reg3;
- combine(&op1, &op2, outputReg, output);
- } else {
- GEN_NODE(abs_expr, output);
- ENSURE_GPR(output, abs_expr->rtype, 0);
-
- reg1 = ALLOC_GPR();
- emitpcode(PC_SRAWI, reg1, output->reg, 31);
- reg2 = ALLOC_GPR();
- emitpcode(PC_XOR, reg2, reg1, output->reg);
- reg3 = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBF, reg3, reg1, reg2);
- output->optype = OpndType_GPR;
- output->reg = reg3;
- }
- return;
- }
-
- if ((has_const = COND_has_const(expr1, expr2))) {
- switch (COND_has_const(expr1, expr2)) {
- case 0:
- case 2:
- break;
- case 3:
- case 4:
- if (has_const == 4) {
- if (expr1->data.intval.lo < expr2->data.intval.lo)
- gen_negated_condition_gpr(cond, &isel_op1, 0);
- else
- gen_condition_gpr(cond, &isel_op1, 0);
-
- GEN_NODE(expr1, &op1);
- GEN_NODE(expr2, &op2);
- reg1 = ALLOC_GPR();
- ENSURE_GPR(&op2, expr2->rtype, reg1);
- emitpcode(PC_ADD, reg1, isel_op1.reg, op2.reg);
- if (outputReg) {
- emitpcode(PC_MR, reg2 = outputReg, reg1);
- reg1 = reg2;
- }
- output->optype = OpndType_GPR;
- output->reg = reg1;
- return;
- }
- break;
- case 5:
- case 6:
- gen_negated_condition_gpr(cond, &isel_op1, 0);
- ENSURE_GPR(&isel_op1, TYPE(&stunsignedint), 0);
- GEN_NODE(expr1, &op1);
- GEN_NODE(expr2, &op2);
-
- reg1 = outputReg ? outputReg : ALLOC_GPR();
- if (op1.optype == OpndType_Absolute && op1.immediate == 0) {
- ENSURE_GPR(&op2, expr2->rtype, 0);
- emitpcode(PC_ANDC, reg1, op2.reg, isel_op1.reg);
- } else if (op2.optype == OpndType_Absolute && op2.immediate == 0) {
- ENSURE_GPR(&op1, expr1->rtype, 0);
- emitpcode(PC_AND, reg1, op1.reg, isel_op1.reg);
- } else {
- CError_FATAL(3119);
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg1;
- return;
- case 1:
- reg2 = ALLOC_GPR();
- reg1 = reg2;
- logical_expression_nobranch(cond, 0, &isel_op2);
-
- GEN_NODE_TO_REG(expr1, reg1, 0, &op1);
- ENSURE_GPR(&op1, expr1->rtype, reg1);
- if (op1.reg != reg1)
- emitpcode(PC_MR, reg1, op1.reg);
-
- branch_conditional(isel_op2.reg, isel_op2.regOffset, 1, label2);
- branch_label(label1);
-
- GEN_NODE_TO_REG(expr2, reg1, 0, &op2);
- ENSURE_GPR(&op2, expr2->rtype, reg1);
- if (op2.reg != reg1)
- emitpcode(PC_MR, reg1, op2.reg);
-
- branch_label(label2);
-
- if (outputReg) {
- emitpcode(PC_MR, reg2 = outputReg, reg1);
- reg1 = reg2;
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg1;
- return;
-
- default:
- CError_FATAL(3168);
- }
- }
-
- reg1 = ALLOC_GPR();
- logical_expression_nobranch(cond, 0, &isel_op2);
-
- GEN_NODE_TO_REG(expr2, reg1, 0, &op2);
- ENSURE_GPR(&op2, expr2->rtype, reg1);
- if (op2.reg != reg1)
- emitpcode(PC_MR, reg1, op2.reg);
-
- branch_conditional(isel_op2.reg, isel_op2.regOffset, 0, label2);
- branch_label(label1);
-
- GEN_NODE_TO_REG(expr1, reg1, 0, &op1);
- ENSURE_GPR(&op1, expr1->rtype, reg1);
- if (op1.reg != reg1)
- emitpcode(PC_MR, reg1, op1.reg);
-
- branch_label(label2);
-
- if (outputReg) {
- emitpcode(PC_MR, reg2 = outputReg, reg1);
- reg1 = reg2;
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg1;
- return;
- }
-
- logical_expression(cond, label1, label2, label1);
- branch_label(label1);
-
- if (IS_TYPE_VOID(type) || expr->ignored) {
- GEN_NODE(expr1, &op1);
- branch_always(label3);
- branch_label(label2);
- GEN_NODE(expr2, &op2);
- } else if (IS_TYPE_FLOAT(type)) {
- if (expr1->hascall || expr2->hascall)
- reg1 = ALLOC_FPR();
- else
- reg1 = outputReg ? outputReg : ALLOC_FPR();
-
- GEN_NODE_TO_REG(expr1, reg1, 0, &op1);
- ENSURE_FPR(&op1, expr1->rtype, reg1);
- if (op1.reg != reg1)
- emitpcode(PC_FMR, reg1, op1.reg);
-
- branch_always(label3);
- branch_label(label2);
-
- GEN_NODE_TO_REG(expr2, reg1, 0, &op2);
- ENSURE_FPR(&op2, expr2->rtype, reg1);
- if (op2.reg != reg1)
- emitpcode(PC_FMR, reg1, op2.reg);
-
- output->optype = OpndType_FPR;
- output->reg = reg1;
- } else if (TYPE_IS_8BYTES(type)) {
- if (expr1->hascall || expr2->hascall) {
- reg1 = ALLOC_GPR();
- reg3 = ALLOC_GPR();
- reg2 = reg3;
- } else {
- reg1 = outputReg ? outputReg : ALLOC_GPR();
- reg3 = outputRegHi ? outputRegHi : ALLOC_GPR();
- reg2 = reg3;
- }
-
- GEN_NODE_TO_REG(expr1, reg1, reg2, &op1);
- coerce_to_register_pair(&op1, expr1->rtype, reg1, reg2);
-
- branch_always(label3);
- branch_label(label2);
-
- GEN_NODE_TO_REG(expr2, reg1, reg2, &op2);
- coerce_to_register_pair(&op2, expr2->rtype, reg1, reg2);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg1;
- output->regHi = reg2;
- } else if (TYPE_FITS_IN_REGISTER(type)) {
- if (expr1->hascall || expr2->hascall)
- reg1 = ALLOC_GPR();
- else
- reg1 = outputReg ? outputReg : ALLOC_GPR();
-
- GEN_NODE_TO_REG(expr1, reg1, 0, &op1);
- ENSURE_GPR(&op1, expr1->rtype, reg1);
- if (op1.reg != reg1)
- emitpcode(PC_MR, reg1, op1.reg);
-
- branch_always(label3);
- branch_label(label2);
-
- GEN_NODE_TO_REG(expr2, reg1, 0, &op2);
- ENSURE_GPR(&op2, expr2->rtype, reg1);
- if (op2.reg != reg1)
- emitpcode(PC_MR, reg1, op2.reg);
-
- output->optype = OpndType_GPR;
- output->reg = reg1;
- } else if (IS_TYPE_VECTOR(type)) {
- if (expr1->hascall || expr2->hascall)
- reg1 = ALLOC_VR();
- else
- reg1 = outputReg ? outputReg : ALLOC_VR();
-
- GEN_NODE_TO_REG(expr1, reg1, 0, &op1);
- ENSURE_VR(&op1, expr1->rtype, reg1);
- if (op1.reg != reg1)
- emitpcode(PC_VMR, reg1, op1.reg);
-
- branch_always(label3);
- branch_label(label2);
-
- GEN_NODE_TO_REG(expr2, reg1, 0, &op2);
- ENSURE_VR(&op2, expr2->rtype, reg1);
- if (op2.reg != reg1)
- emitpcode(PC_VMR, reg1, op2.reg);
-
- output->optype = OpndType_VR;
- output->reg = reg1;
- } else {
- symbol_operand(output, maketemporary(type));
- indirect(output, NULL);
- coerce_to_addressable(output);
-
- GEN_NODE(expr1, &op1);
-
- if (op1.object) {
- if (op1.object->datatype == DLOCAL && (op1.object->u.var.info->flags & VarInfoFlag1))
- align = CMach_ArgumentAlignment(type);
- else
- align = CMach_AllocationAlignment(type, op1.object->qual);
- } else {
- align = CMach_AllocationAlignment(type, 0);
- }
-
- max_align = CMach_AllocationAlignment(type, 0);
- if (align > max_align)
- align = max_align;
-
- move_block(output, &op1, type->size, align);
-
- branch_always(label3);
- branch_label(label2);
-
- GEN_NODE(expr2, &op2);
-
- if (op2.object) {
- if (op2.object->datatype == DLOCAL && (op2.object->u.var.info->flags & VarInfoFlag1))
- align = CMach_ArgumentAlignment(type);
- else
- align = CMach_AllocationAlignment(type, op2.object->qual);
- } else {
- align = CMach_AllocationAlignment(type, 0);
- }
-
- if (align > max_align)
- align = max_align;
-
- move_block(output, &op2, type->size, align);
- }
-
- branch_label(label3);
-}
-
-static Boolean CONDASS_is_ABS(ENode *cond, ENode *expr1, ENode *expr2) {
- ENode *inner;
-
- int parity = 0;
- while (ENODE_IS(cond, ELOGNOT)) {
- parity = (parity + 1) & 1;
- cond = cond->data.monadic;
- }
-
- if (IS_INT_CONST_ZERO(cond->data.diadic.right)) {
- inner = cond->data.diadic.left;
- } else if (IS_INT_CONST_ZERO(cond->data.diadic.left)) {
- inner = cond->data.diadic.left;
- parity = (parity + 1) & 1;
- } else {
- return 0;
- }
-
- switch (cond->type) {
- case EGREATER:
- case EGREATEREQU:
- if (!parity)
- return 0;
- break;
- case ELESS:
- case ELESSEQU:
- if (parity)
- return 0;
- break;
- default:
- return 0;
- }
-
- if (!ENODE_IS(expr2, EMONMIN))
- return 0;
-
- expr2 = expr2->data.monadic;
- if (ENODE_IS(inner, EASS)) {
- inner = inner->data.diadic.left;
- if (!ENODE_IS(expr2, EINDIRECT))
- return 0;
- expr2 = expr2->data.monadic;
- if (!ENODE_IS(expr1, EINDIRECT))
- return 0;
- expr1 = expr1->data.monadic;
- }
-
- return COND_is_ABS_MatchNodes(inner, expr1, expr2);
-}
-
-static int CONDASS_is_OPASS_One(ENode *a, ENode *b, SInt32 *value, ENodeType *nodetype) {
- Type *type;
-
- type = a->rtype;
- if (!ENODE_IS(a, EINDIRECT))
- return 0;
- a = a->data.monadic;
- if (!ENODE_IS(a, EOBJREF))
- return 0;
-
- if (ENODE_IS(b, ETYPCON) && b->rtype == type)
- b = b->data.monadic;
-
- if (b->type != EOR && b->type != EADD && b->type != ESUB)
- return 0;
-
- *nodetype = b->type;
- if (!IS_INT_CONST(b->data.diadic.right))
- return 0;
- *value = b->data.diadic.right->data.intval.lo;
-
- if (*value != 1 && *value != -1)
- return 0;
-
- b = b->data.diadic.left;
- if (ENODE_IS(b, ETYPCON) && TYPE_FITS_IN_REGISTER(b->rtype))
- b = b->data.monadic;
-
- if (!ENODE_IS(b, EINDIRECT))
- return 0;
- b = b->data.monadic;
- if (!ENODE_IS(b, EOBJREF))
- return 0;
-
- if (a->data.objref == b->data.objref)
- return 1;
- return 0;
-}
-
-void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *cond;
- ENode *expr1;
- ENode *expr2;
- Type *type;
- PCodeLabel *label1;
- PCodeLabel *label2;
- Operand op1;
- Operand op2;
- Operand op3;
- int reg1;
- int reg2;
-
- expr1 = expr->data.cond.expr1;
- expr2 = expr->data.cond.expr2;
- type = expr->rtype;
-
- label1 = makepclabel();
- label2 = makepclabel();
-
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
- memclrw(&op3, sizeof(Operand));
-
- cond = evaluate_and_skip_comma(expr->data.cond.cond);
-
- if (TOC_use_fsel(expr)) {
- ENode *left;
- ENode *right;
- ENode *tmp;
- ENodeType nt;
- Boolean flag;
- Boolean flag2;
- Operand op;
- int tmpreg;
- int fneg_reg;
- int fsel_reg;
- int final_reg;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- nt = cond->type;
- flag = 0;
- memclrw(&op, sizeof(Operand));
-
- CError_ASSERT(3704, ENODE_IS(expr1, EINDIRECT));
- CError_ASSERT(3705, ENODE_IS(expr1->data.monadic, EOBJREF));
-
- tmpreg = OBJECT_REG(expr1->data.monadic->data.objref);
- final_reg = outputReg ? tmpreg : ALLOC_FPR();
-
- switch (nt) {
- case EGREATER:
- tmp = left;
- left = right;
- right = tmp;
- case ELESS:
- case ENOTEQU:
- tmp = expr1;
- expr1 = expr2;
- expr2 = tmp;
- flag2 = 1;
- break;
- case ELESSEQU:
- tmp = left;
- left = right;
- right = tmp;
- flag2 = 0;
- break;
- case EGREATEREQU:
- case EEQU:
- flag2 = 0;
- break;
- default:
- CError_FATAL(3744);
- }
-
- if (ENODE_IS(left, EFLOATCONST) && CMach_FloatIsZero(left->data.floatval)) {
- GEN_NODE(right, &op);
- ENSURE_FPR(&op, right->rtype, 0);
- flag = 1;
- } else if (ENODE_IS(right, EFLOATCONST) && CMach_FloatIsZero(right->data.floatval)) {
- GEN_NODE(left, &op);
- ENSURE_FPR(&op, left->rtype, 0);
- } else {
- fp_binary_operator((type->size == 4) ? PC_FSUBS : PC_FSUB, left, right, 0, &op);
- }
-
- switch (cond->type) {
- case EEQU:
- case ENOTEQU:
- if (flag) {
- GEN_NODE(expr1, &op1);
- op3 = op1;
- ENSURE_FPR(&op1, expr1->rtype, 0);
-
- GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0);
-
- fneg_reg = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg, op.reg);
- fsel_reg = ALLOC_FPR();
- emitpcode(PC_FSEL, fsel_reg, op.reg, op2.reg, op1.reg);
- emitpcode(PC_FSEL, final_reg, fneg_reg, op2.reg, fsel_reg);
- } else {
- GEN_NODE(expr1, &op1);
- op3 = op1;
- ENSURE_FPR(&op1, expr1->rtype, 0);
-
- GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0);
-
- fneg_reg = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg, op.reg);
- fsel_reg = ALLOC_FPR();
- emitpcode(PC_FSEL, fsel_reg, op.reg, op2.reg, op1.reg);
- emitpcode(PC_FSEL, final_reg, fneg_reg, op2.reg, fsel_reg);
- }
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- GEN_NODE(expr1, &op1);
- GEN_NODE(expr2, &op2);
- op3 = flag2 ? op2 : op1;
-
- ENSURE_FPR(&op1, expr1->rtype, 0);
- ENSURE_FPR(&op2, expr2->rtype, 0);
-
- fneg_reg = op.reg;
- if (flag) {
- fneg_reg = ALLOC_FPR();
- emitpcode(PC_FNEG, fneg_reg, op.reg);
- }
-
- emitpcode(PC_FSEL, final_reg, fneg_reg, op2.reg, op1.reg);
- break;
- default:
- CError_FATAL(2862);
- }
-
- if (op3.optype != OpndType_FPR)
- store_fp(final_reg, &op3, type);
-
- output->optype = OpndType_FPR;
- output->reg = final_reg;
- return;
- }
-
- if (TOC_use_isel(expr, 1)) {
- Operand isel_op;
- ENode *x;
- ENode *y;
- ENode *abs_expr;
-
- memclrw(&isel_op, sizeof(Operand));
- CError_ASSERT(3966, ENODE_IS(expr1, EINDIRECT));
- CError_ASSERT(3968, ENODE_IS(expr1->data.monadic, EOBJREF));
-
- if (CONDASS_is_ABS(cond, expr1, expr2)) {
- if (ENODE_IS(cond->data.diadic.left, EASS))
- GEN_NODE(cond->data.diadic.left, &isel_op);
- else if (ENODE_IS(cond->data.diadic.right, EASS))
- GEN_NODE(cond->data.diadic.right, &isel_op);
-
- outputReg = OBJECT_REG(expr1->data.monadic->data.objref);
- CError_ASSERT(3979, outputReg);
-
- GEN_NODE(expr1, &op1);
- op3 = op1;
-
- CError_ASSERT(3986, op3.optype == OpndType_GPR && op3.reg == outputReg);
-
- ENSURE_GPR(&op1, expr1->rtype, 0);
- if (expr1->rtype->size < 4)
- extend32(output, expr1->rtype, op3.reg);
-
- reg1 = ALLOC_GPR();
- reg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, reg1, op1.reg, 31);
- emitpcode(PC_XOR, reg2, reg1, op1.reg);
- emitpcode(PC_SUBF, outputReg, reg1, reg2);
- output->optype = OpndType_GPR;
- output->reg = op3.reg;
-
- if (expr1->rtype->size < 4)
- extend32(output, expr1->rtype, op3.reg);
-
- return;
- }
- }
-
- logical_expression(cond, label1, label2, label1);
- branch_label(label1);
- gen_ASS(expr, outputReg, outputRegHi, output);
- branch_label(label2);
-}
-
-void gen_FUNCCALL(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- if (is_intrinsic_function_call(expr))
- call_intrinsic_function(expr, outputReg, output);
- else
- call_function(expr, output);
-}
-
-void gen_OBJREF(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- symbol_operand(output, expr->data.objref);
-}
-
-void gen_UNEXPECTED(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- CError_FATAL(4160);
-}
-
-static int small(ENode *expr) {
- Type *type;
-
- type = expr->rtype;
- if (!ENODE_IS(expr, ETYPCON))
- return 0;
-
- do {
- expr = expr->data.monadic;
- } while (ENODE_IS(expr, ETYPCON) && (type = expr->rtype)->size == 4);
-
- return IS_TYPE_INT_OR_ENUM(type) && ((type->size < 2) || (type->size == 2 && !is_unsigned(type)));
-}
-
-void binary_operator(Opcode opcode, ENode *left, ENode *right, short outputReg, Operand *output) {
- Operand opleft;
- Operand opright;
- int reg;
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE_TO_GPR(right, &opright, right->rtype, 0);
- GEN_NODE_TO_GPR(left, &opleft, left->rtype, 0);
- } else {
- GEN_NODE_TO_GPR(left, &opleft, left->rtype, 0);
- GEN_NODE_TO_GPR(right, &opright, right->rtype, 0);
- }
-
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- if (opcode == PC_MULLW && small(left))
- emitpcode(opcode, reg, opright.reg, opleft.reg);
- else
- emitpcode(opcode, reg, opleft.reg, opright.reg);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void binary_immediate(Opcode opcode, ENode *left, SInt32 value, short outputReg, Operand *output) {
- Operand opleft;
- int reg;
-
- memclrw(&opleft, sizeof(Operand));
- GEN_NODE_TO_GPR(left, &opleft, left->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- if (opcode == PC_MULLI && value == 0)
- emitpcode(PC_LI, reg, 0);
- else if (opcode == PC_MULLI && value == 1)
- emitpcode(PC_MR, reg, opleft.reg);
- else
- emitpcode(opcode, reg, opleft.reg, value);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-void unary_operator(Opcode opcode, ENode *expr, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(opcode, reg, op.reg);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void or_xor_immediate(Opcode opcode, ENode *expr, SInt32 value, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- if (expr->rtype->size > 2 && value != (value & 0xFFFF)) {
- if (value & 0xFFFF) {
- emitpcode((opcode == PC_ORI) ? PC_ORIS : PC_XORIS, reg, op.reg, value >> 16);
- emitpcode(opcode, reg, reg, value & 0xFFFF);
- } else {
- emitpcode((opcode == PC_ORI) ? PC_ORIS : PC_XORIS, reg, op.reg, value >> 16);
- }
- } else {
- emitpcode(opcode, reg, op.reg, value & 0xFFFF);
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void shift_left_immediate(ENode *expr, short shift, short negate, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- if (negate)
- reg = ALLOC_GPR();
- else
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- emitpcode(PC_RLWINM, reg, op.reg, shift & 31, 0, 31 - (shift & 31));
-
- if (negate) {
- int tmp = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_NEG, tmp, reg);
- reg = tmp;
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void shift_right_immediate(ENode *expr, Type *type, short shift, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- if (is_unsigned(type))
- emitpcode(PC_RLWINM, reg, op.reg, (32 - (shift & 31)) & 31, (shift & 31) + (32 - (type->size * 8)), 31);
- else
- emitpcode(PC_SRAWI, reg, op.reg, shift & 31);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void signed_divide_by_power_of_2(ENode *expr, int shift, int negate, short outputReg, Operand *output) {
- Operand op;
- int reg;
- int tmpreg1;
- int tmpreg2;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- if (!copts.optimizesize && shift == 1) {
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpreg1, op.reg, 1, 31, 31);
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_ADD, tmpreg2, tmpreg1, op.reg);
- reg = (outputReg && !negate) ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, reg, tmpreg2, 1);
- } else {
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg1, op.reg, shift);
- reg = (outputReg && !negate) ? outputReg : ALLOC_GPR();
- emitpcode(PC_ADDZE, reg, tmpreg1);
- }
-
- if (negate) {
- int prevreg = reg;
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_NEG, reg, prevreg);
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void signed_mod_by_power_of_2(ENode *expr, int shift, int negate, short outputReg, Operand *output) {
- Operand op;
- int reg;
- int tmpreg1;
- int tmpreg2;
- int tmpreg3;
- int tmpreg4;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
-
- if (shift == 1) {
- emitpcode(PC_RLWINM, tmpreg1, op.reg, 1, 31, 31);
- emitpcode(PC_RLWINM, tmpreg2, op.reg, 0, 31, 31);
- emitpcode(PC_XOR, tmpreg3, tmpreg2, tmpreg1);
- emitpcode(PC_SUBF, reg, tmpreg1, tmpreg3);
- } else {
- tmpreg4 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpreg1, op.reg, 32 - shift, 0, 31 - (32 - shift));
- emitpcode(PC_RLWINM, tmpreg2, op.reg, 1, 31, 31);
- emitpcode(PC_SUBF, tmpreg3, tmpreg2, tmpreg1);
- emitpcode(PC_RLWINM, tmpreg4, tmpreg3, shift, 0, 31);
- emitpcode(PC_ADD, reg, tmpreg4, tmpreg2);
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void fp_binary_operator(Opcode opcode, ENode *left, ENode *right, short outputReg, Operand *output) {
- Operand opleft;
- Operand opright;
- int reg;
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE_TO_FPR(right, &opright, right->rtype, 0);
- GEN_NODE_TO_FPR(left, &opleft, left->rtype, 0);
- } else {
- GEN_NODE_TO_FPR(left, &opleft, left->rtype, 0);
- GEN_NODE_TO_FPR(right, &opright, right->rtype, 0);
- }
-
- reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(opcode, reg, opleft.reg, opright.reg);
-
- output->optype = OpndType_FPR;
- output->reg = reg;
-}
-
-void fp_unary_operator(Opcode opcode, ENode *expr, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE_TO_FPR(expr, &op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(opcode, reg, op.reg);
-
- output->optype = OpndType_FPR;
- output->reg = reg;
-}
-
-void fp_multiply_add(Opcode opcode, ENode *a, ENode *b, ENode *c, short outputReg, Operand *output) {
- Operand opA;
- Operand opB;
- Operand opC;
- int reg;
-
- memclrw(&opA, sizeof(Operand));
- memclrw(&opB, sizeof(Operand));
- memclrw(&opC, sizeof(Operand));
-
- if (c->hascall) {
- GEN_NODE_TO_FPR(c, &opC, c->rtype, 0);
- if (b->hascall) {
- GEN_NODE_TO_FPR(b, &opB, b->rtype, 0);
- GEN_NODE_TO_FPR(a, &opA, a->rtype, 0);
- } else {
- GEN_NODE_TO_FPR(a, &opA, a->rtype, 0);
- GEN_NODE_TO_FPR(b, &opB, b->rtype, 0);
- }
- } else {
- if (b->hascall) {
- GEN_NODE_TO_FPR(b, &opB, b->rtype, 0);
- GEN_NODE_TO_FPR(a, &opA, a->rtype, 0);
- GEN_NODE_TO_FPR(c, &opC, c->rtype, 0);
- } else {
- GEN_NODE_TO_FPR(a, &opA, a->rtype, 0);
- GEN_NODE_TO_FPR(b, &opB, b->rtype, 0);
- GEN_NODE_TO_FPR(c, &opC, c->rtype, 0);
- }
- }
-
- reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(opcode, reg, opA.reg, opB.reg, opC.reg);
-
- output->optype = OpndType_FPR;
- output->reg = reg;
-}
-
-void gen_COMPARE(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- expr = evaluate_and_skip_comma(expr);
- if (TYPE_IS_8BYTES(expr->data.diadic.right->rtype) || TYPE_IS_8BYTES(expr->data.diadic.left->rtype))
- I8_gen_condition(expr, output, 1);
- else
- gen_condition_gpr(expr, output, outputReg);
-}
-
-void gen_LOGICAL(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- ENodeType op;
-
- expr = evaluate_and_skip_comma(expr);
- inner = evaluate_and_skip_comma(expr->data.monadic);
- expr->data.monadic = inner;
-
- if (ENODE_IS(expr, ELOGNOT) && !ENODE_IS2(inner, ELAND, ELOR)) {
- op = inner->type;
- if (ENODE_IS(inner, ELOGNOT)) {
- switch (inner->data.monadic->type) {
- case ELOGNOT:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case ELAND:
- case ELOR:
- GEN_NODE(inner->data.monadic, output);
- if (expr->data.monadic->rtype->size < 4)
- extend32(output, expr->data.monadic->rtype, 0);
- ENSURE_GPR(output, expr->data.monadic->rtype, 0);
- return;
- }
- }
-
- if (ENODE_IS(inner, ENOTEQU) && !TYPE_IS_8BYTES(inner->data.diadic.left->rtype) && ENODE_IS(inner->data.diadic.right, EINTCONST) && inner->data.diadic.right->data.intval.lo == 0) {
- int tmpreg1;
- int tmpreg2;
- GEN_NODE(inner->data.diadic.left, output);
- if (inner->data.diadic.left->rtype->size < 4)
- extend32(output, inner->data.diadic.left->rtype, 0);
- ENSURE_GPR(output, inner->data.diadic.left->rtype, 0);
-
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- CError_ASSERT(4853, output->optype == OpndType_GPR);
-
- emitpcode(PC_CNTLZW, tmpreg2, output->reg);
- emitpcode(PC_RLWINM, tmpreg1, tmpreg2, 27, 5, 31);
- output->optype = OpndType_GPR;
- output->reg = tmpreg1;
- } else {
- int tmpreg1;
- int tmpreg2;
- ENodeType inverted;
-
- inverted = invert_relop(op);
- if (op != inverted && !IS_TYPE_FLOAT(inner->data.diadic.left->rtype)) {
- inner->type = inverted;
- gen_COMPARE(inner, 0, 0, output);
- inner->type = inverted;
- return;
- }
-
- GEN_NODE(inner, output);
- if (inner->rtype->size < 4)
- extend32(output, inner->rtype, 0);
- ENSURE_GPR(output, inner->rtype, 0);
-
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- CError_ASSERT(4883, output->optype == OpndType_GPR);
-
- emitpcode(PC_CNTLZW, tmpreg2, output->reg);
- emitpcode(PC_RLWINM, tmpreg1, tmpreg2, 27, 5, 31);
- output->optype = OpndType_GPR;
- output->reg = tmpreg1;
- }
- } else {
- PCodeLabel *label1;
- PCodeLabel *label2;
- int tmpreg;
-
- label1 = makepclabel();
- label2 = makepclabel();
-
- tmpreg = ALLOC_GPR();
- emitpcode(PC_LI, tmpreg, 0);
- logical_expression(expr, label1, label2, label1);
- branch_label(label1);
- emitpcode(PC_LI, tmpreg, 1);
- branch_label(label2);
- output->optype = OpndType_GPR;
- output->reg = tmpreg;
- }
-}
-
-void gen_NULLCHECK(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- PrecomputedOperand *precomp;
- int flag;
- int reg;
- PCodeLabel *label;
-
- left = expr->data.nullcheck.nullcheckexpr;
- right = expr->data.nullcheck.condexpr;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
- flag = !IS_TYPE_VOID(expr->rtype) && !expr->ignored;
-
- GEN_NODE(left, &opleft);
- if (left->rtype->size < 4)
- extend32(&opleft, left->rtype, 0);
- ENSURE_GPR(&opleft, left->rtype, 0);
-
- precomp = lalloc(sizeof(PrecomputedOperand));
- precomp->precompid = expr->data.nullcheck.precompid;
- precomp->operand = opleft;
- precomp->next = precomputedoperands;
- precomputedoperands = precomp;
-
- emitpcode(PC_CMPI, 0, opleft.reg, 0);
- if (flag) {
- emitpcode(PC_MR, reg = ALLOC_GPR(), opleft.reg);
- }
-
- label = makepclabel();
- branch_conditional(0, EEQU, 1, label);
- GEN_NODE(right, &opright);
- precomputedoperands = precomputedoperands->next;
-
- if (flag) {
- ENSURE_GPR(&opright, right->rtype, reg);
- if (opright.reg != reg)
- emitpcode(PC_MR, reg, opright.reg);
- output->optype = OpndType_GPR;
- output->reg = reg;
- }
-
- branch_label(label);
-}
-
-void gen_PRECOMP(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- PrecomputedOperand *precomp;
-
- for (precomp = precomputedoperands; precomp; precomp = precomp->next) {
- if (precomp->precompid == expr->data.precompid)
- break;
- }
-
- *output = precomp->operand;
-}
-
-void logical_expression(ENode *cond, PCodeLabel *if_true, PCodeLabel *if_false, PCodeLabel *end) {
- PCodeLabel *label;
- Operand op;
- memclrw(&op, sizeof(Operand));
-
- cond = evaluate_and_skip_comma(cond);
- switch (cond->type) {
- case ELAND:
- label = makepclabel();
- logical_expression(cond->data.diadic.left, label, if_false, label);
- branch_label(label);
- logical_expression(cond->data.diadic.right, if_true, if_false, end);
- break;
- case ELOR:
- label = makepclabel();
- logical_expression(cond->data.diadic.left, if_true, label, label);
- branch_label(label);
- logical_expression(cond->data.diadic.right, if_true, if_false, end);
- break;
- case ELOGNOT:
- logical_expression(cond->data.monadic, if_false, if_true, end);
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- if (TYPE_IS_8BYTES(cond->data.diadic.right->rtype) || TYPE_IS_8BYTES(cond->data.diadic.left->rtype))
- I8_gen_condition(cond, &op, 0);
- else
- gen_condition(cond, &op);
-
- if (end == if_true)
- branch_conditional(op.reg, op.regOffset, 0, if_false);
- else
- branch_conditional(op.reg, op.regOffset, 1, if_true);
- break;
- default:
- CError_FATAL(5160);
- }
-}
-
-static void logical_expression_nobranch(ENode *cond, Boolean invert, Operand *output) {
- cond = evaluate_and_skip_comma(cond);
- switch (cond->type) {
- case ELOGNOT:
- logical_expression_nobranch(cond->data.monadic, 1, output);
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- if (invert) {
- ENodeType nt = invert_relop(cond->type);
- CError_ASSERT(5190, nt != cond->type);
- cond->type = nt;
- }
-
- if (TYPE_IS_8BYTES(cond->data.diadic.right->rtype) || TYPE_IS_8BYTES(cond->data.diadic.left->rtype))
- I8_gen_condition(cond, output, 0);
- else
- gen_condition(cond, output);
-
- break;
- default:
- CError_FATAL(5206);
- }
-}
-
-static ENodeType invert_relop(ENodeType nt) {
- switch (nt) {
- 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 nt;
- }
-}
-
-static int reverse_relop(int nt) {
- switch (nt) {
- case ELESS: return EGREATER;
- case EGREATER: return ELESS;
- case ELESSEQU: return EGREATEREQU;
- case EGREATEREQU: return ELESSEQU;
- default: return nt;
- }
-}
-
-void gen_condition(ENode *cond, Operand *output) {
- ENode *left;
- ENode *right;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- if (IS_TYPE_FLOAT(left->rtype)) {
- compare_floating(cond->type, left, right, output);
- return;
- }
-
- if (ENODE_IS(right, EINTCONST)) {
- if (is_unsigned(left->rtype)) {
- UInt32 val = right->data.intval.lo;
- if (FITS_IN_USHORT(val)) {
- compare_immediate(cond->type, left, val, output);
- return;
- } else if (ENODE_IS2(cond, EEQU, ENOTEQU)) {
- compare_immediate_long(cond->type, left, val, output);
- return;
- }
- } else {
- UInt32 val = right->data.intval.lo;
- if (FITS_IN_SHORT(val)) {
- compare_immediate(cond->type, left, val, output);
- return;
- } else if (ENODE_IS2(cond, EEQU, ENOTEQU)) {
- compare_immediate_long(cond->type, left, val, output);
- return;
- }
- }
- } else if (ENODE_IS(left, EINTCONST)) {
- if (is_unsigned(right->rtype)) {
- UInt32 val = left->data.intval.lo;
- if (FITS_IN_USHORT(val)) {
- compare_immediate(reverse_relop(cond->type), right, val, output);
- return;
- } else if (ENODE_IS2(cond, EEQU, ENOTEQU)) {
- compare_immediate_long(reverse_relop(cond->type), right, val, output);
- return;
- }
- } else {
- UInt32 val = left->data.intval.lo;
- if (FITS_IN_SHORT(val)) {
- compare_immediate(reverse_relop(cond->type), right, val, output);
- return;
- } else if (ENODE_IS2(cond, EEQU, ENOTEQU)) {
- compare_immediate_long(reverse_relop(cond->type), right, val, output);
- return;
- }
- }
- }
-
- compare_integer(cond->type, left, right, output);
-}
-
-void gen_condition_gpr(ENode *cond, Operand *output, short outputReg) {
- ENode *left;
- ENode *right;
- Operand condOp;
- int finalReg;
- int tmpReg;
- int tmpReg2;
- int tmpReg3;
- int tmpReg4;
- int a;
- int b;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- memclrw(&condOp, sizeof(Operand));
-
- if (!IS_TYPE_FLOAT(left->rtype)) {
- Operand op1;
- Operand op2;
- Operand opTmp;
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
- memclrw(&opTmp, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &op2);
- if (!IS_INT_CONST_ZERO(right)) {
- if (right->rtype->size < 4)
- extend32(&op2, right->rtype, 0);
- ENSURE_GPR(&op2, right->rtype, 0);
- }
-
- GEN_NODE(left, &op1);
- if (left->rtype->size < 4)
- extend32(&op1, left->rtype, 0);
- ENSURE_GPR(&op1, left->rtype, 0);
- } else {
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
- if (left->rtype->size < 4)
- extend32(&op1, left->rtype, 0);
-
- GEN_NODE(right, &op2);
- if (!IS_INT_CONST_ZERO(right)) {
- if (right->rtype->size < 4)
- extend32(&op2, right->rtype, 0);
- ENSURE_GPR(&op2, right->rtype, 0);
- }
- }
-
- switch (cond->type) {
- case EEQU:
- if (
- copts.peephole &&
- IS_INT_CONST(right) &&
- pclastblock->pcodeCount > 0 &&
- pclastblock->lastPCode->op == PC_RLWINM &&
- pclastblock->lastPCode->args[0].data.reg.reg == op1.reg
- )
- {
- PCode *pc = pclastblock->lastPCode;
- SInt32 a = pc->args[2].data.imm.value;
- SInt32 b = pc->args[3].data.imm.value;
- SInt32 value = right->data.intval.lo;
- if (b == pc->args[4].data.imm.value) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- if (value != (value & 1)) {
- emitpcode(PC_LI, finalReg, 0);
- } else if (value == 0) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM, tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- emitpcode(PC_XORI, finalReg, tmpReg, 1);
- } else if (value == 1) {
- emitpcode(
- PC_RLWINM, finalReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- } else {
- CError_FATAL(5434);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_CNTLZW, tmpReg, op1.reg, 0);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg, 27, 5, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op1.reg, op2.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_CNTLZW, tmpReg2, tmpReg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg2, 27, 5, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- case ENOTEQU:
- if (
- copts.peephole &&
- IS_INT_CONST(right) &&
- pclastblock->pcodeCount > 0 &&
- pclastblock->lastPCode->op == PC_RLWINM &&
- pclastblock->lastPCode->args[0].data.reg.reg == op1.reg
- )
- {
- PCode *pc = pclastblock->lastPCode;
- SInt32 a = pc->args[2].data.imm.value;
- SInt32 b = pc->args[3].data.imm.value;
- SInt32 value = right->data.intval.lo;
- if (b == pc->args[4].data.imm.value) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- if (value != (value & 1)) {
- emitpcode(PC_LI, finalReg, 1);
- } else if (value == 0) {
- emitpcode(
- PC_RLWINM, finalReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- } else if (value == 1) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM, tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- emitpcode(PC_XORI, finalReg, tmpReg, 1);
- } else {
- CError_FATAL(5503);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_ADDIC, tmpReg, op1.reg, -1);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg, op1.reg);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_NEG, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_OR, tmpReg2, tmpReg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg2, 1, 31, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op1.reg, op2.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ADDIC, tmpReg2, tmpReg, -1);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg2, tmpReg);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op1.reg, op2.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg2, op2.reg, op1.reg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_OR, tmpReg3, tmpReg, tmpReg2);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg3, 1, 31, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- case EGREATEREQU:
- if (!is_unsigned(left->rtype) && IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg, op1.reg, 1, 31, 31);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_XORI, finalReg, tmpReg, 1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- opTmp = op2;
- op2 = op1;
- op1 = opTmp;
-
- case ELESSEQU:
- if (is_unsigned(left->rtype)) {
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_LI, tmpReg, -1);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg2, op1.reg, op2.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFZE, finalReg, tmpReg);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op1.reg, op2.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ORC, tmpReg2, op2.reg, op1.reg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg3, tmpReg, 31, 1, 31);
- tmpReg4 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg4, tmpReg3, tmpReg2);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg4, 1, 31, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_LI, tmpReg, 1);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_CNTLZW, tmpReg2, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWNM, finalReg, tmpReg, tmpReg2, 31, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpReg2, op2.reg, 31);
- tmpReg = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg, op1.reg, 1, 31, 31);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg3, op1.reg, op2.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_ADDE, finalReg, tmpReg2, tmpReg);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- case EGREATER:
- if (!is_unsigned(left->rtype) && IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_NEG, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ANDC, tmpReg2, tmpReg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg2, 1, 31, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- opTmp = op2;
- op2 = op1;
- op1 = opTmp;
-
- case ELESS:
- if (is_unsigned(left->rtype)) {
- if (left->rtype->size <= 2) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op2.reg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg, 1, 31, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- } else {
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBFE, tmpReg2, tmpReg, tmpReg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_NEG, finalReg, tmpReg2);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_XOR, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_CNTLZW, tmpReg2, tmpReg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_SLW, tmpReg3, op2.reg, tmpReg2);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg3, 1, 31, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- return;
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, op1.reg, 1, 31, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- tmpReg = ALLOC_GPR();
- emitpcode(PC_XOR, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpReg2, tmpReg, 1);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_AND, tmpReg3, tmpReg, op2.reg);
- tmpReg4 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg4, tmpReg3, tmpReg2);
-
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, finalReg, tmpReg4, 1, 31, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- default:
- CError_FATAL(5777);
- }
- }
-
- gen_condition(cond, &condOp);
- emitpcode(PC_MFCR, tmpReg = used_virtual_registers[RegClass_GPR]++);
- a = 0;
- b = condOp.reg * 4;
- switch (condOp.regOffset) {
- case ENOTEQU:
- a = 1;
- case EEQU:
- b += 2;
- break;
- case EGREATEREQU:
- a = 1;
- break;
- case ELESSEQU:
- a = 1;
- case EGREATER:
- b += 1;
- break;
- }
-
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- if (a) {
- emitpcode(PC_RLWINM, tmpReg, tmpReg, b + 1, 31, 31);
- emitpcode(PC_XORI, finalReg, tmpReg, 1);
- } else {
- emitpcode(PC_RLWINM, finalReg, tmpReg, b + 1, 31, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
-}
-
-void gen_negated_condition_gpr(ENode *cond, Operand *output, short outputReg) {
- ENode *left;
- ENode *right;
- Operand op1;
- Operand op2;
- Operand opTmp;
- int finalReg;
- int tmpReg;
- int tmpReg2;
- int tmpReg3;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- CError_ASSERT(5843, TYPE_FITS_IN_REGISTER(left->rtype) && TYPE_FITS_IN_REGISTER(right->rtype));
-
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
- memclrw(&opTmp, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &op2);
- if (!IS_INT_CONST_ZERO(right)) {
- if (right->rtype->size < 4)
- extend32(&op2, right->rtype, 0);
- ENSURE_GPR(&op2, right->rtype, 0);
- }
-
- GEN_NODE(left, &op1);
- if (left->rtype->size < 4)
- extend32(&op1, left->rtype, 0);
- ENSURE_GPR(&op1, left->rtype, 0);
- } else {
- GEN_NODE(left, &op1);
- ENSURE_GPR(&op1, left->rtype, 0);
- if (left->rtype->size < 4)
- extend32(&op1, left->rtype, 0);
-
- GEN_NODE(right, &op2);
- if (!IS_INT_CONST_ZERO(right)) {
- if (right->rtype->size < 4)
- extend32(&op2, right->rtype, 0);
- ENSURE_GPR(&op2, right->rtype, 0);
- }
- }
-
- switch (cond->type) {
- case EEQU:
- if (
- copts.peephole &&
- IS_INT_CONST(right) &&
- pclastblock->pcodeCount > 0 &&
- pclastblock->lastPCode->op == PC_RLWINM &&
- pclastblock->lastPCode->args[0].data.reg.reg == op1.reg
- )
- {
- PCode *pc = pclastblock->lastPCode;
- SInt32 a = pc->args[2].data.imm.value;
- SInt32 b = pc->args[3].data.imm.value;
- SInt32 value = right->data.intval.lo;
- if (b == pc->args[4].data.imm.value) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- if (value != (value & 1)) {
- emitpcode(PC_LI, finalReg, 0);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (value == 0) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM, tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- emitpcode(PC_ADDI, finalReg, tmpReg, 0, -1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (value == 1) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM,
- tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31,
- 31,
- 31);
- emitpcode(PC_NEG, finalReg, tmpReg);
- output->optype = OpndType_GPR;
- output->reg = tmpReg; // bug???
- return;
- }
-
- CError_FATAL(5923);
- }
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_ADDIC, tmpReg, op1.reg, -1);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg, tmpReg);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_CNTLZW, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg2, tmpReg, 27, 31, 31);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_NEG, finalReg, tmpReg2);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ADDIC, tmpReg2, tmpReg, -1);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg2, tmpReg2);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg2, op1.reg, op2.reg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_NOR, tmpReg3, tmpReg, tmpReg2);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, tmpReg3, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- case ENOTEQU:
- if (
- copts.peephole &&
- IS_INT_CONST(right) &&
- pclastblock->pcodeCount > 0 &&
- pclastblock->lastPCode->op == PC_RLWINM &&
- pclastblock->lastPCode->args[0].data.reg.reg == op1.reg
- )
- {
- PCode *pc = pclastblock->lastPCode;
- SInt32 a = pc->args[2].data.imm.value;
- SInt32 b = pc->args[3].data.imm.value;
- SInt32 value = right->data.intval.lo;
- if (b == pc->args[4].data.imm.value) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
-
- if (value != (value & 1)) {
- emitpcode(PC_LI, finalReg, -1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (value == 0) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM, tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- emitpcode(PC_NEG, finalReg, tmpReg);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (value == 1) {
- tmpReg = ALLOC_GPR();
- emitpcode(
- PC_RLWINM, tmpReg,
- pc->args[1].data.reg.reg,
- (a + b + 1) & 31, 31, 31);
- emitpcode(PC_ADDI, finalReg, tmpReg, 0, -1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- CError_FATAL(6031);
- }
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBFIC, tmpReg, op1.reg, 0);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg, tmpReg);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_NEG, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_OR, tmpReg2, tmpReg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, tmpReg2, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (copts.optimizesize) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBFIC, tmpReg2, tmpReg, 0);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg2, tmpReg2);
- } else {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg2, op1.reg, op2.reg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_OR, tmpReg3, tmpReg, tmpReg2);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, tmpReg3, 31);
- }
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- case EGREATEREQU:
- if (!is_unsigned(left->rtype) && IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg, op1.reg, 1, 31, 31);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_ADDI, finalReg, tmpReg, 0, -1);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- opTmp = op2;
- op2 = op1;
- op1 = opTmp;
-
- case ELESSEQU:
- if (is_unsigned(left->rtype)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg, op1.reg, op2.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ADDZE, tmpReg2, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBF, finalReg, tmpReg2, op1.reg);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_NEG, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ORC, tmpReg2, op1.reg, tmpReg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, tmpReg2, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- tmpReg = ALLOC_GPR();
- emitpcode(PC_XORIS, tmpReg, op1.reg, 0x8000);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_SUBF, tmpReg2, op1.reg, op2.reg);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_ADDC, tmpReg3, tmpReg2, tmpReg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg3, tmpReg3);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- case EGREATER:
- if (!is_unsigned(left->rtype) && IS_INT_CONST_ZERO(right)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_NEG, tmpReg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_ANDC, tmpReg2, tmpReg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, tmpReg2, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
- opTmp = op2;
- op2 = op1;
- op1 = opTmp;
-
- case ELESS:
- if (is_unsigned(left->rtype)) {
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg, op2.reg, op1.reg);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg, tmpReg);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- if (IS_INT_CONST_ZERO(right)) {
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SRAWI, finalReg, op1.reg, 31);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
- }
-
- tmpReg = ALLOC_GPR();
- emitpcode(PC_SUBFC, tmpReg, op2.reg, op1.reg);
- tmpReg2 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg2, op2.reg, 1, 31, 31);
- tmpReg3 = ALLOC_GPR();
- emitpcode(PC_RLWINM, tmpReg3, op1.reg, 1, 31, 31);
- finalReg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_SUBFE, finalReg, tmpReg3, tmpReg2);
- output->optype = OpndType_GPR;
- output->reg = finalReg;
- return;
-
- default:
- CError_FATAL(6240);
- }
-}
-
-void compare_floating(short nt, ENode *left, ENode *right, Operand *output) {
- Operand opleft;
- Operand opright;
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE_TO_FPR(right, &opright, right->rtype, 0);
- GEN_NODE_TO_FPR(left, &opleft, left->rtype, 0);
- } else {
- GEN_NODE_TO_FPR(left, &opleft, left->rtype, 0);
- GEN_NODE_TO_FPR(right, &opright, right->rtype, 0);
- }
-
- emitpcode((nt == EEQU || nt == ENOTEQU) ? PC_FCMPU : PC_FCMPO, 0, opleft.reg, opright.reg);
- if (nt == ELESSEQU) {
- emitpcode(PC_CROR, 0, 2, 0, 0, 0, 2);
- nt = EEQU;
- } else if (nt == EGREATEREQU) {
- emitpcode(PC_CROR, 0, 2, 0, 1, 0, 2);
- nt = EEQU;
- }
-
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = nt;
-}
-
-void compare_integer(short nt, ENode *left, ENode *right, Operand *output) {
- Operand opleft;
- Operand opright;
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (right->rtype->size < 4)
- extend32(&opright, right->rtype, 0);
- ENSURE_GPR(&opright, right->rtype, 0);
-
- GEN_NODE(left, &opleft);
- if (left->rtype->size < 4)
- extend32(&opleft, left->rtype, 0);
- ENSURE_GPR(&opleft, left->rtype, 0);
- } else {
- GEN_NODE(left, &opleft);
- ENSURE_GPR(&opleft, left->rtype, 0);
- if (left->rtype->size < 4)
- extend32(&opleft, left->rtype, 0);
-
- GEN_NODE(right, &opright);
- if (right->rtype->size < 4)
- extend32(&opright, right->rtype, 0);
- ENSURE_GPR(&opright, right->rtype, 0);
- }
-
- emitpcode(is_unsigned(left->rtype) ? PC_CMPL : PC_CMP, 0, opleft.reg, opright.reg);
-
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = nt;
-}
-
-void compare_immediate(short nt, ENode *left, SInt32 value, Operand *output) {
- int postIncFlag;
- short postIncReg;
- Operand op;
- SInt32 postIncValue;
-
- memclrw(&op, sizeof(Operand));
-
- postIncFlag = ispostincrementopportunity(left, &op, &postIncValue);
- if (!postIncFlag) {
- GEN_NODE(left, &op);
- if (op.optype != OpndType_CRField) {
- if (left->rtype->size < 4)
- extend32(&op, left->rtype, 0);
- else
- ENSURE_GPR(&op, left->rtype, 0);
- }
- } else {
- postIncReg = op.reg;
- if (left->rtype->size < 4)
- extend32(&op, left->rtype, 0);
- ENSURE_GPR(&op, left->rtype, 0);
- }
-
- if (op.optype == OpndType_CRField) {
- if (
- (nt == EEQU && value == 1) ||
- (nt == ENOTEQU && value == 0) ||
- (nt == EGREATER && value == 0) ||
- (nt == EGREATEREQU && value == 1)
- )
- {
- *output = op;
- return;
- }
-
- if (
- (nt == EEQU && value == 0) ||
- (nt == ENOTEQU && value == 1) ||
- (nt == ELESS && value == 1) ||
- (nt == ELESSEQU && value == 0)
- )
- {
- *output = op;
- switch (op.regOffset) {
- case EEQU:
- output->regOffset = ENOTEQU;
- return;
- case ENOTEQU:
- output->regOffset = EEQU;
- return;
- case ELESS:
- output->regOffset = EGREATEREQU;
- return;
- case EGREATER:
- output->regOffset = ELESSEQU;
- return;
- case ELESSEQU:
- output->regOffset = EGREATER;
- return;
- case EGREATEREQU:
- output->regOffset = ELESS;
- return;
- }
- }
-
- ENSURE_GPR(&op, left->rtype, 0);
- }
-
- if (
- copts.peephole &&
- value == 0 &&
- pclastblock->pcodeCount > 0 &&
- pclastblock->lastPCode->op != PC_RLWINM &&
- (PCODE_FLAG_SET_F(pclastblock->lastPCode) & (fIsMove | fSideEffects | fCanSetRecordBit | fOpTypeGPR)) == (fCanSetRecordBit | fOpTypeGPR) &&
- pclastblock->lastPCode->args[0].data.reg.reg == op.reg &&
- (!is_unsigned(left->rtype) || nt == EEQU || nt == ENOTEQU)
- )
- {
- pcsetrecordbit(pclastblock->lastPCode);
- } else {
- emitpcode(is_unsigned(left->rtype) ? PC_CMPLI : PC_CMPI, 0, op.reg, value);
- }
-
- if (postIncFlag)
- add_register_immediate(postIncReg, postIncReg, postIncValue);
-
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = nt;
-}
-
-void compare_immediate_long(short nt, ENode *left, SInt32 value, Operand *output) {
- int postIncFlag;
- short postIncReg;
- int outputReg;
- Operand op;
- SInt32 postIncValue;
-
- memclrw(&op, sizeof(Operand));
-
- postIncFlag = ispostincrementopportunity(left, &op, &postIncValue);
- if (!postIncFlag) {
- GEN_NODE(left, &op);
- } else {
- postIncReg = op.reg;
- }
-
- if (left->rtype->size < 4)
- extend32(&op, left->rtype, 0);
- ENSURE_GPR(&op, left->rtype, 0);
-
- outputReg = ALLOC_GPR();
- emitpcode(PC_ADDIS, outputReg, op.reg, 0, (SInt16) (~(value >> 16) + 1));
- emitpcode(PC_CMPLI, 0, outputReg, value & 0xFFFF);
-
- if (postIncFlag)
- add_register_immediate(postIncReg, postIncReg, postIncValue);
-
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = nt;
-}
-
-static int ismask(SInt32 value, short *first, short *last) {
- int start, end, bit;
- start = end = -1;
- for (bit = 31; bit >= 0; bit--) {
- if (value & 1) {
- if (start != -1)
- return 0;
- if (end == -1)
- end = bit;
- } else {
- if (end != -1 && start == -1)
- start = bit + 1;
- }
- value >>= 1;
- }
-
- if (end == -1)
- return 0;
- if (start == -1)
- start = 0;
- *first = start;
- *last = end;
- return 1;
-}
-
-int ismaskconstant(SInt32 value, short *first, short *last) {
- short my_first;
- short my_last;
- if (ismask(value, first, last))
- return 1;
-
- if (value && ismask(~value, &my_first, &my_last)) {
- *first = my_last + 1;
- *last = my_first - 1;
- return 1;
- } else {
- return 0;
- }
-}
-
-static void shift_and_mask(ENode *expr, short a, short b, short c, short outputReg, Operand *output) {
- Operand op;
- int reg;
-
- memclrw(&op, sizeof(Operand));
- GEN_NODE(expr, &op);
- ENSURE_GPR(&op, expr->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, reg, op.reg, a, b, c);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-int ispostincrementopportunity(ENode *expr, Operand *op, SInt32 *value) {
- Type *type;
- int reg;
-
- type = expr->rtype;
- if (!ENODE_IS2(expr, EPOSTINC, EPOSTDEC))
- return 0;
- if (!ENODE_IS(expr->data.monadic, EINDIRECT))
- return 0;
- if (!ENODE_IS(expr->data.monadic->data.monadic, EOBJREF))
- return 0;
-
- reg = OBJECT_REG(expr->data.monadic->data.monadic->data.objref);
- if (!reg)
- return 0;
-
- if (IS_TYPE_POINTER(type)) {
- if (ENODE_IS(expr, EPOSTINC))
- *value = TPTR_TARGET(type)->size;
- else
- *value = -TPTR_TARGET(type)->size;
- } else {
- if (ENODE_IS(expr, EPOSTINC))
- *value = 1;
- else
- *value = -1;
- }
-
- op->optype = OpndType_GPR;
- op->reg = reg;
- return 1;
-}
-
-void add_register_immediate(short regA, short regB, SInt32 value) {
- if (!FITS_IN_SHORT(value)) {
- emitpcode(PC_ADDIS, regA, regB, 0, HIGH_PART(value));
- if (LOW_PART(value))
- emitpcode(PC_ADDI, regA, regA, 0, LOW_PART(value));
- } else {
- emitpcode(PC_ADDI, regA, regB, 0, value);
- }
-}
-
-static int ispowerof2(SInt32 val) {
- int bit = getbit(val);
- return (bit > 0 && bit < 31) ? bit : 0;
-}
-
-void I8_gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- int is_uns;
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- short tmpreg1;
- short tmpreg2;
- SInt32 skipleft;
- SInt32 skipright;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
-
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
- } else {
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
-
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
- }
-
- reg = ALLOC_GPR();
- regHi = ALLOC_GPR();
- is_uns = is_unsigned(expr->rtype) != 0;
- skipleft = GetSizeSkip(left);
- skipright = GetSizeSkip(right);
-
- if (skipleft < skipright) {
- Operand tmpop;
- SInt32 tmp;
-
- expr->data.diadic.left = right;
- expr->data.diadic.right = left;
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
-
- tmpop = opright;
- opright = opleft;
- opleft = tmpop;
-
- tmp = skipleft;
- skipleft = skipright;
- skipright = tmp;
- }
-
- switch (skipleft + skipright) {
- case 1 + 1:
- case 1 + 2:
- case 2 + 2:
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_ADDIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo)) {
- emitpcode(PC_ADDIC, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- } else {
- emitpcode(PC_ADDC, reg, opleft.reg, opright.reg);
- }
- if (is_uns)
- emitpcode(PC_LI, regHi, 0);
- else
- emitpcode(PC_SRAWI, regHi, reg, 31);
- break;
- case 1 + 4:
- case 2 + 4:
- case 4 + 4:
- if (!is_uns) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg2, opleft.reg, 31);
- emitpcode(PC_SRAWI, tmpreg1, opright.reg, 31);
- }
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_ADDIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo)) {
- emitpcode(PC_ADDIC, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- } else {
- emitpcode(PC_ADDC, reg, opleft.reg, opright.reg);
- }
- if (is_uns) {
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_LI, tmpreg1, 0);
- emitpcode(PC_ADDZE, regHi, tmpreg1);
- } else {
- emitpcode(PC_ADDE, regHi, tmpreg1, tmpreg2);
- }
- break;
- case 1 + 8:
- case 2 + 8:
- case 4 + 8:
- CError_ASSERT(6933, skipleft == 8);
- if (!is_uns) {
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg2, opright.reg, 31);
- }
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo) && left->data.intval.hi == 0) {
- emitpcode(PC_ADDIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo) && right->data.intval.hi == 0) {
- emitpcode(PC_ADDIC, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- } else {
- emitpcode(PC_ADDC, reg, opleft.reg, opright.reg);
- }
- if (is_uns)
- emitpcode(PC_ADDZE, regHi, opleft.regHi);
- else
- emitpcode(PC_ADDE, regHi, opleft.regHi, tmpreg2);
- break;
- case 8 + 8:
- emitpcode(PC_ADDC, reg, opleft.reg, opright.reg);
- emitpcode(PC_ADDE, regHi, opleft.regHi, opright.regHi);
- break;
- default:
- CError_FATAL(6979);
- }
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- short reg;
- short regHi;
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
-
- load_immediate(reg, expr->data.intval.lo);
- load_immediate(regHi, expr->data.intval.hi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_SUB(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- int is_uns;
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- short tmpreg1;
- short tmpreg2;
- short tmpreg3;
- SInt32 skipleft;
- SInt32 skipright;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
-
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
- } else {
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
-
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
- }
-
- reg = ALLOC_GPR();
- regHi = ALLOC_GPR();
- is_uns = is_unsigned(expr->rtype) != 0;
- skipleft = GetSizeSkip(left);
- skipright = GetSizeSkip(right);
-
- switch (skipleft + skipright) {
- case 1 + 1:
- case 1 + 2:
- case 2 + 2:
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_SUBFIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else {
- emitpcode(PC_SUBFC, reg, opright.reg, opleft.reg);
- }
- if (is_uns)
- emitpcode(PC_LI, regHi, 0);
- else
- emitpcode(PC_SRAWI, regHi, reg, 31);
- break;
- case 1 + 4:
- case 2 + 4:
- case 4 + 4:
- if (!is_uns) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg2, opleft.reg, 31);
- emitpcode(PC_SRAWI, tmpreg1, opright.reg, 31);
- }
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_SUBFIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else {
- emitpcode(PC_SUBFC, reg, opright.reg, opleft.reg);
- }
- if (is_uns) {
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_LI, tmpreg1, 0);
- emitpcode(PC_SUBFZE, regHi, tmpreg1);
- } else {
- emitpcode(PC_SUBFE, regHi, tmpreg1, tmpreg2);
- }
- break;
- case 1 + 8:
- case 2 + 8:
- case 4 + 8:
- if (skipleft < skipright) {
- emitpcode(PC_SUBFC, reg, opright.reg, opleft.reg);
- emitpcode(PC_SUBFE, regHi, opright.regHi, opleft.regHi);
- } else {
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo) && left->data.intval.hi == 0) {
- emitpcode(PC_SUBFIC, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else {
- emitpcode(PC_SUBFC, reg, opright.reg, opleft.reg);
- }
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_LI, tmpreg1, 0);
- emitpcode(PC_SUBFE, regHi, tmpreg1, opleft.regHi);
- }
- break;
- case 8 + 8:
- emitpcode(PC_SUBFC, reg, opright.reg, opleft.reg);
- emitpcode(PC_SUBFE, regHi, opright.regHi, opleft.regHi);
- break;
- default:
- CError_FATAL(7211);
- }
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_XOR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
-
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- } else {
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
-
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- }
-
- CError_ASSERT(7254, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
-
- emitpcode(PC_XOR, reg, opleft.reg, opright.reg);
- emitpcode(PC_XOR, regHi, opleft.regHi, opright.regHi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_OR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
-
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- } else {
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
-
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- }
-
- CError_ASSERT(7304, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
-
- emitpcode(PC_OR, reg, opleft.reg, opright.reg);
- emitpcode(PC_OR, regHi, opleft.regHi, opright.regHi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_AND(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- Operand opleft;
- Operand opright;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
-
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- } else {
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
-
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- }
-
- CError_ASSERT(7354, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
-
- emitpcode(PC_AND, reg, opleft.reg, opright.reg);
- emitpcode(PC_AND, regHi, opleft.regHi, opright.regHi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-int I8_getbit(UInt64 val) {
- switch (val) {
- case 0: return -1;
- case 1ULL << 0: return 0;
- case 1ULL << 1: return 1;
- case 1ULL << 2: return 2;
- case 1ULL << 3: return 3;
- case 1ULL << 4: return 4;
- case 1ULL << 5: return 5;
- case 1ULL << 6: return 6;
- case 1ULL << 7: return 7;
- case 1ULL << 8: return 8;
- case 1ULL << 9: return 9;
- case 1ULL << 10: return 10;
- case 1ULL << 11: return 11;
- case 1ULL << 12: return 12;
- case 1ULL << 13: return 13;
- case 1ULL << 14: return 14;
- case 1ULL << 15: return 15;
- case 1ULL << 16: return 16;
- case 1ULL << 17: return 17;
- case 1ULL << 18: return 18;
- case 1ULL << 19: return 19;
- case 1ULL << 20: return 20;
- case 1ULL << 21: return 21;
- case 1ULL << 22: return 22;
- case 1ULL << 23: return 23;
- case 1ULL << 24: return 24;
- case 1ULL << 25: return 25;
- case 1ULL << 26: return 26;
- case 1ULL << 27: return 27;
- case 1ULL << 28: return 28;
- case 1ULL << 29: return 29;
- case 1ULL << 30: return 30;
- case 1ULL << 31: return 31;
- case 1ULL << 32: return 32;
- case 1ULL << 33: return 33;
- case 1ULL << 34: return 34;
- case 1ULL << 35: return 35;
- case 1ULL << 36: return 36;
- case 1ULL << 37: return 37;
- case 1ULL << 38: return 38;
- case 1ULL << 39: return 39;
- case 1ULL << 40: return 40;
- case 1ULL << 41: return 41;
- case 1ULL << 42: return 42;
- case 1ULL << 43: return 43;
- case 1ULL << 44: return 44;
- case 1ULL << 45: return 45;
- case 1ULL << 46: return 46;
- case 1ULL << 47: return 47;
- case 1ULL << 48: return 48;
- case 1ULL << 49: return 49;
- case 1ULL << 50: return 50;
- case 1ULL << 51: return 51;
- case 1ULL << 52: return 52;
- case 1ULL << 53: return 53;
- case 1ULL << 54: return 54;
- case 1ULL << 55: return 55;
- case 1ULL << 56: return 56;
- case 1ULL << 57: return 57;
- case 1ULL << 58: return 58;
- case 1ULL << 59: return 59;
- case 1ULL << 60: return 60;
- case 1ULL << 61: return 61;
- case 1ULL << 62: return 62;
- case 1ULL << 63: return 63;
- default: return -2;
- }
-}
-
-int I8_log2n(UInt64 val) {
- int bit = I8_getbit(val);
- return (bit > 0 && bit < 63) ? bit : 0;
-}
-
-void I8_ShiftLeftImmediate(Operand opnd, SInt32 value, int is_unsigned, SInt32 size, short reg, short regHi) {
- if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg)
- CError_FATAL(7703);
-
- if (value < 32) {
- emitpcode(PC_RLWINM, reg, opnd.reg, value, 0, 31 - value);
- if (size > 4) {
- emitpcode(PC_RLWINM, regHi, opnd.regHi, value, 0, 31 - value);
- emitpcode(PC_RLWIMI, regHi, opnd.reg, value, 32 - value, 31);
- } else {
- emitpcode(PC_RLWINM, regHi, opnd.reg, value, 32 - value, 31);
- }
- } else if (value <= 63) {
- if (value == 32)
- emitpcode(PC_MR, regHi, opnd.reg);
- else
- emitpcode(PC_RLWINM, regHi, opnd.reg, value - 32, 0, 63 - value);
- emitpcode(PC_LI, reg, 0);
- } else {
- CError_FATAL(7732);
- }
-}
-
-void I8_ShiftRightImmediate(Operand opnd, SInt32 value, int is_unsigned, short reg, short regHi, int unk) {
- short tmpreg1;
- short tmpreg2;
- short tmpreg3;
- short tmpreg4;
-
- if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg)
- CError_FATAL(7756);
-
- if (value < 32) {
- emitpcode(PC_RLWINM, reg, opnd.reg, 32 - value, 0, 31);
- emitpcode(PC_RLWIMI, reg, opnd.regHi, 32 - value, 0, value - 1);
- if (is_unsigned) {
- emitpcode(PC_RLWINM, regHi, opnd.regHi, 32 - value, value, 31);
- } else if (unk) {
- tmpreg1 = ALLOC_GPR();
- emitpcode(PC_MR, tmpreg1, opnd.regHi);
- emitpcode(PC_RLWIMI, tmpreg1, opnd.reg, 0, 31 - (value - 1), 31);
- emitpcode(PC_SRAWI, regHi, tmpreg1, value);
- } else {
- emitpcode(PC_SRAWI, regHi, opnd.regHi, value);
- }
- } else if (value == 32) {
- if (is_unsigned) {
- emitpcode(PC_MR, reg, opnd.regHi);
- emitpcode(PC_LI, regHi, 0);
- } else if (unk) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- emitpcode(PC_NEG, tmpreg1, opnd.reg);
- emitpcode(PC_OR, tmpreg2, tmpreg1, opnd.reg);
- emitpcode(PC_RLWINM, tmpreg3, tmpreg2, 1, 31, 31);
- emitpcode(PC_RLWIMI, tmpreg3, opnd.regHi, 0, 0, 0);
- emitpcode(PC_MR, reg, opnd.regHi);
- emitpcode(PC_SRAWI, regHi, value, 31);
- } else {
- emitpcode(PC_MR, reg, opnd.regHi);
- emitpcode(PC_SRAWI, regHi, opnd.regHi, 31);
- }
- } else if (value <= 63) {
- if (is_unsigned) {
- emitpcode(PC_RLWINM, reg, opnd.regHi, 64 - value, value - 32, 31);
- emitpcode(PC_LI, regHi, 0);
- } else if (unk) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- emitpcode(PC_NEG, tmpreg1, opnd.reg);
- emitpcode(PC_OR, tmpreg2, tmpreg1, opnd.reg);
- emitpcode(PC_RLWINM, tmpreg3, tmpreg2, 1, 31, 31);
- emitpcode(PC_OR, tmpreg4, opnd.regHi, tmpreg3);
- emitpcode(PC_SRAWI, regHi, opnd.regHi, 31);
- emitpcode(PC_SRAWI, reg, tmpreg4, value - 32);
- } else {
- emitpcode(PC_SRAWI, reg, opnd.regHi, value - 32);
- emitpcode(PC_SRAWI, regHi, opnd.regHi, 31);
- }
- } else {
- CError_FATAL(7866);
- }
-}
-
-void I8_gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- int is_uns;
- ENode *left;
- ENode *right;
- short reg;
- short regHi;
- short tmpreg1;
- short tmpreg2;
- short tmpreg3;
- short tmpreg4;
- SInt32 skipleft;
- SInt32 skipright;
- Operand opleft;
- Operand opright;
- SInt64 leftval;
- SInt64 rightval;
- int shift;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
- skipleft = GetSizeSkip(left);
- skipright = GetSizeSkip(right);
-
- if (ENODE_IS(right, EINTCONST) && ENODE_IS(left, EINTCONST))
- CError_FATAL(7900);
-
- if (ENODE_IS(left, EINTCONST))
- leftval = left->data.intval.lo + (((SInt64) ((skipleft < 8) ? 0 : left->data.intval.hi)) << 32);
- if (ENODE_IS(right, EINTCONST))
- rightval = right->data.intval.lo + (((SInt64) ((skipright < 8) ? 0 : right->data.intval.hi)) << 32);
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
-
- if (!(ENODE_IS(left, EINTCONST) && I8_log2n(leftval) > 0)) {
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
- }
- } else {
- if (!(ENODE_IS(left, EINTCONST) && I8_log2n(leftval) > 0)) {
- GEN_NODE(left, &opleft);
- if (TYPE_IS_8BYTES(left->rtype))
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
- else
- ENSURE_GPR(&opleft, left->rtype, 0);
- }
-
- if (!(ENODE_IS(right, EINTCONST) && I8_log2n(rightval) > 0)) {
- GEN_NODE(right, &opright);
- if (TYPE_IS_8BYTES(right->rtype))
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
- else
- ENSURE_GPR(&opright, right->rtype, 0);
- }
- }
-
- is_uns = is_unsigned(expr->rtype) != 0;
-
- if (skipleft < skipright) {
- Operand tmpop;
- SInt64 tmp64;
- SInt32 tmp;
-
- expr->data.diadic.left = right;
- expr->data.diadic.right = left;
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
-
- tmpop = opright;
- opright = opleft;
- opleft = tmpop;
-
- tmp64 = leftval;
- leftval = rightval;
- rightval = tmp64;
-
- tmp = skipleft;
- skipleft = skipright;
- skipright = tmp;
- }
-
- reg = ALLOC_GPR();
- regHi = ALLOC_GPR();
-
- if (ENODE_IS(left, EINTCONST) && (shift = I8_log2n(leftval)) > 0) {
- I8_ShiftLeftImmediate(opright, shift, is_uns, skipright, reg, regHi);
- } else if (ENODE_IS(right, EINTCONST) && (shift = I8_log2n(rightval)) > 0) {
- I8_ShiftLeftImmediate(opleft, shift, is_uns, skipleft, reg, regHi);
- } else {
- switch (skipleft + skipright) {
- case 1 + 1:
- case 1 + 2:
- case 2 + 2:
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_MULLI, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo)) {
- emitpcode(PC_MULLI, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- } else {
- emitpcode(PC_MULLW, reg, opleft.reg, opright.reg);
- }
- if (is_uns)
- emitpcode(PC_LI, regHi, 0);
- else
- emitpcode(PC_SRAWI, regHi, reg, 31);
- break;
- case 1 + 4:
- case 2 + 4:
- case 4 + 4:
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo)) {
- emitpcode(PC_MULLI, reg, opright.reg, LOW_PART(left->data.intval.lo));
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo)) {
- emitpcode(PC_MULLI, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- } else {
- emitpcode(PC_MULLW, reg, opleft.reg, opright.reg);
- }
- if (is_uns)
- emitpcode(PC_MULHWU, regHi, opleft.reg, opright.reg);
- else
- emitpcode(PC_MULHW, regHi, opleft.reg, opright.reg);
- break;
- case 1 + 8:
- case 2 + 8:
- case 4 + 8:
- CError_ASSERT(8097, skipleft == 8);
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo) && left->data.intval.hi == 0) {
- emitpcode(PC_MULLI, reg, opright.reg, LOW_PART(left->data.intval.lo));
- if (is_uns)
- emitpcode(PC_MULHWU, regHi, opright.reg, opleft.reg);
- else
- emitpcode(PC_MULHW, regHi, opright.reg, opleft.reg);
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo) && right->data.intval.hi == 0) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- if (is_uns) {
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLI, tmpreg1, opleft.regHi, LOW_PART(right->data.intval.lo));
- emitpcode(PC_MULLI, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- emitpcode(PC_ADD, regHi, tmpreg2, tmpreg1);
- } else {
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg4, opright.reg, 31);
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLI, tmpreg1, opleft.regHi, LOW_PART(right->data.intval.lo));
- emitpcode(PC_MULLI, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- emitpcode(PC_MULLW, tmpreg3, opleft.reg, tmpreg4);
- emitpcode(PC_ADD, regHi, tmpreg2, tmpreg1);
- emitpcode(PC_ADD, regHi, regHi, tmpreg3);
- }
- } else {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- if (is_uns) {
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLW, tmpreg1, opleft.regHi, opright.reg);
- emitpcode(PC_MULLW, reg, opleft.reg, opright.reg);
- emitpcode(PC_ADD, regHi, tmpreg2, tmpreg1);
- } else {
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- emitpcode(PC_SRAWI, tmpreg4, opright.reg, 31);
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLW, tmpreg1, opleft.regHi, opright.reg);
- emitpcode(PC_MULLW, reg, opleft.reg, opright.reg);
- emitpcode(PC_MULLW, tmpreg3, opleft.reg, tmpreg4);
- emitpcode(PC_ADD, regHi, tmpreg2, tmpreg1);
- emitpcode(PC_ADD, regHi, regHi, tmpreg3);
- }
- }
- break;
- case 8 + 8:
- if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo) && left->data.intval.hi == 0) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_MULHWU, tmpreg1, opright.reg, opleft.reg);
- emitpcode(PC_MULLW, tmpreg2, opright.reg, opleft.regHi);
- emitpcode(PC_MULLI, reg, opright.reg, LOW_PART(left->data.intval.lo));
- emitpcode(PC_ADD, regHi, tmpreg1, tmpreg2);
- } else if (ENODE_IS(right, EINTCONST) && FITS_IN_SHORT2(right->data.intval.lo) && right->data.intval.hi == 0) {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLW, tmpreg1, opleft.regHi, opright.reg);
- emitpcode(PC_MULLI, reg, opleft.reg, LOW_PART(right->data.intval.lo));
- emitpcode(PC_ADD, regHi, tmpreg2, tmpreg1);
- } else {
- tmpreg1 = ALLOC_GPR();
- tmpreg2 = ALLOC_GPR();
- tmpreg3 = ALLOC_GPR();
- tmpreg4 = ALLOC_GPR();
- emitpcode(PC_MULHWU, tmpreg2, opleft.reg, opright.reg);
- emitpcode(PC_MULLW, tmpreg1, opleft.regHi, opright.reg);
- emitpcode(PC_ADD, tmpreg3, tmpreg2, tmpreg1);
- emitpcode(PC_MULLW, tmpreg4, opleft.reg, opright.regHi);
- emitpcode(PC_MULLW, reg, opleft.reg, opright.reg);
- emitpcode(PC_ADD, regHi, tmpreg3, tmpreg4);
- }
- break;
- default:
- CError_FATAL(8218);
- }
- }
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_BINNOT(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Operand op;
- int reg;
- int regHi;
-
- inner = expr->data.monadic;
- memclrw(&op, sizeof(Operand));
- GEN_NODE(inner, &op);
- coerce_to_register_pair(&op, inner->rtype, 0, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
- emitpcode(PC_NOR, reg, op.reg, op.reg);
- emitpcode(PC_NOR, regHi, op.regHi, op.regHi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_MONMIN(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Operand op;
- int reg;
- int regHi;
-
- inner = expr->data.monadic;
- memclrw(&op, sizeof(Operand));
- GEN_NODE(inner, &op);
- coerce_to_register_pair(&op, inner->rtype, 0, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
- emitpcode(PC_SUBFIC, reg, op.reg, 0);
- emitpcode(PC_SUBFZE, regHi, op.regHi);
-
- output->optype = OpndType_GPRPair;
- output->reg = reg;
- output->regHi = regHi;
-}
-
-void I8_gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *type;
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- VarInfo *vi;
-
- type = expr->rtype;
- if (ENODE_IS(expr, ECONDASS)) {
- left = expr->data.cond.expr1;
- if (ENODE_IS(left, EINDIRECT))
- left = left->data.monadic;
- else
- CError_FATAL(8328);
- right = expr->data.cond.expr2;
- } else {
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- }
-
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- if (ENODE_IS(left, EOBJREF) && OBJECT_REG(left->data.objref)) {
- vi = Registers_GetVarInfo(left->data.objref);
- GEN_NODE_TO_REG(right, vi->reg, vi->regHi, &opright);
- if (vi->rclass != RegClass_GPR) {
- CError_FATAL(8348);
- } else {
- coerce_to_register_pair(&opright, type, vi->reg, vi->regHi);
- *output = opright;
- }
- return;
- }
-
- if (TYPE_FITS_IN_REGISTER(type)) {
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
-
- if (ENODE_IS(left, EBITFIELD)) {
- CError_FATAL(8376);
- } else {
- GEN_NODE(left, &opleft);
- indirect(&opleft, left);
- store_pair(opright.reg, opright.regHi, &opleft, type);
- }
-
- output->optype = OpndType_GPRPair;
- output->reg = opright.reg;
- output->regHi = opright.regHi;
- }
-}
-
-void I8_gen_POSTINCDEC(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- Type *type;
- int flag;
- int reg;
- int regHi;
- Operand op1;
- Operand op2;
- Operand op3;
-
- inner = expr->data.monadic->data.monadic;
- type = expr->rtype;
- flag = 0;
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
-
- if (ENODE_IS(inner, EOBJREF) && (reg = OBJECT_REG(inner->data.objref))) {
- regHi = Registers_GetVarInfo(inner->data.objref)->regHi;
- output->optype = OpndType_GPRPair;
- output->reg = (outputReg && outputReg != reg && outputReg != regHi) ? outputReg : ALLOC_GPR();
- output->regHi = (outputRegHi && outputRegHi != regHi && outputRegHi != reg) ? outputRegHi : ALLOC_GPR();
- emitpcode(PC_MR, output->reg, reg);
- emitpcode(PC_MR, output->regHi, regHi);
- if (ENODE_IS(expr, EPOSTINC)) {
- emitpcode(PC_ADDIC, reg, reg, 1);
- emitpcode(PC_ADDME, regHi, regHi);
- } else {
- emitpcode(PC_ADDIC, reg, reg, -1);
- emitpcode(PC_ADDZE, regHi, regHi);
- }
- return;
- }
-
- CError_ASSERT(8446, !ENODE_IS(inner, EBITFIELD));
-
- GEN_NODE(inner, &op1);
- indirect(&op1, inner);
- op2 = op1;
- coerce_to_register_pair(&op2, type, 0, 0);
-
- output->optype = OpndType_GPRPair;
- output->reg = ALLOC_GPR();
- output->regHi = ALLOC_GPR();
-
- emitpcode(PC_MR, output->reg, op2.reg);
- emitpcode(PC_MR, output->regHi, op2.regHi);
-
- reg = ALLOC_GPR();
- regHi = ALLOC_GPR();
-
- if (ENODE_IS(expr, EPOSTINC)) {
- emitpcode(PC_ADDIC, reg, op2.reg, 1);
- emitpcode(PC_ADDZE, regHi, op2.regHi);
- } else {
- emitpcode(PC_ADDIC, reg, op2.reg, -1);
- emitpcode(PC_ADDME, regHi, op2.regHi);
- }
- store_pair(reg, regHi, &op1, type);
-}
-
-void I8_gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- ENode *inner;
- VarInfo *vi;
-
- inner = expr->data.monadic;
- if (ENODE_IS(inner, EOBJREF) && OBJECT_REG(inner->data.objref)) {
- vi = Registers_GetVarInfo(inner->data.objref);
- switch (vi->rclass) {
- case RegClass_GPR:
- output->optype = OpndType_GPRPair;
- break;
- case RegClass_FPR:
- output->optype = OpndType_FPR;
- break;
- default:
- CError_FATAL(8511);
- }
-
- output->reg = vi->reg;
- output->regHi = vi->regHi;
- output->object = NULL;
- return;
- }
-
- if (ENODE_IS(inner, EBITFIELD)) {
- CError_FATAL(8529);
- return;
- }
-
- GEN_NODE(inner, output);
- indirect(output, inner);
-}
-
-void I8_gen_condition(ENode *cond, Operand *output, int write_to_gpr) {
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- Operand tmpop;
- int reg1;
- int reg2;
- int reg3;
- int reg4;
- int reg5;
-
- left = cond->data.diadic.left;
- right = cond->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
- memclrw(&tmpop, sizeof(Operand));
-
- if (right->hascall) {
- GEN_NODE(right, &opright);
- if (right->rtype->size < 4)
- extend32(&opright, right->rtype, 0);
- ENSURE_GPR(&opright, right->rtype, 0);
-
- if (right->rtype->size < 8) {
- short tmp = ALLOC_GPR();
- if (is_unsigned(right->rtype))
- load_immediate(tmp, 0);
- else
- emitpcode(PC_SRAWI, tmp, opright.reg, 31);
- opright.optype = OpndType_GPRPair;
- opright.regHi = tmp;
- }
-
- GEN_NODE(left, &opleft);
- if (left->rtype->size < 4)
- extend32(&opleft, left->rtype, 0);
- ENSURE_GPR(&opleft, left->rtype, 0);
-
- if (left->rtype->size < 8) {
- short tmp = ALLOC_GPR();
- // this looks like a bug??? surely this should check left->rtype
- if (is_unsigned(right->rtype))
- load_immediate(tmp, 0);
- else
- emitpcode(PC_SRAWI, tmp, opleft.reg, 31);
- opleft.optype = OpndType_GPRPair;
- opleft.regHi = tmp;
- }
- } else {
- GEN_NODE(left, &opleft);
- ENSURE_GPR(&opleft, left->rtype, 0);
- if (left->rtype->size < 4)
- extend32(&opleft, left->rtype, 0);
-
- if (left->rtype->size < 8) {
- short tmp = ALLOC_GPR();
- if (is_unsigned(right->rtype))
- load_immediate(tmp, 0);
- else
- emitpcode(PC_SRAWI, tmp, opleft.reg, 31);
- opleft.optype = OpndType_GPRPair;
- opleft.regHi = tmp;
- }
-
- GEN_NODE(right, &opright);
- if (right->rtype->size < 4)
- extend32(&opright, right->rtype, 0);
- ENSURE_GPR(&opright, right->rtype, 0);
-
- if (right->rtype->size < 8) {
- short tmp = ALLOC_GPR();
- if (is_unsigned(right->rtype))
- load_immediate(tmp, 0);
- else
- emitpcode(PC_SRAWI, tmp, opright.reg, 31);
- opright.optype = OpndType_GPRPair;
- opright.regHi = tmp;
- }
- }
-
- CError_ASSERT(8704, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair);
-
- switch (cond->type) {
- case EEQU:
- case ENOTEQU:
- reg1 = ALLOC_GPR();
- reg2 = ALLOC_GPR();
- emitpcode(PC_XOR, reg1, opleft.reg, opright.reg);
- emitpcode(PC_XOR, reg2, opleft.regHi, opright.regHi);
- emitpcode(PC_OR, reg2, reg1, reg2);
- if (write_to_gpr) {
- if (ENODE_IS(cond, EEQU)) {
- emitpcode(PC_CNTLZW, reg2, reg2);
- emitpcode(PC_RLWINM, reg2, reg2, 27, 5, 31);
- } else {
- emitpcode(PC_ADDIC, reg1, reg2, -1);
- emitpcode(PC_SUBFE, reg2, reg1, reg2);
- }
- output->optype = OpndType_GPR;
- output->reg = reg2;
- output->regHi = 0;
- } else {
- emitpcode(PC_CMPI, 0, reg2, 0);
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = cond->type;
- }
- break;
- case EGREATER:
- tmpop = opleft;
- opleft = opright;
- opright = tmpop;
- case ELESS:
- reg1 = ALLOC_GPR();
- reg2 = ALLOC_GPR();
- reg3 = ALLOC_GPR();
- if (left->rtype != TYPE(&stunsignedlonglong) && right->rtype != TYPE(&stunsignedlonglong)) {
- emitpcode(PC_XORIS, reg1, opleft.regHi, 0x8000);
- emitpcode(PC_XORIS, reg2, opright.regHi, 0x8000);
- reg4 = reg1;
- reg5 = reg2;
- } else {
- reg4 = opleft.regHi;
- reg5 = opright.regHi;
- }
- emitpcode(PC_SUBFC, reg3, opright.reg, opleft.reg);
- emitpcode(PC_SUBFE, reg2, reg5, reg4);
- emitpcode(PC_SUBFE, reg2, reg1, reg1);
- emitpcode(PC_NEG, reg2, reg2);
- if (write_to_gpr) {
- output->optype = OpndType_GPR;
- output->reg = reg2;
- output->regHi = 0;
- } else {
- emitpcode(PC_CMPI, 0, reg2, 0);
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = ENOTEQU;
- }
- break;
- case ELESSEQU:
- tmpop = opleft;
- opleft = opright;
- opright = tmpop;
- case EGREATEREQU:
- reg1 = ALLOC_GPR();
- reg2 = ALLOC_GPR();
- reg3 = ALLOC_GPR();
- if (left->rtype != TYPE(&stunsignedlonglong) && right->rtype != TYPE(&stunsignedlonglong)) {
- emitpcode(PC_XORIS, reg1, opleft.regHi, 0x8000);
- emitpcode(PC_XORIS, reg2, opright.regHi, 0x8000);
- reg4 = reg1;
- reg5 = reg2;
- } else {
- reg4 = opleft.regHi;
- reg5 = opright.regHi;
- }
- emitpcode(PC_SUBFC, reg3, opright.reg, opleft.reg);
- emitpcode(PC_SUBFE, reg2, reg5, reg4);
- emitpcode(PC_SUBFE, reg2, reg1, reg1);
- emitpcode(PC_NEG, reg2, reg2);
- if (write_to_gpr) {
- emitpcode(PC_SUBFIC, reg2, reg2, 1);
- output->optype = OpndType_GPR;
- output->reg = reg2;
- output->regHi = 0;
- } else {
- emitpcode(PC_CMPI, 0, reg2, 0);
- output->optype = OpndType_CRField;
- output->reg = 0;
- output->regOffset = EEQU;
- }
- break;
- default:
- CError_FATAL(8814);
- }
-}
-
-void I8_gen_SHL_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- static UInt32 used_regs[RegClassMax] = {0, 0, 0, 0, (1 << 3) | (1 << 4) | (1 << 5)};
-
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- int is_uns;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
-
- output->optype = OpndType_GPRPair;
- output->reg = ALLOC_GPR();
- output->regHi = ALLOC_GPR();
-
- is_uns = is_unsigned(expr->rtype) != 0;
-
- if (ENODE_IS(right, EINTCONST)) {
- if (ENODE_IS(expr, ESHL)) {
- I8_ShiftLeftImmediate(opleft, right->data.intval.lo, is_uns, expr->rtype->size, output->reg, output->regHi);
- } else {
- I8_ShiftRightImmediate(opleft, right->data.intval.lo, is_uns, output->reg, output->regHi, 0);
- }
- return;
- }
-
- GEN_NODE(right, &opright);
- ENSURE_GPR(&opright, right->rtype, 0);
- if (opright.optype == OpndType_GPRPair) {
- opright.regHi = 0;
- opright.optype = OpndType_GPR;
- }
-
- CError_ASSERT(8890, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPR);
-
- if (opleft.regHi != high_reg)
- emitpcode(PC_MR, high_reg, opleft.regHi);
- if (opleft.reg != low_reg)
- emitpcode(PC_MR, low_reg, opleft.reg);
- if (opright.reg != 5)
- emitpcode(PC_MR, 5, opright.reg);
-
- if (ENODE_IS(expr, ESHR)) {
- if (is_unsigned(left->rtype))
- branch_subroutine(rt_shr2u, 0, used_regs);
- else
- branch_subroutine(rt_shr2i, 0, used_regs);
- } else if (ENODE_IS(expr, ESHL)) {
- branch_subroutine(rt_shl2i, 0, used_regs);
- } else {
- CError_FATAL(8909);
- }
-
- emitpcode(PC_MR, output->reg, low_reg);
- emitpcode(PC_MR, output->regHi, high_reg);
-}
-
-void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- static UInt32 used_regs[RegClassMax] = {0, 0, 0, 0, (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)};
-
- int is_uns;
- ENode *left;
- ENode *right;
- Operand opleft;
- Operand opright;
- SInt64 constval;
- int shift;
-
- left = expr->data.diadic.left;
- right = expr->data.diadic.right;
- memclrw(&opleft, sizeof(Operand));
- memclrw(&opright, sizeof(Operand));
-
- GEN_NODE(left, &opleft);
- coerce_to_register_pair(&opleft, left->rtype, 0, 0);
-
- output->optype = OpndType_GPRPair;
- output->reg = ALLOC_GPR();
- output->regHi = ALLOC_GPR();
-
- is_uns = is_unsigned(expr->rtype) != 0;
-
- if (ENODE_IS(right, EINTCONST))
- constval = (((SInt64) right->data.intval.hi) << 32) + right->data.intval.lo;
- if (ENODE_IS(right, EINTCONST) && ((shift = I8_log2n(constval)) > 0)) {
- CError_ASSERT(8976, opleft.optype == OpndType_GPRPair);
- if (ENODE_IS(expr, EDIV)) {
- I8_ShiftRightImmediate(opleft, shift, is_uns, output->reg, output->regHi, 1);
- if (!is_uns) {
- emitpcode(PC_ADDZE, output->reg, output->reg);
- emitpcode(PC_ADDZE, output->regHi, output->regHi);
- }
- } else {
- if (is_uns) {
- if (shift < 32) {
- emitpcode(PC_LI, output->regHi, 0);
- emitpcode(PC_RLWINM, output->reg, opleft.reg, 0, 32 - shift, 31);
- } else if (shift == 32) {
- emitpcode(PC_LI, output->regHi, 0);
- emitpcode(PC_MR, output->reg, opleft.reg);
- } else if (shift <= 63) {
- emitpcode(PC_RLWINM, output->regHi, opleft.regHi, 0, 32 - (shift - 32), 31);
- emitpcode(PC_MR, output->reg, opleft.reg);
- } else {
- CError_FATAL(9018);
- }
- } else {
- short tmpreg1 = ALLOC_GPR();
- short tmpreg2 = ALLOC_GPR();
- I8_ShiftRightImmediate(opleft, shift, is_uns, output->reg, output->regHi, 1);
- emitpcode(PC_ADDZE, output->reg, output->reg);
- emitpcode(PC_ADDZE, output->regHi, output->regHi);
- I8_ShiftLeftImmediate(*output, shift, is_uns, expr->rtype->size, tmpreg1, tmpreg2);
- emitpcode(PC_SUBFC, output->reg, tmpreg1, opleft.reg);
- emitpcode(PC_SUBFE, output->regHi, tmpreg2, opleft.regHi);
- }
- }
- return;
- }
-
- GEN_NODE(right, &opright);
- coerce_to_register_pair(&opright, right->rtype, 0, 0);
-
- CError_ASSERT(9048, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair);
-
- if (opleft.regHi != high_reg)
- emitpcode(PC_MR, high_reg, opleft.regHi);
- if (opleft.reg != low_reg)
- emitpcode(PC_MR, low_reg, opleft.reg);
- if (opright.regHi != high_reg2)
- emitpcode(PC_MR, high_reg2, opright.regHi);
- if (opright.reg != low_reg2)
- emitpcode(PC_MR, low_reg2, opright.reg);
-
- if (ENODE_IS(expr, EDIV)) {
- if (is_unsigned(left->rtype) || is_unsigned(right->rtype))
- branch_subroutine(rt_div2u, 0, used_regs);
- else
- branch_subroutine(rt_div2i, 0, used_regs);
- } else if (ENODE_IS(expr, EMODULO)) {
- if (is_unsigned(left->rtype) || is_unsigned(right->rtype))
- branch_subroutine(rt_mod2u, 0, used_regs);
- else
- branch_subroutine(rt_mod2i, 0, used_regs);
- } else {
- CError_FATAL(9074);
- }
-
- emitpcode(PC_MR, output->reg, low_reg);
- emitpcode(PC_MR, output->regHi, high_reg);
-}
-
-void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- Type *dsttype;
- ENode *inner;
- Type *srctype;
- short regHi;
- short reg;
-
- static UInt32 used_regs[RegClassMax] = {0, 0, 0, 0, (1 << 3) | (1 << 4)};
- static UInt32 used_regs_f1[RegClassMax] = {0, 0, 0, (1 << 1), 0};
-
- inner = expr->data.monadic;
- srctype = inner->rtype;
- dsttype = expr->rtype;
-
- if (IS_TYPE_VOID(dsttype)) {
- GEN_NODE(inner, output);
- if (ENODE_IS(inner, EINDIRECT) && (output->flags & OpndFlags_Volatile))
- coerce_to_register_pair(output, inner->rtype, 0, 0);
- output->optype = OpndType_Absolute;
- output->immediate = 0;
- return;
- }
-
- if (IS_TYPE_INT_OR_ENUM(srctype)) {
- if (IS_TYPE_FLOAT(dsttype)) {
- GEN_NODE(inner, output);
- coerce_to_register_pair(output, srctype, 0, 0);
- if (output->regHi != high_reg)
- emitpcode(PC_MR, high_reg, output->regHi);
- if (output->reg != low_reg)
- emitpcode(PC_MR, low_reg, output->reg);
-
- if (is_unsigned(srctype)) {
- branch_subroutine(
- (dsttype->size == 4) ? rt_cvt_ull_flt : rt_cvt_ull_dbl,
- 0,
- used_regs);
- } else {
- branch_subroutine(
- (dsttype->size == 4) ? rt_cvt_sll_flt : rt_cvt_sll_dbl,
- 0,
- used_regs);
- }
-
- output->optype = OpndType_FPR;
- output->reg = ALLOC_FPR();
- emitpcode(PC_FMR, output->reg, 1);
- return;
- }
-
- if (srctype->size < dsttype->size) {
- CError_ASSERT(9171, TYPE_IS_8BYTES(dsttype));
-
- GEN_NODE(inner, output);
- if (srctype->size < 4 &&
- !ENODE_IS_INDIRECT_TO(inner, EBITFIELD) &&
- !((ENODE_IS_ASSIGN(inner) || ENODE_IS_RANGE(inner, EPOSTINC, EPREDEC)) && ENODE_IS(inner->data.monadic->data.monadic, EBITFIELD))
- ) {
- extend32(output, srctype, outputReg);
- }
- extend64(output, srctype, outputReg, outputRegHi);
- } else {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- if (dsttype->size < srctype->size) {
- coerce_to_register_pair(output, srctype, outputReg, outputRegHi);
- output->optype = OpndType_GPR;
- output->regHi = 0;
- }
- }
- return;
- }
-
- if (IS_TYPE_POINTER(srctype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
- CError_ASSERT(9200, TYPE_IS_8BYTES(expr->rtype));
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
-
- regHi = outputRegHi ? outputRegHi : ALLOC_GPR();
- if (regHi == output->reg) {
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_MR, reg, output->reg);
- output->reg = reg;
- }
- if (is_unsigned(inner->rtype))
- load_immediate(regHi, 0);
- else
- emitpcode(PC_SRAWI, regHi, output->reg, 31);
- output->optype = OpndType_GPRPair;
- output->regHi = regHi;
- return;
- }
-
- if (IS_TYPE_FLOAT(srctype)) {
- if (IS_TYPE_FLOAT(dsttype)) {
- CError_FATAL(9222);
- return;
- }
-
- GEN_NODE(inner, output);
- ENSURE_FPR(output, srctype, 0);
- if (output->reg != 1)
- emitpcode(PC_FMR, 1, output->reg);
-
- branch_subroutine(rt_cvt_dbl_usll, 0, used_regs_f1);
-
- output->optype = OpndType_GPRPair;
- output->reg = ALLOC_GPR();
- output->regHi = ALLOC_GPR();
- emitpcode(PC_MR, output->reg, low_reg);
- emitpcode(PC_MR, output->regHi, high_reg);
- return;
- }
-
- if (IS_TYPE_STRUCT(srctype)) {
- GEN_NODE_TO_REG(inner, outputReg, 0, output);
-
- if (TYPE_IS_8BYTES(expr->rtype) && dsttype->size == srctype->size) {
- coerce_to_register_pair(output, srctype, outputReg, outputRegHi);
- } else {
- CError_FATAL(9256);
- }
- return;
- }
-
- CError_FATAL(9261);
-}
-
-void gen_VECTOR128CONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) {
- int gpr;
- int vr;
- COVCResult result;
-
- vr = outputReg ? outputReg : ALLOC_VR();
- if (!canoptimizevectorconst(&expr->data.vector128val, expr->rtype, &result))
- CError_FATAL(9282);
-
- if (result.op1 != -1) {
- emitpcode(result.op1, vr, result.arg);
- output->optype = OpndType_VR;
- output->reg = vr;
- return;
- }
-
- if (result.op2 != -1) {
- gpr = ALLOC_GPR();
- emitpcode(PC_LI, gpr, result.arg);
- emitpcode(result.op2, vr, 0, gpr);
- output->optype = OpndType_VR;
- output->reg = vr;
- return;
- }
-
- CError_FATAL(9298);
-}
diff --git a/compiler_and_linker/unsorted/InterferenceGraph.c b/compiler_and_linker/unsorted/InterferenceGraph.c
deleted file mode 100644
index d589502..0000000
--- a/compiler_and_linker/unsorted/InterferenceGraph.c
+++ /dev/null
@@ -1,364 +0,0 @@
-#include "compiler/InterferenceGraph.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/BitVectors.h"
-#include "compiler/Coloring.h"
-#include "compiler/LiveInfo.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Registers.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/CompilerTools.h"
-
-IGNode **interferencegraph;
-static UInt32 *interferencematrix;
-Boolean coalesced_nregisters;
-static SInt16 *coalesced;
-
-static void makeinterfere(UInt32 a, UInt32 b) {
- if (a < b)
- bitvectorsetbit(((b * b) / 2) + a, interferencematrix);
- else if (a > b)
- bitvectorsetbit(((a * a) / 2) + b, interferencematrix);
-}
-
-int interferes(UInt32 a, UInt32 b) {
- if (a < b)
- return bitvectorgetbit(((b * b) / 2) + a, interferencematrix) > 0;
- else if (a > b)
- return bitvectorgetbit(((a * a) / 2) + b, interferencematrix) > 0;
- else
- return 0;
-}
-
-static void buildinterferencematrix(void) {
- PCodeBlock *block; // r30
- PCode *instr; // r29
- PCodeArg *op;
- UInt32 *vec; // r28
- UInt32 i;
- UInt32 j;
-
- UInt32 regs = used_virtual_registers[coloring_class];
- interferencematrix = oalloc(4 * ((((regs * regs) / 2) + 31) >> 5));
- bitvectorinitialize(interferencematrix, (regs * regs) / 2, 0);
-
- for (i = 0; i < 32; i++)
- for (j = 0; j < 32; j++)
- if (i != j)
- makeinterfere(i, j);
-
- vec = oalloc(4 * ((regs + 31) >> 5));
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- bitvectorcopy(vec, liveinfo[block->blockIndex].out, regs);
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class)) {
- int reg = op->data.reg.reg;
- bitvectorclearbit(reg, vec);
- for (j = 0; j < regs; j++) {
- if (bitvectorgetbit(j, vec)) {
- if (
- (instr->flags & fIsMove) &&
- PC_OP_IS_ANY_REGISTER(&instr->args[0], coloring_class) &&
- instr->args[1].data.reg.reg == j
- )
- continue;
- makeinterfere(reg, j);
- }
- }
- }
- }
-
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class)) {
- int reg = op->data.reg.reg;
- if (bitvectorgetbit(op->data.reg.reg, vec) == 0)
- op->data.reg.effect |= Effect4;
- bitvectorsetbit(reg, vec);
- }
- }
-
- if (coloring_class == RegClass_GPR) {
- if (PCODE_FLAG_SET_F(instr) & (fIsRead | fIsWrite | fPCodeFlag400000)) {
- if (instr->args[1].data.reg.reg >= n_real_registers[coloring_class])
- makeinterfere(0, instr->args[1].data.reg.reg);
- if (PCODE_FLAG_SET_F(instr) & fUpdatesPtr)
- makeinterfere(instr->args[0].data.reg.reg, instr->args[1].data.reg.reg);
- } else {
- switch (instr->op) {
- case PC_DCBF:
- case PC_DCBST:
- case PC_DCBT:
- case PC_DCBTST:
- case PC_DCBZ:
- case PC_DCBI:
- case PC_ICBI:
- case PC_DCCCI:
- case PC_ICBT:
- case PC_ICCCI:
- case PC_ICREAD:
- case PC_DCBA:
- case PC_DST:
- case PC_DSTT:
- case PC_DSTST:
- case PC_DSTSTT:
- if (instr->args[0].data.reg.reg >= n_real_registers[coloring_class])
- makeinterfere(0, instr->args[0].data.reg.reg);
- break;
- }
- }
- }
-
- if (coloring_class == RegClass_GPR && (instr->flags & fIsCall)) {
- i = branch_count_volatiles();
- op = instr->args;
- CError_ASSERT(219, instr->argCount != 0);
-
- while (op->kind != PCOp_REGISTER || !(op->data.reg.effect & EffectWrite)) {
- i++;
- op++;
- CError_ASSERT(226, i <= instr->argCount);
- }
-
- for (op = instr->args + i; i < instr->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
- for (j = 0; j < n_scratch_registers[coloring_class]; j++)
- makeinterfere(op->data.reg.reg, scratch_registers[coloring_class][j]);
- }
- }
- }
- }
- }
-}
-
-static short coalesced_path(short id) {
- while (id != coalesced[id])
- id = coalesced[id];
- return id;
-}
-
-static void coalescenodes(void) {
- PCodeArg *op;
- UInt32 regs;
- PCodeBlock *block;
- PCode *instr;
- UInt32 i;
- short path1;
- short path2;
- short node1;
- short node2;
-
- regs = used_virtual_registers[coloring_class];
- coalesced = oalloc(sizeof(SInt16) * regs);
-
- for (i = 0; i < regs; i++)
- coalesced[i] = i;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if ((instr->flags & fIsMove) && !(instr->flags & fSideEffects)) {
- if (PCODE_FLAG_SET_F(instr) & fRecordBit) {
- CError_FATAL(309);
- continue;
- }
-
- if (instr->argCount > 2) {
- if (instr->argCount != 3 || instr->args[2].kind != PCOp_PLACEHOLDEROPERAND) {
- CError_FATAL(316);
- continue;
- }
- }
-
- if (PC_OP_IS_ANY_REGISTER(&instr->args[0], coloring_class)) {
- path1 = coalesced_path(instr->args[0].data.reg.reg);
- path2 = coalesced_path(instr->args[1].data.reg.reg);
- if (path1 == path2) {
- deletepcode(instr);
- continue;
- }
-
- if (!interferes(path1, path2)) {
- if (path1 >= n_real_registers[coloring_class] && path2 >= n_real_registers[coloring_class]) {
- if (path1 < first_fe_temporary_register[coloring_class])
- continue;
- if (path1 > last_temporary_register[coloring_class])
- continue;
- if (path2 < first_fe_temporary_register[coloring_class])
- continue;
- if (path2 > last_temporary_register[coloring_class])
- continue;
- }
-
- node1 = (path2 < path1) ? path2 : path1;
- node2 = (path2 > path1) ? path2 : path1;
-
- if (coloring_class == RegClass_GPR && node2 == _CALLER_SP_)
- continue;
-
- coalesced[node2] = node1;
- for (i = 0; i < regs; i++) {
- if (interferes(node2, i))
- makeinterfere(node1, i);
- }
-
- deletepcode(instr);
- }
- }
- }
- }
- }
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_ANY_REGISTER(op, coloring_class) && op->data.reg.reg != coalesced[op->data.reg.reg])
- op->data.reg.reg = coalesced_path(op->data.reg.reg);
- op++;
- }
- }
- }
-}
-
-static void buildadjacencyvectors(void) {
- IGNode *node;
- UInt32 regs;
- UInt32 i;
- UInt32 counter;
- short *array;
- short *dest;
- short *src;
- UInt32 j;
-
- regs = used_virtual_registers[coloring_class];
- interferencegraph = oalloc(sizeof(IGNode *) * regs);
- array = oalloc(sizeof(short) * regs);
-
- for (i = 0; i < regs; i++) {
- counter = 0;
- for (j = 0; j < regs; j++) {
- if (interferes(i, j))
- array[counter++] = j;
- }
-
- node = interferencegraph[i] = oalloc(sizeof(IGNode) + sizeof(short) * (counter - 1));
- memclrw(node, sizeof(IGNode) + sizeof(short) * (counter - 1));
-
- node->x10 = i;
- node->x14 = -1;
- node->arraySize = counter;
- node->x12 = counter;
-
- dest = node->array;
- src = array;
- for (j = 0; j < counter; j++)
- *(dest++) = *(src++);
-
- if (i != coalesced[i]) {
- node->flags |= fCoalesced;
- j = coalesced_path(i);
- interferencegraph[j]->flags |= fCoalescedInto;
- node->x14 = j;
- }
- }
-}
-
-static void eliminatedeadcode(void) {
- UInt32 regs;
- PCodeBlock *block;
- PCode *instr;
- UInt32 *vec;
- UInt32 i;
- PCodeArg *op;
-
- regs = used_virtual_registers[coloring_class];
- vec = oalloc(4 * ((regs + 31) >> 5));
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- bitvectorcopy(vec, liveinfo[block->blockIndex].out, regs);
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- if (dead(instr, coloring_class, vec)) {
- deletepcode(instr);
- continue;
- }
-
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class))
- bitvectorclearbit(op->data.reg.reg, vec);
- op++;
- }
-
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class)) {
- int reg = op->data.reg.reg;
- if (!bitvectorgetbit(reg, vec))
- op->data.reg.effect |= Effect4;
- bitvectorsetbit(reg, vec);
- }
- op++;
- }
- }
- }
-}
-
-static void findrematerializations(void) {
- UInt32 regs;
- UInt32 i;
- PCodeBlock *block;
- PCode *instr;
- PCodeArg *op;
- IGNode *node;
-
- regs = used_virtual_registers[coloring_class];
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class) &&
- op->data.reg.reg >= n_real_registers[coloring_class] &&
- !(interferencegraph[op->data.reg.reg]->flags & (fPairLow | fPairHigh)) &&
- !(interferencegraph[op->data.reg.reg]->flags & fIGNode40)
- )
- {
- node = interferencegraph[op->data.reg.reg];
- if (!node->instr8) {
- node->instr8 = instr;
- } else {
- node->instr8 = NULL;
- node->flags |= fIGNode40;
- }
- }
- op++;
- }
- }
- }
-
- for (i = 0; i < regs; i++) {
- node = interferencegraph[i];
- if (node->instr8 && !is_location_independent(node->instr8))
- node->instr8 = NULL;
- }
-}
-
-void buildinterferencegraph(Object *proc) {
- int regs = used_virtual_registers[coloring_class];
-
- computelivevariables(proc);
- eliminatedeadcode();
- buildinterferencematrix();
- if (copts.debuglisting)
- pclistinterferences(register_class_format[coloring_class], regs);
- coalescenodes();
- buildadjacencyvectors();
- findrematerializations();
-}
diff --git a/compiler_and_linker/unsorted/Intrinsics.c b/compiler_and_linker/unsorted/Intrinsics.c
deleted file mode 100644
index 49334b8..0000000
--- a/compiler_and_linker/unsorted/Intrinsics.c
+++ /dev/null
@@ -1,4894 +0,0 @@
-#include "compiler/Intrinsics.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/FunctionCalls.h"
-#include "compiler/InstrSelection.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/PPCError.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/StructMoves.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/types.h"
-
-Object *__memcpy_object;
-static Object *intrinsics[311];
-int VectorConditions; // unused?
-static Object *cur_intrinsic_object;
-
-static TypePointer stvectorunsignedchar_ptr = {TYPEPOINTER, 4, TYPE(&stvectorunsignedchar), 0};
-static TypePointer stvectorsignedchar_ptr = {TYPEPOINTER, 4, TYPE(&stvectorsignedchar), 0};
-static TypePointer stvectorboolchar_ptr = {TYPEPOINTER, 4, TYPE(&stvectorboolchar), 0};
-static TypePointer stvectorunsignedshort_ptr = {TYPEPOINTER, 4, TYPE(&stvectorunsignedshort), 0};
-static TypePointer stvectorsignedshort_ptr = {TYPEPOINTER, 4, TYPE(&stvectorsignedshort), 0};
-static TypePointer stvectorboolshort_ptr = {TYPEPOINTER, 4, TYPE(&stvectorboolshort), 0};
-static TypePointer stvectorunsignedlong_ptr = {TYPEPOINTER, 4, TYPE(&stvectorunsignedlong), 0};
-static TypePointer stvectorsignedlong_ptr = {TYPEPOINTER, 4, TYPE(&stvectorsignedlong), 0};
-static TypePointer stvectorboollong_ptr = {TYPEPOINTER, 4, TYPE(&stvectorboollong), 0};
-static TypePointer stvectorfloat_ptr = {TYPEPOINTER, 4, TYPE(&stvectorfloat), 0};
-static TypePointer stvectorpixel_ptr = {TYPEPOINTER, 4, TYPE(&stvectorpixel), 0};
-static TypePointer stunsignedchar_ptr = {TYPEPOINTER, 4, TYPE(&stunsignedchar), 0};
-static TypePointer stsignedchar_ptr = {TYPEPOINTER, 4, TYPE(&stsignedchar), 0};
-static TypePointer stunsignedshort_ptr = {TYPEPOINTER, 4, TYPE(&stunsignedshort), 0};
-static TypePointer stsignedshort_ptr = {TYPEPOINTER, 4, TYPE(&stsignedshort), 0};
-static TypePointer stunsignedlong_ptr = {TYPEPOINTER, 4, TYPE(&stunsignedlong), 0};
-static TypePointer stsignedlong_ptr = {TYPEPOINTER, 4, TYPE(&stsignedlong), 0};
-static TypePointer stunsignedint_ptr = {TYPEPOINTER, 4, TYPE(&stunsignedint), 0};
-static TypePointer stsignedint_ptr = {TYPEPOINTER, 4, TYPE(&stsignedint), 0};
-static TypePointer stfloat_ptr = {TYPEPOINTER, 4, TYPE(&stfloat), 0};
-
-// Verify1VectorArg2Ops
-typedef struct TypeTable22 {
- Type *rtype;
- Type *arg1;
- int opcode1;
- int opcode2;
-} TypeTable22;
-
-// VerifyNoVectorArgs
-typedef struct TypeTable11 {
- Type *rtype;
- int opcode;
-} TypeTable11;
-
-// Verify1VectorArg
-typedef struct TypeTable21 {
- Type *rtype;
- Type *arg1;
- int opcode;
-} TypeTable21;
-
-// Verify2VectorArgs
-typedef struct TypeTable31 {
- Type *rtype;
- Type *arg1;
- Type *arg2;
- int opcode;
-} TypeTable31;
-
-// Verify3VectorArgs
-typedef struct TypeTable41 {
- Type *rtype;
- Type *arg1;
- Type *arg2;
- Type *arg3;
- int opcode;
-} TypeTable41;
-
-static TypeTable31 vector_add_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VADDUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VADDUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VADDUBM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VADDUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VADDUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VADDUHM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VADDUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VADDUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VADDUWM,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VADDFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_addc_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VADDCUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_adds_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VADDUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VADDUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VADDUBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VADDSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VADDSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VADDSBS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VADDUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VADDUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VADDUHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VADDSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VADDSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VADDSHS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VADDUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VADDUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VADDUWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VADDSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VADDSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VADDSWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_and_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VAND,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VAND,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VAND,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VAND,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VAND,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VAND,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VAND,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VAND,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VAND,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VAND,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VAND,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VAND,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VAND,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VAND,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VAND,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VAND,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VAND,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VAND,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VAND,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VAND,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VAND,
- TYPE(&stvectorfloat), TYPE(&stvectorboollong), TYPE(&stvectorfloat), PC_VAND,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorboollong), PC_VAND,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VAND,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_andc_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VANDC,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VANDC,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VANDC,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VANDC,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VANDC,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VANDC,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VANDC,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VANDC,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VANDC,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VANDC,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VANDC,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VANDC,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VANDC,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VANDC,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VANDC,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VANDC,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VANDC,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VANDC,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VANDC,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VANDC,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VANDC,
- TYPE(&stvectorfloat), TYPE(&stvectorboollong), TYPE(&stvectorfloat), PC_VANDC,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorboollong), PC_VANDC,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VANDC,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_avg_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VAVGUB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VAVGSB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VAVGUH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VAVGSH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VAVGUW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VAVGSW,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_ceil_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VRFIP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_cmpb_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_cmpeq_type_table[] = {
- TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stvectorboollong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_cmpge_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_cmpgt_type_table[] = {
- TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stvectorboollong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_ctf_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VCFUX,
- TYPE(&stvectorfloat), TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VCFSX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_cts_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorfloat), TYPE(&stsignedint), PC_VCTSXS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_ctu_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorfloat), TYPE(&stsignedint), PC_VCTUXS,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_dss_type_table[] = {
- TYPE(&stvoid), TYPE(&stsignedint), PC_DSS, PC_B,
- NULL, NULL, 0
-};
-static TypeTable11 vector_dssall_type_table[] = {
- TYPE(&stvoid), PC_DSSALL,
- NULL, 0
-};
-static TypeTable41 vector_datastream_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorsignedchar_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorboolchar_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorsignedshort_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorboolshort_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorpixel_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorsignedlong_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorboollong_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stvectorfloat_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stunsignedchar_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stsignedchar_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stunsignedshort_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stsignedshort_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stunsignedint_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stsignedint_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stunsignedlong_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stsignedlong_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- TYPE(&stvoid), TYPE(&stfloat_ptr), TYPE(&stsignedint), TYPE(&stsignedint), PC_DST,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_expte_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VEXPTEFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_floor_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VRFIM, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_load_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stvectorunsignedchar_ptr), PC_LVX,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVX,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stvectorsignedchar_ptr), PC_LVX,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVX,
- TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stvectorboolchar_ptr), PC_LVX,
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stvectorunsignedshort_ptr), PC_LVX,
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVX,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stvectorsignedshort_ptr), PC_LVX,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVX,
- TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stvectorboolshort_ptr), PC_LVX,
- TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stvectorpixel_ptr), PC_LVX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stvectorunsignedlong_ptr), PC_LVX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stvectorsignedlong_ptr), PC_LVX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVX,
- TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stvectorboollong_ptr), PC_LVX,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stvectorfloat_ptr), PC_LVX,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_loade_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVEBX,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVEBX,
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVEHX,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVEHX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVEWX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVEWX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVEWX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVEWX,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVEWX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_loadl_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stvectorunsignedchar_ptr), PC_LVXL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVXL,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stvectorsignedchar_ptr), PC_LVXL,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVXL,
- TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stvectorboolchar_ptr), PC_LVXL,
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stvectorunsignedshort_ptr), PC_LVXL,
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVXL,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stvectorsignedshort_ptr), PC_LVXL,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVXL,
- TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stvectorboolshort_ptr), PC_LVXL,
- TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stvectorpixel_ptr), PC_LVXL,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stvectorunsignedlong_ptr), PC_LVXL,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVXL,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVXL,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stvectorsignedlong_ptr), PC_LVXL,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVXL,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVXL,
- TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stvectorboollong_ptr), PC_LVXL,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stvectorfloat_ptr), PC_LVXL,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVXL,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_loge_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VLOGEFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_lvsl_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVSL,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVSL,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_lvsr_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVSR,
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVSR,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_madd_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMADDFP,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_madds_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMHADDSHS,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_max_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMAXUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VMAXUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VMAXUB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMAXSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VMAXSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VMAXSB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMAXUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VMAXUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VMAXUH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMAXSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VMAXSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VMAXSH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMAXUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VMAXUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VMAXUW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMAXSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VMAXSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VMAXSW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMAXFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_mergeh_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGHB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMRGHB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VMRGHB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGHH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMRGHH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VMRGHH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VMRGHH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMRGHW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMRGHW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VMRGHW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMRGHW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_mergel_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMRGLB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VMRGLB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMRGLH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VMRGLH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VMRGLH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMRGLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMRGLW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VMRGLW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMRGLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable11 vector_mfvscr_type_table[] = {
- TYPE(&stvectorunsignedshort), PC_MFVSCR,
- NULL, 0
-};
-static TypeTable31 vector_min_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMINUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VMINUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VMINUB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMINSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VMINSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VMINSB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMINUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VMINUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VMINUH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMINSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VMINSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VMINSH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMINUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VMINUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VMINUW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMINSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VMINSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VMINSW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMINFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_mladd_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMLADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMLADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMLADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMLADDUHM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_mradds_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMHRADDSHS,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_msum_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VMSUMUBM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VMSUMUHM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedlong), PC_VMSUMMBM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VMSUMSHM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_msums_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VMSUMUHS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VMSUMSHS,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable21 vector_mtvscr_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorboolchar), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorboolshort), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorpixel), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), PC_MTVSCR,
- TYPE(&stvoid), TYPE(&stvectorboollong), PC_MTVSCR,
- NULL, NULL, 0
-};
-static TypeTable31 vector_mule_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMULEUB,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMULESB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMULEUH,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMULESH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_mulo_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMULOUB,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMULOSB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMULOUH,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMULOSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_nmsub_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VNMSUBFP,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_nor_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VNOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VNOR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VNOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VNOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VNOR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VNOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VNOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VNOR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VNOR,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VNOR,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_or_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VOR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VOR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VOR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VOR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VOR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VOR,
- TYPE(&stvectorfloat), TYPE(&stvectorboollong), TYPE(&stvectorfloat), PC_VOR,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorboollong), PC_VOR,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VOR,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_pack_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VPKUHUM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKUHUM,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VPKUHUM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKUWUM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKUWUM,
- TYPE(&stvectorboolshort), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VPKUWUM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_packpx_type_table[] = {
- TYPE(&stvectorpixel), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKPX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_packs_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VPKUHUS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKSHSS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKUWUS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKSWSS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_packsu_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VPKUHUS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKSHUS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKUWUS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKSWUS,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_perm_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedchar), PC_VPERM,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorunsignedchar), PC_VPERM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_re_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VREFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_rl_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VRLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VRLB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VRLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VRLH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VRLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VRLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_round_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VRFIN, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_rsqrte_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VRSQRTEFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable41 vector_sel_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSEL,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VSEL,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSEL,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VSEL,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSEL,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VSEL,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSEL,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VSEL,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSEL,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VSEL,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSEL,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VSEL,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSEL,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VSEL,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSEL,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VSEL,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSEL,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VSEL,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorunsignedlong), PC_VSEL,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorboollong), PC_VSEL,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sl_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSLB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSLH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_sld_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VSLDOI,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stsignedint), PC_VSLDOI,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sll_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSL,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedchar), PC_VSL,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedshort), PC_VSL,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSL,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_slo_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), PC_VSLO,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorunsignedchar), PC_VSLO,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorsignedchar), PC_VSLO,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_splat_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), PC_VSPLTB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stsignedint), PC_VSPLTB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stsignedint), PC_VSPLTB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stsignedint), PC_VSPLTW,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_splat_s8_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), PC_VSPLTISB, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_splat_s16_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), PC_VSPLTISH, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_splat_s32_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VSPLTISW, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_splat_u8_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), PC_VSPLTISB, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_splat_u16_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), PC_VSPLTISH, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_splat_u32_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VSPLTISW, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_sr_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSRB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSRB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSRH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSRH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSRW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSRW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sra_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSRAB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSRAB,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSRAH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSRAH,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSRAW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSRAW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_srl_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedchar), PC_VSR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedshort), PC_VSR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSR,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sro_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), PC_VSRO,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorunsignedchar), PC_VSRO,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorsignedchar), PC_VSRO,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_st_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stvectorunsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stvectorsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stvectorunsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stvectorsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stvectorunsignedlong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stvectorsignedlong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stvectorfloat_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stvectorpixel_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stvectorboolchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stvectorboolshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stvectorboollong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVX,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_ste_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVEWX,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_stl_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stvectorunsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stvectorsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stvectorunsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stvectorsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stvectorunsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stvectorsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stvectorfloat_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stvectorpixel_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stvectorboolchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stvectorboolshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stvectorboollong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVXL,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVXL,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sub_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSUBUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VSUBUBM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSUBUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VSUBUHM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSUBUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VSUBUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VSUBUWM,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VSUBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_subc_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSUBCUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_subs_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSUBUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSUBUBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VSUBSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VSUBSBS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSUBUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSUBUHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VSUBSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VSUBSHS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSUBUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VSUBUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSUBUWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VSUBSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VSUBSWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sum4s_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VSUM4UBS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedlong), PC_VSUM4SBS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VSUM4SHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sum2s_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUM2SWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_sums_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUMSWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_trunc_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VRFIZ, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_unpack2sh_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGHB,
- TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGHH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_unpack2sl_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGLB,
- TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGLH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_unpack2uh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGHB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGHH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_unpack2ul_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGLB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGLH,
- NULL, NULL, NULL, 0
-};
-static TypeTable21 vector_unpackh_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VUPKHSB,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolchar), PC_VUPKHSB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorpixel), PC_VUPKHPX,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), PC_VUPKHSH,
- TYPE(&stvectorboollong), TYPE(&stvectorboolshort), PC_VUPKHSH,
- NULL, NULL, 0
-};
-static TypeTable21 vector_unpackl_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VUPKLSB,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolchar), PC_VUPKLSB,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorpixel), PC_VUPKLPX,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), PC_VUPKLSH,
- TYPE(&stvectorboollong), TYPE(&stvectorboolshort), PC_VUPKLSH,
- NULL, NULL, 0
-};
-static TypeTable31 vector_xor_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VXOR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VXOR,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VXOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VXOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VXOR,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VXOR,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VXOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VXOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VXOR,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VXOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VXOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VXOR,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VXOR,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VXOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VXOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VXOR,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VXOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VXOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VXOR,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VXOR,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VXOR,
- TYPE(&stvectorfloat), TYPE(&stvectorboollong), TYPE(&stvectorfloat), PC_VXOR,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorboollong), PC_VXOR,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VXOR,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_eq_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_ge_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_gt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_in_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_le_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_lt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP
-};
-static TypeTable22 vector_all_nan_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), PC_VCMPEQFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_all_ne_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_nge_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_ngt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_nle_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_all_nlt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_all_numeric_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), PC_VCMPEQFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_any_eq_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_ge_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_gt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_le_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_lt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_any_nan_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), PC_VCMPEQFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_any_ne_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VCMPEQUB,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VCMPEQUH,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VCMPEQUW,
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_nge_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_ngt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_nle_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGEFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_any_nlt_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_any_numeric_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), PC_VCMPEQFP, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_any_out_type_table[] = {
- TYPE(&stsignedint), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddubm_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VADDUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VADDUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VADDUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VADDUBM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vadduhm_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VADDUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VADDUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VADDUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VADDUHM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vadduwm_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VADDUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VADDUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VADDUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VADDUWM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddfp_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VADDFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddubs_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VADDUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VADDUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VADDUBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddsbs_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VADDSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VADDSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VADDSBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vadduhs_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VADDUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VADDUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VADDUHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddshs_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VADDSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VADDSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VADDSHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vadduws_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VADDUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VADDUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VADDUWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vaddsws_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VADDSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VADDSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VADDSWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavgub_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VAVGUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavgsb_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VAVGSB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavguh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VAVGUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavgsh_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VAVGSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavguw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VAVGUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vavgsw_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VAVGSW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpequb_type_table[] = {
- TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPEQUB,
- TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPEQUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpequh_type_table[] = {
- TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPEQUH,
- TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPEQUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpequw_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPEQUW,
- TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPEQUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpeqfp_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPEQFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtub_type_table[] = {
- TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VCMPGTUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtsb_type_table[] = {
- TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VCMPGTSB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtuh_type_table[] = {
- TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VCMPGTUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtsh_type_table[] = {
- TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VCMPGTSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtuw_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VCMPGTUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtsw_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VCMPGTSW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcmpgtfp_type_table[] = {
- TYPE(&stvectorboollong), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VCMPGTFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcfux_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VCFUX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vcfsx_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VCFSX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_lvebx_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_LVEBX,
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_LVEBX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_lvehx_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_LVEHX,
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_LVEHX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_lvewx_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_LVEWX,
- TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_LVEWX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_LVEWX,
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_LVEWX,
- TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_LVEWX,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxub_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMAXUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VMAXUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VMAXUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxsb_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMAXSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VMAXSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VMAXSB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxuh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMAXUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VMAXUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VMAXUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxsh_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMAXSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VMAXSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VMAXSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxuw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMAXUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VMAXUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VMAXUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxsw_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMAXSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VMAXSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VMAXSW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmaxfp_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMAXFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrghb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGHB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMRGHB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VMRGHB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrghh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGHH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMRGHH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VMRGHH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VMRGHH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrghw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMRGHW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMRGHW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VMRGHW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMRGHW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrglb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMRGLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMRGLB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), PC_VMRGLB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrglh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMRGLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMRGLH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VMRGLH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stvectorpixel), PC_VMRGLH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmrglw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMRGLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMRGLW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VMRGLW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMRGLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminub_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMINUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VMINUB,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VMINUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminsb_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMINSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VMINSB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VMINSB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminuh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMINUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VMINUH,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VMINUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminsh_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMINSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VMINSH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VMINSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminuw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VMINUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VMINUW,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VMINUW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminsw_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VMINSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VMINSW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VMINSW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vminfp_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VMINFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsumubm_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VMSUMUBM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsumuhm_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VMSUMUHM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsummbm_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedlong), PC_VMSUMMBM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsumshm_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VMSUMSHM,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsumuhs_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), PC_VMSUMUHS,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_vmsumshs_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VMSUMSHS,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmuleub_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMULEUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmulesb_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMULESB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmuleuh_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMULEUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmulesh_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMULESH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmuloub_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VMULOUB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmulosb_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VMULOSB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmulouh_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VMULOUH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vmulosh_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VMULOSH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkuhum_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VPKUHUM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKUHUM,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), PC_VPKUHUM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkuwum_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKUWUM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKUWUM,
- TYPE(&stvectorboolshort), TYPE(&stvectorboollong), TYPE(&stvectorboollong), PC_VPKUWUM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkuhus_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VPKUHUS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkshss_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKSHSS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkuwus_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VPKUWUS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkswss_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKSWSS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkshus_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VPKSHUS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vpkswus_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VPKSWUS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vrlb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VRLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VRLB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vrlh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VRLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VRLH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vrlw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VRLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VRLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vslb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSLB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSLB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vslh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSLH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSLH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vslw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSLW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSLW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vspltb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), PC_VSPLTB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stsignedint), PC_VSPLTB,
- TYPE(&stvectorboolchar), TYPE(&stvectorboolchar), TYPE(&stsignedint), PC_VSPLTB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsplth_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolshort), TYPE(&stsignedint), PC_VSPLTH,
- TYPE(&stvectorpixel), TYPE(&stvectorpixel), TYPE(&stsignedint), PC_VSPLTH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vspltw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorboollong), TYPE(&stvectorboollong), TYPE(&stsignedint), PC_VSPLTW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stsignedint), PC_VSPLTW,
- NULL, NULL, NULL, 0
-};
-static TypeTable22 vector_vspltisb_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stsignedint), PC_VSPLTISB, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_vspltish_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stsignedint), PC_VSPLTISH, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_vspltisw_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stsignedint), PC_VSPLTISW, PC_B,
- NULL, NULL, 0
-};
-static TypeTable31 vector_vsrb_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSRB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSRB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsrh_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSRH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSRH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsrw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSRW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSRW,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsrab_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSRAB,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorunsignedchar), PC_VSRAB,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsrah_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSRAH,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorunsignedshort), PC_VSRAH,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsraw_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSRAW,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorunsignedlong), PC_VSRAW,
- NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_stvebx_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedchar), TYPE(&stsignedint), TYPE(&stunsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorsignedchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVEBX,
- TYPE(&stvoid), TYPE(&stvectorboolchar), TYPE(&stsignedint), TYPE(&stsignedchar_ptr), PC_STVEBX,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_stvehx_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedshort), TYPE(&stsignedint), TYPE(&stunsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorsignedshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorboolshort), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- TYPE(&stvoid), TYPE(&stvectorpixel), TYPE(&stsignedint), TYPE(&stsignedshort_ptr), PC_STVEHX,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable41 vector_stvewx_type_table[] = {
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorunsignedlong), TYPE(&stsignedint), TYPE(&stunsignedlong_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorsignedlong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorfloat), TYPE(&stsignedint), TYPE(&stfloat_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedint_ptr), PC_STVEWX,
- TYPE(&stvoid), TYPE(&stvectorboollong), TYPE(&stsignedint), TYPE(&stsignedlong_ptr), PC_STVEWX,
- NULL, NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsububm_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSUBUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBM,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBM,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VSUBUBM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubuhm_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSUBUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHM,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHM,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VSUBUHM,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubuwm_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSUBUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VSUBUWM,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VSUBUWM,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VSUBUWM,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VSUBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubfp_type_table[] = {
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VSUBFP,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsububs_type_table[] = {
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), PC_VSUBUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), PC_VSUBUBS,
- TYPE(&stvectorunsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorunsignedchar), PC_VSUBUBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubsbs_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), PC_VSUBSBS,
- TYPE(&stvectorsignedchar), TYPE(&stvectorboolchar), TYPE(&stvectorsignedchar), PC_VSUBSBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubuhs_type_table[] = {
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), PC_VSUBUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), PC_VSUBUHS,
- TYPE(&stvectorunsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorunsignedshort), PC_VSUBUHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubshs_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), PC_VSUBSHS,
- TYPE(&stvectorsignedshort), TYPE(&stvectorboolshort), TYPE(&stvectorsignedshort), PC_VSUBSHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubuws_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), PC_VSUBUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), PC_VSUBUWS,
- TYPE(&stvectorunsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorunsignedlong), PC_VSUBUWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsubsws_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), PC_VSUBSWS,
- TYPE(&stvectorsignedlong), TYPE(&stvectorboollong), TYPE(&stvectorsignedlong), PC_VSUBSWS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsum4ubs_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorunsignedchar), TYPE(&stvectorunsignedlong), PC_VSUM4UBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsum4sbs_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedchar), TYPE(&stvectorsignedlong), PC_VSUM4SBS,
- NULL, NULL, NULL, 0
-};
-static TypeTable31 vector_vsum4shs_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), TYPE(&stvectorsignedlong), PC_VSUM4SHS,
- NULL, NULL, NULL, 0
-};
-static TypeTable21 vector_vupkhsb_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VUPKHSB,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolchar), PC_VUPKHSB,
- NULL, NULL, 0
-};
-static TypeTable21 vector_vupklsb_type_table[] = {
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedchar), PC_VUPKLSB,
- TYPE(&stvectorboolshort), TYPE(&stvectorboolchar), PC_VUPKLSB,
- NULL, NULL, 0
-};
-static TypeTable22 vector_vupkhpx_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorpixel), PC_VUPKHPX, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_vupklpx_type_table[] = {
- TYPE(&stvectorunsignedlong), TYPE(&stvectorpixel), PC_VUPKLPX, PC_B,
- NULL, NULL, 0
-};
-static TypeTable21 vector_vupkhsh_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), PC_VUPKHSH,
- TYPE(&stvectorboollong), TYPE(&stvectorboolshort), PC_VUPKHSH,
- NULL, NULL, 0
-};
-static TypeTable21 vector_vupklsh_type_table[] = {
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedshort), PC_VUPKLSH,
- TYPE(&stvectorboollong), TYPE(&stvectorboolshort), PC_VUPKLSH,
- NULL, NULL, 0
-};
-static TypeTable22 vector_abs_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBUBM, PC_VMAXSB,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBUHM, PC_VMAXSH,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBUWM, PC_VMAXSW,
- TYPE(&stvectorfloat), TYPE(&stvectorfloat), PC_VANDC, PC_B,
- NULL, NULL, 0
-};
-static TypeTable22 vector_abss_type_table[] = {
- TYPE(&stvectorsignedchar), TYPE(&stvectorsignedchar), PC_VSUBSBS, PC_VMAXSB,
- TYPE(&stvectorsignedshort), TYPE(&stvectorsignedshort), PC_VSUBSHS, PC_VMAXSH,
- TYPE(&stvectorsignedlong), TYPE(&stvectorsignedlong), PC_VSUBSWS, PC_VMAXSW,
- NULL, NULL, 0
-};
-static void *typeTable[] = {
- vector_add_type_table,
- vector_addc_type_table,
- vector_adds_type_table,
- vector_and_type_table,
- vector_andc_type_table,
- vector_avg_type_table,
- vector_ceil_type_table,
- vector_cmpb_type_table,
- vector_cmpeq_type_table,
- vector_cmpge_type_table,
- vector_cmpge_type_table,
- vector_cmpgt_type_table,
- vector_cmpgt_type_table,
- vector_ctf_type_table,
- vector_cts_type_table,
- vector_ctu_type_table,
- vector_dss_type_table,
- vector_dssall_type_table,
- vector_datastream_type_table,
- vector_datastream_type_table,
- vector_datastream_type_table,
- vector_datastream_type_table,
- vector_expte_type_table,
- vector_floor_type_table,
- vector_load_type_table,
- vector_loade_type_table,
- vector_loadl_type_table,
- vector_loge_type_table,
- vector_lvsl_type_table,
- vector_lvsr_type_table,
- vector_madd_type_table,
- vector_madds_type_table,
- vector_max_type_table,
- vector_mergeh_type_table,
- vector_mergel_type_table,
- vector_mfvscr_type_table,
- vector_min_type_table,
- vector_mladd_type_table,
- vector_mradds_type_table,
- vector_msum_type_table,
- vector_msums_type_table,
- vector_mtvscr_type_table,
- vector_mule_type_table,
- vector_mulo_type_table,
- vector_nmsub_type_table,
- vector_nor_type_table,
- vector_or_type_table,
- vector_pack_type_table,
- vector_packpx_type_table,
- vector_packs_type_table,
- vector_packsu_type_table,
- vector_perm_type_table,
- vector_re_type_table,
- vector_rl_type_table,
- vector_round_type_table,
- vector_rsqrte_type_table,
- vector_sel_type_table,
- vector_sl_type_table,
- vector_sld_type_table,
- vector_sll_type_table,
- vector_slo_type_table,
- vector_splat_type_table,
- vector_splat_s8_type_table,
- vector_splat_s16_type_table,
- vector_splat_s32_type_table,
- vector_splat_u8_type_table,
- vector_splat_u16_type_table,
- vector_splat_u32_type_table,
- vector_sr_type_table,
- vector_sra_type_table,
- vector_srl_type_table,
- vector_sro_type_table,
- vector_st_type_table,
- vector_ste_type_table,
- vector_stl_type_table,
- vector_sub_type_table,
- vector_subc_type_table,
- vector_subs_type_table,
- vector_sum4s_type_table,
- vector_sum2s_type_table,
- vector_sums_type_table,
- vector_trunc_type_table,
- vector_unpack2sh_type_table,
- vector_unpack2sl_type_table,
- vector_unpack2uh_type_table,
- vector_unpack2ul_type_table,
- vector_unpackh_type_table,
- vector_unpackl_type_table,
- vector_xor_type_table,
- vector_all_eq_type_table,
- vector_all_ge_type_table,
- vector_all_gt_type_table,
- vector_all_in_type_table,
- vector_all_le_type_table,
- vector_all_lt_type_table,
- vector_all_nan_type_table,
- vector_all_ne_type_table,
- vector_all_nge_type_table,
- vector_all_ngt_type_table,
- vector_all_nle_type_table,
- vector_all_nlt_type_table,
- vector_all_numeric_type_table,
- vector_any_eq_type_table,
- vector_any_ge_type_table,
- vector_any_gt_type_table,
- vector_any_le_type_table,
- vector_any_lt_type_table,
- vector_any_nan_type_table,
- vector_any_ne_type_table,
- vector_any_nge_type_table,
- vector_any_ngt_type_table,
- vector_any_nle_type_table,
- vector_any_nlt_type_table,
- vector_any_numeric_type_table,
- vector_any_out_type_table,
- vector_vaddubm_type_table,
- vector_vadduhm_type_table,
- vector_vadduwm_type_table,
- vector_vaddfp_type_table,
- vector_addc_type_table,
- vector_vaddubs_type_table,
- vector_vaddsbs_type_table,
- vector_vadduhs_type_table,
- vector_vaddshs_type_table,
- vector_vadduws_type_table,
- vector_vaddsws_type_table,
- vector_and_type_table,
- vector_andc_type_table,
- vector_vavgub_type_table,
- vector_vavgsb_type_table,
- vector_vavguh_type_table,
- vector_vavgsh_type_table,
- vector_vavguw_type_table,
- vector_vavgsw_type_table,
- vector_ceil_type_table,
- vector_cmpb_type_table,
- vector_vcmpequb_type_table,
- vector_vcmpequh_type_table,
- vector_vcmpequw_type_table,
- vector_vcmpeqfp_type_table,
- vector_cmpge_type_table,
- vector_vcmpgtub_type_table,
- vector_vcmpgtsb_type_table,
- vector_vcmpgtuh_type_table,
- vector_vcmpgtsh_type_table,
- vector_vcmpgtuw_type_table,
- vector_vcmpgtsw_type_table,
- vector_vcmpgtfp_type_table,
- vector_vcfux_type_table,
- vector_vcfsx_type_table,
- vector_cts_type_table,
- vector_ctu_type_table,
- vector_expte_type_table,
- vector_floor_type_table,
- vector_load_type_table,
- vector_lvebx_type_table,
- vector_lvehx_type_table,
- vector_lvewx_type_table,
- vector_loadl_type_table,
- vector_loge_type_table,
- vector_madd_type_table,
- vector_madds_type_table,
- vector_vmaxub_type_table,
- vector_vmaxsb_type_table,
- vector_vmaxuh_type_table,
- vector_vmaxsh_type_table,
- vector_vmaxuw_type_table,
- vector_vmaxsw_type_table,
- vector_vmaxfp_type_table,
- vector_vmrghb_type_table,
- vector_vmrghh_type_table,
- vector_vmrghw_type_table,
- vector_vmrglb_type_table,
- vector_vmrglh_type_table,
- vector_vmrglw_type_table,
- vector_vminub_type_table,
- vector_vminsb_type_table,
- vector_vminuh_type_table,
- vector_vminsh_type_table,
- vector_vminuw_type_table,
- vector_vminsw_type_table,
- vector_vminfp_type_table,
- vector_mladd_type_table,
- vector_mradds_type_table,
- vector_vmsumubm_type_table,
- vector_vmsumuhm_type_table,
- vector_vmsummbm_type_table,
- vector_vmsumshm_type_table,
- vector_vmsumuhs_type_table,
- vector_vmsumshs_type_table,
- vector_vmuleub_type_table,
- vector_vmulesb_type_table,
- vector_vmuleuh_type_table,
- vector_vmulesh_type_table,
- vector_vmuloub_type_table,
- vector_vmulosb_type_table,
- vector_vmulouh_type_table,
- vector_vmulosh_type_table,
- vector_nmsub_type_table,
- vector_nor_type_table,
- vector_or_type_table,
- vector_vpkuhum_type_table,
- vector_vpkuwum_type_table,
- vector_packpx_type_table,
- vector_vpkuhus_type_table,
- vector_vpkshss_type_table,
- vector_vpkuwus_type_table,
- vector_vpkswss_type_table,
- vector_vpkshus_type_table,
- vector_vpkswus_type_table,
- vector_perm_type_table,
- vector_re_type_table,
- vector_vrlb_type_table,
- vector_vrlh_type_table,
- vector_vrlw_type_table,
- vector_round_type_table,
- vector_rsqrte_type_table,
- vector_sel_type_table,
- vector_vslb_type_table,
- vector_vslh_type_table,
- vector_vslw_type_table,
- vector_sld_type_table,
- vector_sll_type_table,
- vector_slo_type_table,
- vector_vspltb_type_table,
- vector_vsplth_type_table,
- vector_vspltw_type_table,
- vector_vspltisb_type_table,
- vector_vspltish_type_table,
- vector_vspltisw_type_table,
- vector_vsrb_type_table,
- vector_vsrh_type_table,
- vector_vsrw_type_table,
- vector_vsrab_type_table,
- vector_vsrah_type_table,
- vector_vsraw_type_table,
- vector_srl_type_table,
- vector_sro_type_table,
- vector_st_type_table,
- vector_stvebx_type_table,
- vector_stvehx_type_table,
- vector_stvewx_type_table,
- vector_stl_type_table,
- vector_vsububm_type_table,
- vector_vsubuhm_type_table,
- vector_vsubuwm_type_table,
- vector_vsubfp_type_table,
- vector_subc_type_table,
- vector_vsububs_type_table,
- vector_vsubsbs_type_table,
- vector_vsubuhs_type_table,
- vector_vsubshs_type_table,
- vector_vsubuws_type_table,
- vector_vsubsws_type_table,
- vector_vsum4ubs_type_table,
- vector_vsum4sbs_type_table,
- vector_vsum4shs_type_table,
- vector_sum2s_type_table,
- vector_sums_type_table,
- vector_trunc_type_table,
- vector_vupkhsb_type_table,
- vector_vupklsb_type_table,
- vector_vupkhpx_type_table,
- vector_vupklpx_type_table,
- vector_vupkhsh_type_table,
- vector_vupklsh_type_table,
- vector_xor_type_table,
- vector_abs_type_table,
- vector_abss_type_table,
- NULL
-};
-
-int is_intrinsic_function_call(ENode *funccall) {
- ENode *funcref = funccall->data.funccall.funcref;
- return
- ENODE_IS(funcref, EOBJREF) &&
- funcref->data.objref->datatype == DFUNC &&
- (TYPE_FUNC(funcref->data.objref->type)->flags & FUNC_INTRINSIC);
-}
-
-static void abs_intrinsic(ENode *expr, short outputReg, Operand *output) {
- int reg1;
- int reg2;
- Operand op;
-
- memclrw(&op, sizeof(op));
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
-
- reg1 = ALLOC_GPR();
- emitpcode(PC_SRAWI, reg1, op.reg, 31);
-
- reg2 = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_XOR, reg2, reg1, op.reg);
- emitpcode(PC_SUBF, reg2, reg1, reg2);
-
- output->optype = OpndType_GPR;
- output->reg = reg2;
-}
-
-static void setflm_intrinsic(ENode *expr, short outputReg, Operand *output, int flag) {
- int reg;
- Operand op;
-
- memclrw(&op, sizeof(op));
- GEN_NODE_TO_FPR(expr, &op, expr->rtype, 0);
-
- if (!flag) {
- output->optype = OpndType_FPR;
- reg = (outputReg && outputReg != op.reg) ? outputReg : ALLOC_FPR();
- emitpcode(PC_MFFS, output->reg = reg);
- }
-
- emitpcode(PC_MTFSF, 255, op.reg);
-}
-
-static void alloca_intrinsic(ENode *expr, short outputReg, Operand *output) {
- int reg;
- Operand op;
-
- memclrw(&op, sizeof(op));
-
- if (ENODE_IS(expr, EINTCONST)) {
- reg = outputReg ? outputReg : ALLOC_GPR();
- allocate_dynamic_stack_space(
- 1, reg, ALLOC_GPR(), CInt64_GetULong(&expr->data.intval));
- } else {
- GEN_NODE_TO_GPR(expr, &op, expr->rtype, 0);
- reg = outputReg ? outputReg : ALLOC_GPR();
-
- emitpcode(PC_NEG, reg, op.reg);
- emitpcode(PC_RLWINM, reg, reg, 0, 0, get_alloca_alignment());
- allocate_dynamic_stack_space(0, reg, ALLOC_GPR(), 0);
- }
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void load_bytereversed_intrinsic(Opcode opcode, ENode *expr1, ENode *expr2, short outputReg, Operand *output) {
- int reg;
- Operand op1;
- Operand op2;
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
-
- if (ENODE_IS(expr2, EINTCONST) && expr2->data.intval.lo == 0) {
- GEN_NODE(expr1, &op1);
- if (op1.optype == OpndType_GPR_Indexed) {
- emitpcode(opcode, reg, op1.reg, op1.regOffset);
- } else {
- ENSURE_GPR(&op1, expr1->rtype, 0);
- emitpcode(opcode, reg, 0, op1.reg);
- }
- } else {
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_GPR(expr2, &op2, expr2->rtype, 0);
- emitpcode(opcode, reg, op1.reg, op2.reg);
- }
-
- setpcodeflags(fSideEffects | ((expr1->flags | expr2->flags | output->flags) & (fIsConst | fIsVolatile)));
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void store_bytereversed_intrinsic(Opcode opcode, ENode *expr1, ENode *expr2, ENode *expr3) {
- Operand op1;
- Operand op2;
- Operand op3;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- memclrw(&op3, sizeof(op3));
-
- if (ENODE_IS(expr3, EINTCONST) && expr3->data.intval.lo == 0) {
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE(expr2, &op2);
- if (op2.optype == OpndType_GPR_Indexed) {
- emitpcode(opcode, op1.reg, op2.reg, op2.regOffset);
- } else {
- ENSURE_GPR(&op2, expr2->rtype, 0);
- emitpcode(opcode, op1.reg, 0, op2.reg);
- }
- } else {
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_GPR(expr2, &op2, expr2->rtype, 0);
- GEN_NODE_TO_GPR(expr3, &op3, expr3->rtype, 0);
- emitpcode(opcode, op1.reg, op2.reg, op3.reg);
- }
-
- setpcodeflags(fSideEffects | ((op1.flags | op2.flags | op3.flags) & (fIsConst | fIsVolatile)));
-}
-
-static void data_cache_block_intrinsic(Opcode opcode, ENode *expr1, ENode *expr2) {
- Operand op1;
- Operand op2;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
-
- if (ENODE_IS(expr2, EINTCONST) && expr2->data.intval.lo == 0) {
- GEN_NODE(expr1, &op1);
- if (op1.optype == OpndType_GPR_Indexed) {
- emitpcode(opcode, op1.reg, op1.regOffset);
- } else {
- ENSURE_GPR(&op1, expr1->rtype, 0);
- emitpcode(opcode, 0, op1.reg);
- }
- } else {
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_GPR(expr2, &op2, expr2->rtype, 0);
- emitpcode(opcode, op1.reg, op2.reg);
- }
-}
-
-static void memcpy_intrinsic(ENode *destexpr, ENode *srcexpr, SInt32 size, Boolean ignored, Operand *output) {
- UInt32 qual;
- Operand destOp;
- Operand srcOp;
-
- qual = 0;
-
- memclrw(&destOp, sizeof(destOp));
- memclrw(&srcOp, sizeof(srcOp));
-
- GEN_NODE(srcexpr, &srcOp);
- indirect(&srcOp, srcexpr);
-
- GEN_NODE(destexpr, output);
- destOp = *output;
- indirect(&destOp, destexpr);
-
- if (destOp.object)
- qual = destOp.object->qual;
-
- move_block(&destOp, &srcOp, size, destexpr->rtype ? CMach_AllocationAlignment(destexpr->rtype, qual) : 1);
-}
-
-static SInt32 checkconstintarg(ENode *expr, char *name, SInt32 min, SInt32 max, int argnum) {
- SInt32 value;
-
- if (!ENODE_IS(expr, EINTCONST))
- PPCError_ErrorTerm(PPCErrorStr210, name, 3, max, argnum);
-
- value = CInt64_GetULong(&expr->data.intval);
-
- if (value < min) {
- PPCError_Warning(PPCErrorStr211, name, argnum, value, min, max, min);
- return min;
- }
-
- if (value > max) {
- PPCError_Warning(PPCErrorStr211, name, argnum, value, min, max, value & max);
- value = value & max;
- }
-
- return value;
-}
-
-static void rlwimi_intrinsic(ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode *expr5, short outputReg, Operand *output) {
- SInt32 arg3;
- SInt32 arg4;
- SInt32 arg5;
- Operand op1;
- Operand op2;
- int reg;
- char *name = "__rlwimi";
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
-
- arg3 = checkconstintarg(expr3, name, 0, 31, 3);
- arg4 = checkconstintarg(expr4, name, 0, 31, 4);
- arg5 = checkconstintarg(expr5, name, 0, 31, 5);
-
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
-
- GEN_NODE(expr2, &op2);
- if (copts.optimizationlevel > 1) {
- reg = ALLOC_GPR();
- emitpcode(PC_MR, reg, op1.reg);
- op1.reg = reg;
- }
- ENSURE_GPR(&op2, expr2->rtype, 0);
-
- emitpcode(PC_RLWIMI, op1.reg, op2.reg, arg3, arg4, arg5);
-
- output->optype = OpndType_GPR;
- output->reg = op1.reg;
-}
-
-static void rlwinm_intrinsic(ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, short outputReg, Operand *output) {
- char *name = "__rlwinm";
- short reg;
- short arg2;
- short arg3;
- short arg4;
- Operand op1;
-
- memclrw(&op1, sizeof(op1));
- arg2 = checkconstintarg(expr2, name, 0, 31, 2);
- arg3 = checkconstintarg(expr3, name, 0, 31, 3);
- arg4 = checkconstintarg(expr4, name, 0, 31, 4);
-
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWINM, reg, op1.reg, arg2, arg3, arg4);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static void rlwnm_intrinsic(ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, short outputReg, Operand *output) {
- short reg;
- short arg3;
- short arg4;
- char *name = "__rlwnm";
- Operand op1;
- Operand op2;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- arg3 = checkconstintarg(expr3, name, 0, 31, 3);
- arg4 = checkconstintarg(expr4, name, 0, 31, 4);
-
- GEN_NODE_TO_GPR(expr1, &op1, expr1->rtype, 0);
- GEN_NODE_TO_GPR(expr2, &op2, expr2->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_GPR();
- emitpcode(PC_RLWNM, reg, op1.reg, op2.reg, arg3, arg4);
-
- output->optype = OpndType_GPR;
- output->reg = reg;
-}
-
-static Boolean promotable_types_are_equal(Type *a, Type *b) {
- if (a == b)
- return 1;
-
- if (a == TYPE(&stsignedint)) {
- if (
- b == TYPE(&stunsignedint) ||
- b == TYPE(&stsignedchar) ||
- b == TYPE(&stunsignedchar) ||
- b == TYPE(&stsignedshort) ||
- b == TYPE(&stunsignedshort) ||
- b == TYPE(&stsignedlong) ||
- b == TYPE(&stunsignedlong) ||
- b == TYPE(&stbool)
- )
- return 1;
- }
-
- return 0;
-}
-
-static int Intrinsics_VerifyParameterCount(int wantedCount, ENodeList *args, HashNameNode *name) {
- ENodeList *scan;
- int count;
-
- for (scan = args, count = 0; scan; scan = scan->next)
- count++;
-
- if (count != wantedCount) {
- PPCError_Error(PPCErrorStr103, name->name, count, wantedCount);
- return 0;
- }
-
- return 1;
-}
-
-static ENode *Intrinsics_CreateIntrinsicFunc(Object *func, ENodeList *args, Type *rtype) {
- TypeFunc *tfunc;
- ENodeList *scan;
- ENode *expr;
-
- tfunc = TYPE_FUNC(func->type);
- CError_ASSERT(3741, IS_TYPE_FUNC(tfunc));
-
- for (scan = args; scan; scan = scan->next) {
- if (IS_TYPE_ARRAY(scan->node->rtype))
- scan->node = CExpr_PointerGeneration(scan->node);
- }
-
- expr = lalloc(sizeof(ENode));
- expr->type = EFUNCCALL;
- expr->cost = 4;
- expr->rtype = rtype;
- expr->ignored = 0;
- expr->flags = tfunc->qual & ENODE_FLAG_QUALS;
- expr->data.funccall.funcref = create_objectrefnode(func);
- expr->data.funccall.args = args;
- expr->data.funccall.functype = tfunc;
- return CExpr_AdjustFunctionCall(expr);
-}
-
-static Type *Intrinsics_Verify1VectorArg2Ops(Intrinsics id, ENodeList *args, HashNameNode *name) {
- ENode *arg1;
- TypeTable22 *table;
- Type *typeA;
- Type *typeB;
- Type *rtype;
-
- arg1 = args->node;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB = arg1->rtype;
- typeA = table->arg1;
- if (IS_TYPE_POINTER(typeA) && IS_TYPE_POINTER(typeB)) {
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- }
- if (promotable_types_are_equal(typeA, typeB))
- break;
- }
-
- rtype = table->rtype;
- if (!rtype) {
- PPCError_Error(PPCErrorStr104, name->name, name->name, arg1->rtype, 0);
- rtype = NULL;
- }
- return rtype;
-}
-
-static Type *Intrinsics_VerifyNoVectorArgs(Intrinsics id, HashNameNode *name) {
- TypeTable11 *table = typeTable[id - Intrinsic_042];
- return table->rtype;
-}
-
-static Type *Intrinsics_Verify1VectorArg(Intrinsics id, ENodeList *args, HashNameNode *name) {
- ENode *arg1;
- TypeTable21 *table;
- Type *typeA;
- Type *typeB;
- Type *rtype;
-
- arg1 = args->node;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB = arg1->rtype;
- typeA = table->arg1;
- if (IS_TYPE_POINTER(typeA) && IS_TYPE_POINTER(typeB)) {
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- }
- if (promotable_types_are_equal(typeA, typeB))
- break;
- }
-
- switch (id) {
- case Intrinsic_104:
- case Intrinsic_105:
- case Intrinsic_106:
- case Intrinsic_107:
- case Intrinsic_108:
- case Intrinsic_109:
- case Intrinsic_269:
- case Intrinsic_270:
- case Intrinsic_271:
- if (ENODE_IS(arg1, EINTCONST)) {
- SInt32 val = arg1->data.intval.lo;
- if (val > 15 || val < -16) {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 5);
- return NULL;
- }
- } else {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 5);
- return NULL;
- }
- break;
- case Intrinsic_058:
- if (ENODE_IS(arg1, EINTCONST)) {
- SInt32 val = arg1->data.intval.lo;
- if (val > 3 || val < 0) {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 2);
- return NULL;
- }
- } else {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 2);
- return NULL;
- }
- break;
- }
-
- rtype = table->rtype;
- if (!rtype) {
- PPCError_Error(PPCErrorStr104, name->name, name->name, arg1->rtype, 0);
- rtype = NULL;
- }
- return rtype;
-}
-
-static Type *Intrinsics_Verify2VectorArgs(Intrinsics id, ENodeList *args, HashNameNode *name) {
- ENode *arg1;
- ENode *arg2;
- TypeTable31 *table;
- Type *typeB1;
- Type *typeB2;
- Type *typeA1;
- Type *typeA2;
-
- arg1 = args->node;
- arg2 = args->next->node;
- table = typeTable[id - Intrinsic_042];
-
- switch (id) {
- case Intrinsic_055:
- case Intrinsic_056:
- case Intrinsic_057:
- case Intrinsic_103:
- case Intrinsic_190:
- case Intrinsic_191:
- case Intrinsic_192:
- case Intrinsic_193:
- case Intrinsic_266:
- case Intrinsic_267:
- case Intrinsic_268:
- if (ENODE_IS(arg2, EINTCONST)) {
- if (arg2->data.intval.lo > 31 || arg2->data.intval.hi < 0) {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 5);
- return NULL;
- }
- } else {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 5);
- return NULL;
- }
- break;
- }
-
- for (; table->rtype; table++) {
- typeB1 = arg1->rtype;
- typeB2 = arg2->rtype;
- typeA1 = table->arg1;
- typeA2 = table->arg2;
- if (IS_TYPE_POINTER(typeA1) && IS_TYPE_POINTER(typeB1)) {
- typeA1 = TPTR_TARGET(typeA1);
- typeB1 = TPTR_TARGET(typeB1);
- }
- if (IS_TYPE_POINTER(typeA2) && IS_TYPE_POINTER(typeB2)) {
- typeA2 = TPTR_TARGET(typeA2);
- typeB2 = TPTR_TARGET(typeB2);
- }
- if (promotable_types_are_equal(typeA1, typeB1) &&
- promotable_types_are_equal(typeA2, typeB2))
- break;
- }
-
- if (!table->rtype) {
- PPCError_Error(PPCErrorStr105, name->name, name->name, arg1->rtype, 0, arg2->rtype, 0);
- return NULL;
- }
-
- switch (id) {
- case Intrinsic_066:
- case Intrinsic_067:
- case Intrinsic_068:
- if (arg2->flags & ENODE_FLAG_VOLATILE)
- PPCError_Warning(PPCErrorStr178, name->name);
- }
-
- return table->rtype;
-}
-
-static Type *Intrinsics_Verify3VectorArgs(Intrinsics id, ENodeList *args, HashNameNode *name) {
- ENode *arg1;
- ENode *arg2;
- ENode *arg3;
- TypeTable41 *table;
- Type *typeB1;
- Type *typeB2;
- Type *typeB3;
- Type *typeA1;
- Type *typeA2;
- Type *typeA3;
-
- arg1 = args->node;
- arg2 = args->next->node;
- arg3 = args->next->next->node;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB1 = arg1->rtype;
- typeB2 = arg2->rtype;
- typeB3 = arg3->rtype;
- typeA1 = table->arg1;
- typeA2 = table->arg2;
- typeA3 = table->arg3;
- if (IS_TYPE_POINTER(typeA1) && IS_TYPE_POINTER(typeB1)) {
- typeA1 = TPTR_TARGET(typeA1);
- typeB1 = TPTR_TARGET(typeB1);
- }
- if (IS_TYPE_POINTER(typeA2) && IS_TYPE_POINTER(typeB2)) {
- typeA2 = TPTR_TARGET(typeA2);
- typeB2 = TPTR_TARGET(typeB2);
- }
- if (IS_TYPE_POINTER(typeA3) && IS_TYPE_POINTER(typeB3)) {
- typeA3 = TPTR_TARGET(typeA3);
- typeB3 = TPTR_TARGET(typeB3);
- }
- if (promotable_types_are_equal(typeA1, typeB1) &&
- promotable_types_are_equal(typeA2, typeB2) &&
- promotable_types_are_equal(typeA3, typeB3))
- break;
- }
-
- switch (id) {
- case Intrinsic_060:
- case Intrinsic_061:
- case Intrinsic_062:
- case Intrinsic_063:
- if (ENODE_IS(arg3, EINTCONST)) {
- SInt32 val = arg3->data.intval.lo;
- if (val > 3 || val < 0) {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 2);
- return NULL;
- }
- } else {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 2);
- return NULL;
- }
- break;
- case Intrinsic_100:
- case Intrinsic_263:
- if (ENODE_IS(arg3, EINTCONST)) {
- if (arg3->data.intval.lo > 15 || arg3->data.intval.hi < 0) {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 4);
- return NULL;
- }
- } else {
- PPCError_Error(PPCErrorStr108, name->name, name->name, 4);
- return NULL;
- }
- break;
- }
-
- if (!table->rtype) {
- PPCError_Error(PPCErrorStr106, name->name, name->name, arg1->rtype, 0, arg2->rtype, 0, arg3->rtype, 0);
- return NULL;
- }
-
- switch (id) {
- case Intrinsic_114:
- case Intrinsic_115:
- case Intrinsic_116:
- if (arg3->flags & ENODE_FLAG_VOLATILE)
- PPCError_Warning(PPCErrorStr178, name->name);
- }
-
- return table->rtype;
-}
-
-static Opcode Intrinsics_FindOpcodeNoArgs(Intrinsics id, ENode *funccall) {
- TypeTable11 *table = typeTable[id - Intrinsic_042];
- return table->opcode;
-}
-
-static Opcode Intrinsics_FindOpcode1Arg(Intrinsics id, ENode *funccall, ENode *arg1) {
- TypeTable21 *table;
- Type *typeA;
- Type *typeB;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB = arg1->rtype;
- typeA = table->arg1;
- if (IS_TYPE_POINTER(typeA) && IS_TYPE_POINTER(typeB)) {
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- }
- if (promotable_types_are_equal(typeA, typeB))
- break;
- }
-
- CError_ASSERT(4105, table->rtype);
- return table->opcode;
-}
-
-static Opcode Intrinsics_FindOpcode2Args(Intrinsics id, ENode *funccall, ENode *arg1, ENode *arg2) {
- TypeTable31 *table;
- Type *typeB1;
- Type *typeB2;
- Type *typeA1;
- Type *typeA2;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB1 = arg1->rtype;
- typeB2 = arg2->rtype;
- typeA1 = table->arg1;
- typeA2 = table->arg2;
- if (IS_TYPE_POINTER(typeA1) && IS_TYPE_POINTER(typeB1)) {
- typeA1 = TPTR_TARGET(typeA1);
- typeB1 = TPTR_TARGET(typeB1);
- }
- if (IS_TYPE_POINTER(typeA2) && IS_TYPE_POINTER(typeB2)) {
- typeA2 = TPTR_TARGET(typeA2);
- typeB2 = TPTR_TARGET(typeB2);
- }
- if (promotable_types_are_equal(typeA1, typeB1) &&
- promotable_types_are_equal(typeA2, typeB2))
- break;
- }
-
- CError_ASSERT(4144, table->rtype);
- return table->opcode;
-}
-
-static Opcode Intrinsics_FindOpcode3Args(Intrinsics id, ENode *funccall, ENode *arg1, ENode *arg2, ENode *arg3) {
- TypeTable41 *table;
- Type *typeB1;
- Type *typeB2;
- Type *typeB3;
- Type *typeA1;
- Type *typeA2;
- Type *typeA3;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB1 = arg1->rtype;
- typeB2 = arg2->rtype;
- typeB3 = arg3->rtype;
- typeA1 = table->arg1;
- typeA2 = table->arg2;
- typeA3 = table->arg3;
- if (IS_TYPE_POINTER(typeA1) && IS_TYPE_POINTER(typeB1)) {
- typeA1 = TPTR_TARGET(typeA1);
- typeB1 = TPTR_TARGET(typeB1);
- }
- if (IS_TYPE_POINTER(typeA2) && IS_TYPE_POINTER(typeB2)) {
- typeA2 = TPTR_TARGET(typeA2);
- typeB2 = TPTR_TARGET(typeB2);
- }
- if (IS_TYPE_POINTER(typeA3) && IS_TYPE_POINTER(typeB3)) {
- typeA3 = TPTR_TARGET(typeA3);
- typeB3 = TPTR_TARGET(typeB3);
- }
- if (promotable_types_are_equal(typeA1, typeB1) &&
- promotable_types_are_equal(typeA2, typeB2) &&
- promotable_types_are_equal(typeA3, typeB3))
- break;
- }
-
- CError_ASSERT(4191, table->rtype);
- return table->opcode;
-}
-
-static void vector_intrinsic_no_args(Opcode opcode) {
- emitpcode(opcode);
-}
-
-static void vector_intrinsic_mfvscr(short outputReg, Opcode opcode, Operand *output) {
- short reg;
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_1arg(ENode *arg1, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_splats(ENode *arg1, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- CError_ASSERT(4253, ENODE_IS(arg1, EINTCONST));
- GEN_NODE(arg1, &op1);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.immediate);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_splatu8(ENode *arg1, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- CError_ASSERT(4277, ENODE_IS(arg1, EINTCONST));
- GEN_NODE(arg1, &op1);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.immediate);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_splatu16(ENode *arg1, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- CError_ASSERT(4301, ENODE_IS(arg1, EINTCONST));
- GEN_NODE(arg1, &op1);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.immediate);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_splatu32(ENode *arg1, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- CError_ASSERT(4325, ENODE_IS(arg1, EINTCONST));
- GEN_NODE(arg1, &op1);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.immediate);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_dss(ENode *arg1) {
- Operand op1;
-
- memclrw(&op1, sizeof(op1));
- CError_ASSERT(4348, ENODE_IS(arg1, EINTCONST));
- GEN_NODE(arg1, &op1);
-
- emitpcode(PC_DSS, op1.immediate, 0);
-}
-
-static void vector_intrinsic_2args(ENode *arg1, ENode *arg2, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE_TO_VR(arg2, &op2, arg2->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg, op2.reg);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_2args1const(ENode *arg1, ENode *arg2, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- CError_ASSERT(4393, ENODE_IS(arg2, EINTCONST));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE(arg2, &op2);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg, op2.immediate);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_3args(ENode *arg1, ENode *arg2, ENode *arg3, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- Operand op3;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- memclrw(&op3, sizeof(op3));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE_TO_VR(arg2, &op2, arg2->rtype, 0);
- GEN_NODE_TO_VR(arg3, &op3, arg3->rtype, 0);
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg, op2.reg, op3.reg);
-
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_datastream(ENode *arg1, ENode *arg2, ENode *arg3, Opcode opcode) {
- Operand op1;
- Operand op2;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- CError_ASSERT(4445, ENODE_IS(arg3, EINTCONST));
- GEN_NODE_TO_GPR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE_TO_GPR(arg2, &op2, arg2->rtype, 0);
-
- switch (opcode) {
- case PC_DST:
- case PC_DSTST:
- emitpcode(opcode, op1.reg, op2.reg, arg3->data.intval.lo, 0);
- break;
- case PC_DSTT:
- case PC_DSTSTT:
- emitpcode(opcode, op1.reg, op2.reg, arg3->data.intval.lo);
- break;
- default:
- CError_FATAL(4463);
- }
-}
-
-static void vector_intrinsic_sld(ENode *arg1, ENode *arg2, ENode *arg3, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- CError_ASSERT(4479, ENODE_IS(arg3, EINTCONST));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE_TO_VR(arg2, &op2, arg2->rtype, 0);
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg, op2.reg, arg3->data.intval.lo);
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_load(ENode *arg1, ENode *arg2, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- short reg;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
-
- GEN_NODE(arg1, &op1);
- if (op1.optype == OpndType_Absolute && op1.immediate == 0) {
- op1.optype = OpndType_GPR;
- op1.reg = 0;
- } else {
- ENSURE_GPR(&op1, arg1->rtype, 0);
- }
-
- GEN_NODE(arg2, &op2);
- if (op2.optype == OpndType_Absolute && op2.immediate == 0 && op1.reg != 0) {
- op2 = op1;
- op1.optype = OpndType_GPR;
- op1.reg = 0;
- } else {
- ENSURE_GPR(&op2, arg2->rtype, 0);
- }
-
- reg = outputReg ? outputReg : ALLOC_VR();
-
- emitpcode(opcode, reg, op1.reg, op2.reg);
- output->optype = OpndType_VR;
- output->reg = reg;
-}
-
-static void vector_intrinsic_store(ENode *arg1, ENode *arg2, ENode *arg3, short outputReg, Operand *output, Opcode opcode) {
- Operand op1;
- Operand op2;
- Operand op3;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
- memclrw(&op3, sizeof(op3));
-
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
-
- GEN_NODE(arg2, &op2);
- if (op2.optype == OpndType_Absolute && op2.immediate == 0) {
- op2.optype = OpndType_GPR;
- op2.reg = 0;
- } else {
- ENSURE_GPR(&op2, arg2->rtype, 0);
- }
-
- GEN_NODE(arg3, &op3);
- if (op3.optype == OpndType_Absolute && op3.immediate == 0 && op2.reg != 0) {
- op3 = op2;
- op2.optype = OpndType_GPR;
- op2.reg = 0;
- } else {
- ENSURE_GPR(&op3, arg3->rtype, 0);
- }
-
- emitpcode(opcode, op1.reg, op2.reg, op3.reg);
- output->optype = OpndType_VR;
- output->reg = op1.reg;
-}
-
-static void vector_intrinsic_abs(Intrinsics id, ENode *funccall, ENode *arg1, short outputReg, Operand *output) {
- TypeTable22 *table;
- Type *typeA;
- Type *typeB;
- short reg1;
- short reg2;
- short reg3;
- Operand op1;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB = arg1->rtype;
- typeA = table->arg1;
- if (IS_TYPE_POINTER(typeA) && IS_TYPE_POINTER(typeB)) {
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- }
- if (promotable_types_are_equal(typeA, typeB))
- break;
- }
-
- CError_ASSERT(4617, table->rtype);
-
- reg1 = ALLOC_VR();
- reg2 = ALLOC_VR();
- reg3 = outputReg ? outputReg : ALLOC_VR();
-
- memclrw(&op1, sizeof(op1));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
-
- if (arg1->rtype == TYPE(&stvectorfloat)) {
- emitpcode(PC_VSPLTISW, reg1, -1);
- emitpcode(PC_VSLW, reg2, reg1, reg1);
- emitpcode(table->opcode1, reg3, op1.reg, reg2);
- } else {
- emitpcode(PC_VSPLTISB, reg1, 0);
- emitpcode(table->opcode1, reg2, reg1, op1.reg);
- emitpcode(table->opcode2, reg3, op1.reg, reg2);
- }
-
- output->optype = OpndType_VR;
- output->reg = reg3;
-}
-
-static void vector_intrinsic_abss(Intrinsics id, ENode *funccall, ENode *arg1, short outputReg, Operand *output) {
- TypeTable22 *table;
- Type *typeA;
- Type *typeB;
- short reg1;
- short reg2;
- short reg3;
- Operand op1;
-
- for (table = typeTable[id - Intrinsic_042]; table->rtype; table++) {
- typeB = arg1->rtype;
- typeA = table->arg1;
- if (IS_TYPE_POINTER(typeA) && IS_TYPE_POINTER(typeB)) {
- typeA = TPTR_TARGET(typeA);
- typeB = TPTR_TARGET(typeB);
- }
- if (promotable_types_are_equal(typeA, typeB))
- break;
- }
-
- CError_ASSERT(4683, table->rtype);
-
- reg1 = ALLOC_VR();
- reg2 = ALLOC_VR();
- reg3 = outputReg ? outputReg : ALLOC_VR();
-
- memclrw(&op1, sizeof(op1));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
-
- emitpcode(PC_VSPLTISB, reg1, 0);
- emitpcode(table->opcode1, reg2, reg1, op1.reg);
- emitpcode(table->opcode2, reg3, op1.reg, reg2);
-
- output->optype = OpndType_VR;
- output->reg = reg3;
-}
-
-static void vector_intrinsic_mtvscr(ENode *arg1, Operand *output, Opcode opcode) {
- Operand op1;
-
- memclrw(&op1, sizeof(op1));
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- emitpcode(opcode, op1.reg);
-}
-
-static void vector_predicate_2args(ENode *arg1, ENode *arg2, short outputReg, Operand *output, Opcode opcode, Intrinsics id) {
- Operand op1;
- Operand op2;
- short reg1;
- short reg2;
- short reg3;
- Opcode cond;
-
- memclrw(&op1, sizeof(op1));
- memclrw(&op2, sizeof(op2));
-
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
- GEN_NODE_TO_VR(arg2, &op2, arg2->rtype, 0);
-
- reg1 = ALLOC_VR();
- reg2 = op1.reg;
- reg3 = op2.reg;
- if (
- ((id == Intrinsic_132 || id == Intrinsic_145) && arg1->rtype != TYPE(&stvectorfloat)) ||
- ((id == Intrinsic_135 || id == Intrinsic_147) && arg1->rtype == TYPE(&stvectorfloat)) ||
- id == Intrinsic_136 ||
- id == Intrinsic_148 ||
- id == Intrinsic_153 ||
- id == Intrinsic_141 ||
- id == Intrinsic_142 ||
- id == Intrinsic_154
- )
- {
- reg3 = op1.reg;
- reg2 = op2.reg;
- }
- emitpcode(opcode, reg1, reg2, reg3);
- pcsetrecordbit(pclastblock->lastPCode);
-
- if (arg1->rtype == TYPE(&stvectorfloat)) {
- switch (id) {
- case Intrinsic_131:
- case Intrinsic_132:
- case Intrinsic_133:
- case Intrinsic_135:
- case Intrinsic_136:
- cond = ELESS;
- break;
- case Intrinsic_150:
- case Intrinsic_151:
- case Intrinsic_152:
- case Intrinsic_153:
- case Intrinsic_154:
- cond = EGREATEREQU;
- break;
- case Intrinsic_134:
- case Intrinsic_138:
- case Intrinsic_139:
- case Intrinsic_140:
- case Intrinsic_141:
- case Intrinsic_142:
- cond = EEQU;
- break;
- case Intrinsic_144:
- case Intrinsic_145:
- case Intrinsic_146:
- case Intrinsic_147:
- case Intrinsic_148:
- case Intrinsic_156:
- cond = ENOTEQU;
- break;
- default:
- CError_FATAL(4805);
- }
- } else {
- switch (id) {
- case Intrinsic_131:
- case Intrinsic_133:
- case Intrinsic_136:
- cond = ELESS;
- break;
- case Intrinsic_144:
- case Intrinsic_146:
- case Intrinsic_148:
- cond = ENOTEQU;
- break;
- case Intrinsic_132:
- case Intrinsic_135:
- case Intrinsic_138:
- cond = EEQU;
- break;
- case Intrinsic_145:
- case Intrinsic_147:
- case Intrinsic_150:
- cond = EGREATEREQU;
- break;
- default:
- CError_FATAL(4834);
- }
- }
-
- output->optype = OpndType_CRField;
- output->reg = 6;
- output->regOffset = cond;
-}
-
-static void vector_predicate_1arg(ENode *arg1, short outputReg, Operand *output, Opcode opcode, Intrinsics id) {
- Operand op1;
- short reg;
- Opcode cond;
-
- memclrw(&op1, sizeof(op1));
-
- GEN_NODE_TO_VR(arg1, &op1, arg1->rtype, 0);
-
- reg = ALLOC_VR();
- emitpcode(opcode, reg, op1.reg, op1.reg);
- pcsetrecordbit(pclastblock->lastPCode);
-
- switch (id) {
- case Intrinsic_143:
- cond = ELESS;
- break;
- case Intrinsic_149:
- cond = EGREATEREQU;
- break;
- case Intrinsic_137:
- cond = EEQU;
- break;
- case Intrinsic_155:
- cond = ENOTEQU;
- break;
- default:
- CError_FATAL(4878);
- }
-
- output->optype = OpndType_CRField;
- output->reg = 6;
- output->regOffset = cond;
-}
-
-ENode *Intrinsics_HandleIntrinsicCall(Object *func, ENodeList *args) {
- ENode *callexpr;
- Type *rtype;
- Intrinsics id;
-
- callexpr = NULL;
-
- if (copts.altivec_model) {
- id = func->u.func.u.intrinsicid;
- switch (id) {
- case Intrinsic_060:
- case Intrinsic_061:
- case Intrinsic_062:
- case Intrinsic_063:
- case Intrinsic_072:
- case Intrinsic_073:
- case Intrinsic_079:
- case Intrinsic_080:
- case Intrinsic_081:
- case Intrinsic_082:
- case Intrinsic_086:
- case Intrinsic_093:
- case Intrinsic_098:
- case Intrinsic_100:
- case Intrinsic_114:
- case Intrinsic_115:
- case Intrinsic_116:
- case Intrinsic_202:
- case Intrinsic_203:
- case Intrinsic_224:
- case Intrinsic_225:
- case Intrinsic_226:
- case Intrinsic_227:
- case Intrinsic_228:
- case Intrinsic_229:
- case Intrinsic_230:
- case Intrinsic_231:
- case Intrinsic_240:
- case Intrinsic_252:
- case Intrinsic_259:
- case Intrinsic_263:
- case Intrinsic_280:
- case Intrinsic_281:
- case Intrinsic_282:
- case Intrinsic_283:
- case Intrinsic_284:
- if (Intrinsics_VerifyParameterCount(3, args, func->name)) {
- if ((rtype = Intrinsics_Verify3VectorArgs(id, args, func->name)))
- callexpr = Intrinsics_CreateIntrinsicFunc(func, args, rtype);
- }
- break;
- case Intrinsic_042:
- case Intrinsic_043:
- case Intrinsic_044:
- case Intrinsic_045:
- case Intrinsic_046:
- case Intrinsic_047:
- case Intrinsic_049:
- case Intrinsic_050:
- case Intrinsic_051:
- case Intrinsic_052:
- case Intrinsic_053:
- case Intrinsic_054:
- case Intrinsic_055:
- case Intrinsic_056:
- case Intrinsic_057:
- case Intrinsic_066:
- case Intrinsic_067:
- case Intrinsic_068:
- case Intrinsic_070:
- case Intrinsic_071:
- case Intrinsic_074:
- case Intrinsic_075:
- case Intrinsic_076:
- case Intrinsic_078:
- case Intrinsic_084:
- case Intrinsic_085:
- case Intrinsic_087:
- case Intrinsic_088:
- case Intrinsic_089:
- case Intrinsic_090:
- case Intrinsic_091:
- case Intrinsic_092:
- case Intrinsic_095:
- case Intrinsic_099:
- case Intrinsic_101:
- case Intrinsic_102:
- case Intrinsic_103:
- case Intrinsic_110:
- case Intrinsic_111:
- case Intrinsic_112:
- case Intrinsic_113:
- case Intrinsic_117:
- case Intrinsic_118:
- case Intrinsic_119:
- case Intrinsic_120:
- case Intrinsic_121:
- case Intrinsic_122:
- case Intrinsic_124:
- case Intrinsic_125:
- case Intrinsic_126:
- case Intrinsic_127:
- case Intrinsic_130:
- case Intrinsic_131:
- case Intrinsic_132:
- case Intrinsic_133:
- case Intrinsic_134:
- case Intrinsic_135:
- case Intrinsic_136:
- case Intrinsic_138:
- case Intrinsic_139:
- case Intrinsic_140:
- case Intrinsic_141:
- case Intrinsic_142:
- case Intrinsic_144:
- case Intrinsic_145:
- case Intrinsic_146:
- case Intrinsic_147:
- case Intrinsic_148:
- case Intrinsic_150:
- case Intrinsic_151:
- case Intrinsic_152:
- case Intrinsic_153:
- case Intrinsic_154:
- case Intrinsic_156:
- case Intrinsic_157:
- case Intrinsic_158:
- case Intrinsic_159:
- case Intrinsic_160:
- case Intrinsic_161:
- case Intrinsic_162:
- case Intrinsic_163:
- case Intrinsic_164:
- case Intrinsic_165:
- case Intrinsic_166:
- case Intrinsic_167:
- case Intrinsic_168:
- case Intrinsic_169:
- case Intrinsic_170:
- case Intrinsic_171:
- case Intrinsic_172:
- case Intrinsic_173:
- case Intrinsic_174:
- case Intrinsic_175:
- case Intrinsic_177:
- case Intrinsic_178:
- case Intrinsic_179:
- case Intrinsic_180:
- case Intrinsic_181:
- case Intrinsic_182:
- case Intrinsic_183:
- case Intrinsic_184:
- case Intrinsic_185:
- case Intrinsic_186:
- case Intrinsic_187:
- case Intrinsic_188:
- case Intrinsic_189:
- case Intrinsic_190:
- case Intrinsic_191:
- case Intrinsic_192:
- case Intrinsic_193:
- case Intrinsic_196:
- case Intrinsic_197:
- case Intrinsic_198:
- case Intrinsic_199:
- case Intrinsic_200:
- case Intrinsic_204:
- case Intrinsic_205:
- case Intrinsic_206:
- case Intrinsic_207:
- case Intrinsic_208:
- case Intrinsic_209:
- case Intrinsic_210:
- case Intrinsic_211:
- case Intrinsic_212:
- case Intrinsic_213:
- case Intrinsic_214:
- case Intrinsic_215:
- case Intrinsic_216:
- case Intrinsic_217:
- case Intrinsic_218:
- case Intrinsic_219:
- case Intrinsic_220:
- case Intrinsic_221:
- case Intrinsic_222:
- case Intrinsic_223:
- case Intrinsic_232:
- case Intrinsic_233:
- case Intrinsic_234:
- case Intrinsic_235:
- case Intrinsic_236:
- case Intrinsic_237:
- case Intrinsic_238:
- case Intrinsic_239:
- case Intrinsic_241:
- case Intrinsic_242:
- case Intrinsic_243:
- case Intrinsic_244:
- case Intrinsic_245:
- case Intrinsic_246:
- case Intrinsic_247:
- case Intrinsic_248:
- case Intrinsic_249:
- case Intrinsic_250:
- case Intrinsic_251:
- case Intrinsic_254:
- case Intrinsic_255:
- case Intrinsic_256:
- case Intrinsic_260:
- case Intrinsic_261:
- case Intrinsic_262:
- case Intrinsic_264:
- case Intrinsic_265:
- case Intrinsic_266:
- case Intrinsic_267:
- case Intrinsic_268:
- case Intrinsic_272:
- case Intrinsic_273:
- case Intrinsic_274:
- case Intrinsic_275:
- case Intrinsic_276:
- case Intrinsic_277:
- case Intrinsic_278:
- case Intrinsic_279:
- case Intrinsic_285:
- case Intrinsic_286:
- case Intrinsic_287:
- case Intrinsic_288:
- case Intrinsic_289:
- case Intrinsic_290:
- case Intrinsic_291:
- case Intrinsic_292:
- case Intrinsic_293:
- case Intrinsic_294:
- case Intrinsic_295:
- case Intrinsic_296:
- case Intrinsic_297:
- case Intrinsic_298:
- case Intrinsic_299:
- case Intrinsic_300:
- case Intrinsic_308:
- if (Intrinsics_VerifyParameterCount(2, args, func->name)) {
- if ((rtype = Intrinsics_Verify2VectorArgs(id, args, func->name)))
- callexpr = Intrinsics_CreateIntrinsicFunc(func, args, rtype);
- }
- break;
- case Intrinsic_048:
- case Intrinsic_058:
- case Intrinsic_064:
- case Intrinsic_065:
- case Intrinsic_069:
- case Intrinsic_083:
- case Intrinsic_094:
- case Intrinsic_096:
- case Intrinsic_097:
- case Intrinsic_104:
- case Intrinsic_105:
- case Intrinsic_106:
- case Intrinsic_107:
- case Intrinsic_108:
- case Intrinsic_109:
- case Intrinsic_123:
- case Intrinsic_128:
- case Intrinsic_129:
- case Intrinsic_137:
- case Intrinsic_143:
- case Intrinsic_149:
- case Intrinsic_155:
- case Intrinsic_176:
- case Intrinsic_194:
- case Intrinsic_195:
- case Intrinsic_201:
- case Intrinsic_253:
- case Intrinsic_257:
- case Intrinsic_258:
- case Intrinsic_269:
- case Intrinsic_270:
- case Intrinsic_271:
- case Intrinsic_301:
- case Intrinsic_302:
- case Intrinsic_303:
- case Intrinsic_304:
- case Intrinsic_305:
- case Intrinsic_306:
- case Intrinsic_307:
- if (Intrinsics_VerifyParameterCount(1, args, func->name)) {
- if ((rtype = Intrinsics_Verify1VectorArg(id, args, func->name)))
- callexpr = Intrinsics_CreateIntrinsicFunc(func, args, rtype);
- }
- break;
- case Intrinsic_059:
- case Intrinsic_077:
- if (Intrinsics_VerifyParameterCount(0, args, func->name)) {
- if ((rtype = Intrinsics_VerifyNoVectorArgs(id, func->name)))
- callexpr = Intrinsics_CreateIntrinsicFunc(func, args, rtype);
- }
- break;
- case Intrinsic_309:
- case Intrinsic_310:
- if (Intrinsics_VerifyParameterCount(1, args, func->name)) {
- if ((rtype = Intrinsics_Verify1VectorArg2Ops(id, args, func->name)))
- callexpr = Intrinsics_CreateIntrinsicFunc(func, args, rtype);
- }
- break;
- }
- }
-
- return callexpr;
-}
-
-void call_intrinsic_function(ENode *funccall, short outputReg, Operand *output) {
- ENodeList *args;
- Object *object;
- Intrinsics id;
- Opcode op;
- short reg;
-
- static Opcode opcode[MaxIntrinsics] = {
- /* Intrinsic_000 */ PC_EIEIO,
- /* Intrinsic_001 */ PC_SYNC,
- /* Intrinsic_002 */ PC_ISYNC,
- 0,
- 0,
- /* Intrinsic_005 */ PC_FABS,
- /* Intrinsic_006 */ PC_FNABS,
- 0,
- 0,
- /* Intrinsic_009 */ PC_CNTLZW,
- /* Intrinsic_010 */ PC_LHBRX,
- /* Intrinsic_011 */ PC_LWBRX,
- /* Intrinsic_012 */ PC_STHBRX,
- /* Intrinsic_013 */ PC_STWBRX,
- /* Intrinsic_014 */ PC_DCBF,
- /* Intrinsic_015 */ PC_DCBT,
- /* Intrinsic_016 */ PC_DCBST,
- /* Intrinsic_017 */ PC_DCBTST,
- /* Intrinsic_018 */ PC_DCBZ,
- /* Intrinsic_019 */ PC_MULHW,
- /* Intrinsic_020 */ PC_MULHWU,
- /* Intrinsic_021 */ PC_DIVW,
- /* Intrinsic_022 */ PC_DIVWU,
- /* Intrinsic_023 */ PC_FMADD,
- /* Intrinsic_024 */ PC_FMSUB,
- /* Intrinsic_025 */ PC_FNMADD,
- /* Intrinsic_026 */ PC_FNMSUB,
- /* Intrinsic_027 */ PC_FMADDS,
- /* Intrinsic_028 */ PC_FMSUBS,
- /* Intrinsic_029 */ PC_FNMADDS,
- /* Intrinsic_030 */ PC_FNMSUBS,
- /* Intrinsic_031 */ PC_MFFS,
- /* Intrinsic_032 */ PC_FRES,
- /* Intrinsic_033 */ PC_FRSQRTE,
- /* Intrinsic_004 */ PC_FSEL,
- 0,
- 0,
- /* Intrinsic_037 */ PC_RLWIMI,
- /* Intrinsic_038 */ PC_RLWINM,
- /* Intrinsic_039 */ PC_RLWNM,
- /* Intrinsic_040 */ PC_FABS,
- /* Intrinsic_041 */ PC_FNABS
- };
-
- args = funccall->data.funccall.args;
- object = funccall->data.funccall.funcref->data.objref;
- id = object->u.func.u.intrinsicid;
- cur_intrinsic_object = object;
-
- switch (id) {
- case Intrinsic_000:
- case Intrinsic_001:
- case Intrinsic_002:
- appendpcode(pclastblock, makepcode(opcode[id]));
- output->optype = OpndType_Absolute;
- break;
- case Intrinsic_003:
- case Intrinsic_004:
- abs_intrinsic(args->node, outputReg, output);
- break;
- case Intrinsic_005:
- case Intrinsic_006:
- case Intrinsic_032:
- case Intrinsic_033:
- case Intrinsic_040:
- case Intrinsic_041:
- fp_unary_operator(opcode[id], args->node, outputReg, output);
- break;
- case Intrinsic_007:
- setflm_intrinsic(args->node, outputReg, output, funccall->ignored);
- break;
- case Intrinsic_008:
- alloca_intrinsic(args->node, outputReg, output);
- break;
- case Intrinsic_009:
- unary_operator(PC_CNTLZW, args->node, outputReg, output);
- break;
- case Intrinsic_010:
- case Intrinsic_011:
- load_bytereversed_intrinsic(opcode[id], args->node, args->next->node, outputReg, output);
- break;
- case Intrinsic_012:
- case Intrinsic_013:
- store_bytereversed_intrinsic(opcode[id], args->node, args->next->node, args->next->next->node);
- output->optype = OpndType_Absolute;
- break;
- case Intrinsic_014:
- case Intrinsic_015:
- case Intrinsic_016:
- case Intrinsic_017:
- case Intrinsic_018:
- data_cache_block_intrinsic(opcode[id], args->node, args->next->node);
- output->optype = OpndType_Absolute;
- break;
- case Intrinsic_019:
- case Intrinsic_020:
- case Intrinsic_021:
- case Intrinsic_022:
- binary_operator(opcode[id], args->node, args->next->node, outputReg, output);
- break;
- case Intrinsic_023:
- case Intrinsic_024:
- case Intrinsic_025:
- case Intrinsic_026:
- case Intrinsic_027:
- case Intrinsic_028:
- case Intrinsic_029:
- case Intrinsic_030:
- case Intrinsic_034:
- fp_multiply_add(opcode[id],
- args->node, args->next->node, args->next->next->node,
- outputReg, output);
- break;
- case Intrinsic_031:
- reg = outputReg ? outputReg : ALLOC_FPR();
- emitpcode(PC_MFFS, output->reg = reg);
- output->optype = OpndType_FPR;
- break;
- case Intrinsic_035:
- call_function(funccall, output);
- break;
- case Intrinsic_036:
- if (ENODE_IS(args->next->next->node, EINTCONST))
- memcpy_intrinsic(
- args->node, args->next->node, args->next->next->node->data.intval.lo,
- funccall->ignored, output);
- else
- call_function(funccall, output);
- break;
- case Intrinsic_037:
- rlwimi_intrinsic(
- args->node,
- args->next->node,
- args->next->next->node,
- args->next->next->next->node,
- args->next->next->next->next->node,
- outputReg, output);
- break;
- case Intrinsic_038:
- rlwinm_intrinsic(
- args->node,
- args->next->node,
- args->next->next->node,
- args->next->next->next->node,
- outputReg, output);
- break;
- case Intrinsic_039:
- rlwnm_intrinsic(
- args->node,
- args->next->node,
- args->next->next->node,
- args->next->next->next->node,
- outputReg, output);
- break;
- case Intrinsic_072:
- case Intrinsic_073:
- case Intrinsic_079:
- case Intrinsic_080:
- case Intrinsic_081:
- case Intrinsic_082:
- case Intrinsic_086:
- case Intrinsic_093:
- case Intrinsic_098:
- case Intrinsic_202:
- case Intrinsic_203:
- case Intrinsic_224:
- case Intrinsic_225:
- case Intrinsic_226:
- case Intrinsic_227:
- case Intrinsic_228:
- case Intrinsic_229:
- case Intrinsic_230:
- case Intrinsic_231:
- case Intrinsic_240:
- case Intrinsic_252:
- case Intrinsic_259:
- op = Intrinsics_FindOpcode3Args(id, funccall, args->node, args->next->node, args->next->next->node);
- vector_intrinsic_3args(args->node, args->next->node, args->next->next->node, outputReg, output, op);
- break;
- case Intrinsic_100:
- case Intrinsic_263:
- op = Intrinsics_FindOpcode3Args(id, funccall, args->node, args->next->node, args->next->next->node);
- vector_intrinsic_sld(args->node, args->next->node, args->next->next->node, outputReg, output, op);
- break;
- case Intrinsic_042:
- case Intrinsic_043:
- case Intrinsic_044:
- case Intrinsic_045:
- case Intrinsic_046:
- case Intrinsic_047:
- case Intrinsic_049:
- case Intrinsic_050:
- case Intrinsic_051:
- case Intrinsic_053:
- case Intrinsic_074:
- case Intrinsic_075:
- case Intrinsic_076:
- case Intrinsic_078:
- case Intrinsic_084:
- case Intrinsic_085:
- case Intrinsic_087:
- case Intrinsic_088:
- case Intrinsic_089:
- case Intrinsic_090:
- case Intrinsic_091:
- case Intrinsic_092:
- case Intrinsic_095:
- case Intrinsic_099:
- case Intrinsic_101:
- case Intrinsic_102:
- case Intrinsic_110:
- case Intrinsic_111:
- case Intrinsic_112:
- case Intrinsic_113:
- case Intrinsic_117:
- case Intrinsic_118:
- case Intrinsic_119:
- case Intrinsic_120:
- case Intrinsic_121:
- case Intrinsic_122:
- case Intrinsic_124:
- case Intrinsic_125:
- case Intrinsic_126:
- case Intrinsic_127:
- case Intrinsic_130:
- case Intrinsic_157:
- case Intrinsic_158:
- case Intrinsic_159:
- case Intrinsic_160:
- case Intrinsic_161:
- case Intrinsic_162:
- case Intrinsic_163:
- case Intrinsic_164:
- case Intrinsic_165:
- case Intrinsic_166:
- case Intrinsic_167:
- case Intrinsic_168:
- case Intrinsic_169:
- case Intrinsic_170:
- case Intrinsic_171:
- case Intrinsic_172:
- case Intrinsic_173:
- case Intrinsic_174:
- case Intrinsic_175:
- case Intrinsic_177:
- case Intrinsic_178:
- case Intrinsic_179:
- case Intrinsic_180:
- case Intrinsic_181:
- case Intrinsic_182:
- case Intrinsic_183:
- case Intrinsic_184:
- case Intrinsic_185:
- case Intrinsic_186:
- case Intrinsic_187:
- case Intrinsic_188:
- case Intrinsic_189:
- case Intrinsic_204:
- case Intrinsic_205:
- case Intrinsic_206:
- case Intrinsic_207:
- case Intrinsic_208:
- case Intrinsic_209:
- case Intrinsic_210:
- case Intrinsic_211:
- case Intrinsic_212:
- case Intrinsic_213:
- case Intrinsic_214:
- case Intrinsic_215:
- case Intrinsic_216:
- case Intrinsic_217:
- case Intrinsic_218:
- case Intrinsic_219:
- case Intrinsic_220:
- case Intrinsic_221:
- case Intrinsic_222:
- case Intrinsic_223:
- case Intrinsic_232:
- case Intrinsic_233:
- case Intrinsic_234:
- case Intrinsic_235:
- case Intrinsic_236:
- case Intrinsic_237:
- case Intrinsic_238:
- case Intrinsic_239:
- case Intrinsic_241:
- case Intrinsic_242:
- case Intrinsic_243:
- case Intrinsic_244:
- case Intrinsic_245:
- case Intrinsic_246:
- case Intrinsic_247:
- case Intrinsic_248:
- case Intrinsic_249:
- case Intrinsic_250:
- case Intrinsic_251:
- case Intrinsic_254:
- case Intrinsic_255:
- case Intrinsic_256:
- case Intrinsic_260:
- case Intrinsic_261:
- case Intrinsic_262:
- case Intrinsic_264:
- case Intrinsic_265:
- case Intrinsic_272:
- case Intrinsic_273:
- case Intrinsic_274:
- case Intrinsic_275:
- case Intrinsic_276:
- case Intrinsic_277:
- case Intrinsic_278:
- case Intrinsic_279:
- case Intrinsic_285:
- case Intrinsic_286:
- case Intrinsic_287:
- case Intrinsic_288:
- case Intrinsic_289:
- case Intrinsic_290:
- case Intrinsic_291:
- case Intrinsic_292:
- case Intrinsic_293:
- case Intrinsic_294:
- case Intrinsic_295:
- case Intrinsic_296:
- case Intrinsic_297:
- case Intrinsic_298:
- case Intrinsic_299:
- case Intrinsic_300:
- case Intrinsic_308:
- op = Intrinsics_FindOpcode2Args(id, funccall, args->node, args->next->node);
- vector_intrinsic_2args(args->node, args->next->node, outputReg, output, op);
- break;
- case Intrinsic_048:
- case Intrinsic_064:
- case Intrinsic_065:
- case Intrinsic_069:
- case Intrinsic_094:
- case Intrinsic_096:
- case Intrinsic_097:
- case Intrinsic_123:
- case Intrinsic_128:
- case Intrinsic_129:
- case Intrinsic_176:
- case Intrinsic_194:
- case Intrinsic_195:
- case Intrinsic_201:
- case Intrinsic_253:
- case Intrinsic_257:
- case Intrinsic_258:
- case Intrinsic_301:
- case Intrinsic_302:
- case Intrinsic_303:
- case Intrinsic_304:
- case Intrinsic_305:
- case Intrinsic_306:
- case Intrinsic_307:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_intrinsic_1arg(args->node, outputReg, output, op);
- break;
- case Intrinsic_055:
- case Intrinsic_056:
- case Intrinsic_057:
- case Intrinsic_103:
- case Intrinsic_190:
- case Intrinsic_191:
- case Intrinsic_192:
- case Intrinsic_193:
- case Intrinsic_266:
- case Intrinsic_267:
- case Intrinsic_268:
- op = Intrinsics_FindOpcode2Args(id, funccall, args->node, args->next->node);
- vector_intrinsic_2args1const(args->node, args->next->node, outputReg, output, op);
- break;
- case Intrinsic_104:
- case Intrinsic_105:
- case Intrinsic_106:
- case Intrinsic_269:
- case Intrinsic_270:
- case Intrinsic_271:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_intrinsic_splats(args->node, outputReg, output, op);
- break;
- case Intrinsic_107:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_intrinsic_splatu8(args->node, outputReg, output, op);
- break;
- case Intrinsic_108:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_intrinsic_splatu16(args->node, outputReg, output, op);
- break;
- case Intrinsic_109:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_intrinsic_splatu32(args->node, outputReg, output, op);
- break;
- case Intrinsic_083:
- vector_intrinsic_mtvscr(args->node, output, PC_MTVSCR);
- break;
- case Intrinsic_077:
- op = Intrinsics_FindOpcodeNoArgs(id, funccall);
- vector_intrinsic_mfvscr(outputReg, op, output);
- break;
- case Intrinsic_058:
- vector_intrinsic_dss(args->node);
- break;
- case Intrinsic_059:
- op = Intrinsics_FindOpcodeNoArgs(id, funccall);
- vector_intrinsic_no_args(op);
- break;
- case Intrinsic_060:
- case Intrinsic_061:
- case Intrinsic_062:
- case Intrinsic_063:
- switch (id) {
- case Intrinsic_060:
- op = PC_DST;
- break;
- case Intrinsic_061:
- op = PC_DSTST;
- break;
- case Intrinsic_062:
- op = PC_DSTSTT;
- break;
- case Intrinsic_063:
- op = PC_DSTT;
- break;
- }
- vector_intrinsic_datastream(args->node, args->next->node, args->next->next->node, op);
- break;
- case Intrinsic_066:
- case Intrinsic_067:
- case Intrinsic_068:
- case Intrinsic_070:
- case Intrinsic_071:
- case Intrinsic_196:
- case Intrinsic_197:
- case Intrinsic_198:
- case Intrinsic_199:
- case Intrinsic_200:
- op = Intrinsics_FindOpcode2Args(id, funccall, args->node, args->next->node);
- vector_intrinsic_load(args->node, args->next->node, outputReg, output, op);
- break;
- case Intrinsic_114:
- case Intrinsic_115:
- case Intrinsic_116:
- case Intrinsic_280:
- case Intrinsic_281:
- case Intrinsic_282:
- case Intrinsic_283:
- case Intrinsic_284:
- op = Intrinsics_FindOpcode3Args(id, funccall, args->node, args->next->node, args->next->next->node);
- vector_intrinsic_store(args->node, args->next->node, args->next->next->node, outputReg, output, op);
- break;
- case Intrinsic_131:
- case Intrinsic_132:
- case Intrinsic_133:
- case Intrinsic_134:
- case Intrinsic_135:
- case Intrinsic_136:
- case Intrinsic_138:
- case Intrinsic_139:
- case Intrinsic_140:
- case Intrinsic_141:
- case Intrinsic_142:
- case Intrinsic_144:
- case Intrinsic_145:
- case Intrinsic_146:
- case Intrinsic_147:
- case Intrinsic_148:
- case Intrinsic_150:
- case Intrinsic_151:
- case Intrinsic_152:
- case Intrinsic_153:
- case Intrinsic_154:
- case Intrinsic_156:
- op = Intrinsics_FindOpcode2Args(id, funccall, args->node, args->next->node);
- vector_predicate_2args(args->node, args->next->node, outputReg, output, op, id);
- break;
- case Intrinsic_137:
- case Intrinsic_143:
- case Intrinsic_149:
- case Intrinsic_155:
- op = Intrinsics_FindOpcode1Arg(id, funccall, args->node);
- vector_predicate_1arg(args->node, outputReg, output, op, id);
- break;
- case Intrinsic_309:
- vector_intrinsic_abs(id, funccall, args->node, outputReg, output);
- break;
- case Intrinsic_310:
- vector_intrinsic_abss(id, funccall, args->node, outputReg, output);
- break;
- case Intrinsic_052:
- case Intrinsic_054:
- op = Intrinsics_FindOpcode2Args(id, funccall, args->node, args->next->node);
- vector_intrinsic_2args(args->node, args->next->node, outputReg, output, op);
- break;
- default:
- CError_FATAL(6152);
- }
-}
-
-void Intrinsics_SetupRuntimeObjects(void) {
- static TypePointer char_ptr = {TYPEPOINTER, 4, TYPE(&stchar), 0};
- Boolean savecpp;
- int i;
-
- savecpp = copts.cplusplus;
- copts.cplusplus = 0;
-
- for (i = 0; i < MaxIntrinsics; i++)
- intrinsics[i] = NULL;
-
- intrinsics[Intrinsic_000] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__eieio"), 0, 0);
- intrinsics[Intrinsic_001] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__sync"), 0, 0);
- intrinsics[Intrinsic_002] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__isync"), 0, 0);
- intrinsics[Intrinsic_003] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__abs"), 0, 1, &stsignedint);
- intrinsics[Intrinsic_004] = CParser_NewRTFunc(TYPE(&stsignedlong), GetHashNameNodeExport("__labs"), 0, 1, &stsignedlong);
- intrinsics[Intrinsic_005] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fabs"), 0, 1, &stdouble);
- intrinsics[Intrinsic_006] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fnabs"), 0, 1, &stdouble);
- intrinsics[Intrinsic_007] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__setflm"), 0, 1, &stdouble);
- intrinsics[Intrinsic_033] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__frsqrte"), 0, 1, &stdouble);
- intrinsics[Intrinsic_008] = CParser_NewRTFunc(TYPE(&void_ptr), GetHashNameNodeExport("__alloca"), 0, 1, &stunsignedint);
- intrinsics[Intrinsic_009] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__cntlzw"), 0, 1, &stunsignedint);
- intrinsics[Intrinsic_010] = CParser_NewRTFunc(TYPE(&stunsignedint), GetHashNameNodeExport("__lhbrx"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_011] = CParser_NewRTFunc(TYPE(&stunsignedint), GetHashNameNodeExport("__lwbrx"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_012] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__sthbrx"), 0, 3, &stunsignedshort, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_013] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__stwbrx"), 0, 3, &stunsignedint, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_014] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__dcbf"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_015] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__dcbt"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_016] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__dcbst"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_017] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__dcbtst"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_018] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("__dcbz"), 0, 2, &void_ptr, &stsignedint);
- intrinsics[Intrinsic_019] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__mulhw"), 0, 2, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_020] = CParser_NewRTFunc(TYPE(&stunsignedint), GetHashNameNodeExport("__mulhwu"), 0, 2, &stunsignedint, &stunsignedint);
- intrinsics[Intrinsic_021] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__divw"), 0, 2, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_022] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__divwu"), 0, 2, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_023] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fmadd"), 0, 3, &stdouble, &stdouble, &stdouble);
- intrinsics[Intrinsic_024] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fmsub"), 0, 3, &stdouble, &stdouble, &stdouble);
- intrinsics[Intrinsic_025] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fnmadd"), 0, 3, &stdouble, &stdouble, &stdouble);
- intrinsics[Intrinsic_026] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fnmsub"), 0, 3, &stdouble, &stdouble, &stdouble);
- intrinsics[Intrinsic_034] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__fsel"), 0, 3, &stdouble, &stdouble, &stdouble);
- intrinsics[Intrinsic_027] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fmadds"), 0, 3, &stfloat, &stfloat, &stfloat);
- intrinsics[Intrinsic_028] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fmsubs"), 0, 3, &stfloat, &stfloat, &stfloat);
- intrinsics[Intrinsic_029] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fnmadds"), 0, 3, &stfloat, &stfloat, &stfloat);
- intrinsics[Intrinsic_030] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fnmsubs"), 0, 3, &stfloat, &stfloat, &stfloat);
- intrinsics[Intrinsic_031] = CParser_NewRTFunc(TYPE(&stdouble), GetHashNameNodeExport("__mffs"), 0, 0);
- intrinsics[Intrinsic_032] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fres"), 0, 1, &stfloat);
- intrinsics[Intrinsic_040] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fabsf"), 0, 1, &stfloat);
- intrinsics[Intrinsic_041] = CParser_NewRTFunc(TYPE(&stfloat), GetHashNameNodeExport("__fnabsf"), 0, 1, &stfloat);
- intrinsics[Intrinsic_035] = CParser_NewRTFunc(TYPE(&char_ptr), GetHashNameNodeExport("__strcpy"), 0, 2, &char_ptr, &char_ptr);
- TYPE_FUNC(intrinsics[Intrinsic_035]->type)->args->next->qual |= Q_CONST;
- intrinsics[Intrinsic_036] = CParser_NewRTFunc(TYPE(&void_ptr), GetHashNameNodeExport("__memcpy"), 0, 3, &void_ptr, &void_ptr, &stunsignedlong);
- __memcpy_object = intrinsics[Intrinsic_036];
- TYPE_FUNC(intrinsics[Intrinsic_036]->type)->args->next->qual |= Q_CONST;
- intrinsics[Intrinsic_037] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__rlwimi"), 0, 5, &stsignedint, &stsignedint, &stsignedint, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_038] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__rlwinm"), 0, 4, &stsignedint, &stsignedint, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_039] = CParser_NewRTFunc(TYPE(&stsignedint), GetHashNameNodeExport("__rlwnm"), 0, 4, &stsignedint, &stsignedint, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_042] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_add"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_043] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_addc"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_044] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_adds"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_045] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_and"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_046] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_andc"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_047] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_avg"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_048] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ceil"), 0, 1, &stvector);
- intrinsics[Intrinsic_049] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmpb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_050] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmpeq"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_051] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmpge"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_052] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmple"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_053] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmpgt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_054] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cmplt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_055] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ctf"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_056] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_cts"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_057] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ctu"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_058] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dss"), 0, 1, &stsignedint);
- intrinsics[Intrinsic_059] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dssall"), 0, 0);
- intrinsics[Intrinsic_060] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dst"), 0, 3, &stvector, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_061] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dstst"), 0, 3, &stvector, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_062] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dststt"), 0, 3, &stvector, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_063] = CParser_NewRTFunc(&stvoid, GetHashNameNodeExport("vec_dstt"), 0, 3, &stvector, &stsignedint, &stsignedint);
- intrinsics[Intrinsic_064] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_expte"), 0, 1, &stvector);
- intrinsics[Intrinsic_065] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_floor"), 0, 1, &stvector);
- intrinsics[Intrinsic_066] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ld"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_067] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lde"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_068] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ldl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_069] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_loge"), 0, 1, &stvector);
- intrinsics[Intrinsic_070] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvsl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_071] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvsr"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_072] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_madd"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_073] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_madds"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_074] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_max"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_075] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mergeh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_076] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mergel"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_077] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mfvscr"), 0, 0);
- intrinsics[Intrinsic_078] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_min"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_079] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mladd"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_080] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mradds"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_081] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_msum"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_082] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_msums"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_083] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mtvscr"), 0, 1, &stvector);
- intrinsics[Intrinsic_084] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mule"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_085] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_mulo"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_086] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_nmsub"), 0, 2, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_087] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_nor"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_088] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_or"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_089] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_pack"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_090] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_packpx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_091] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_packs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_092] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_packsu"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_093] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_perm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_094] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_re"), 0, 1, &stvector);
- intrinsics[Intrinsic_095] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_rl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_096] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_round"), 0, 1, &stvector);
- intrinsics[Intrinsic_097] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_rsqrte"), 0, 1, &stvector);
- intrinsics[Intrinsic_098] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sel"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_099] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_100] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sld"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_101] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sll"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_102] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_slo"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_103] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_104] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_s8"), 0, 1, &stvector);
- intrinsics[Intrinsic_105] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_s16"), 0, 1, &stvector);
- intrinsics[Intrinsic_106] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_s32"), 0, 1, &stvector);
- intrinsics[Intrinsic_107] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_u8"), 0, 1, &stvector);
- intrinsics[Intrinsic_108] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_u16"), 0, 1, &stvector);
- intrinsics[Intrinsic_109] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_splat_u32"), 0, 1, &stvector);
- intrinsics[Intrinsic_110] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sr"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_111] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sra"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_112] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_srl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_113] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sro"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_114] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_st"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_115] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_ste"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_116] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stl"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_117] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_118] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_subc"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_119] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_subs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_120] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sum4s"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_121] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sum2s"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_122] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_sums"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_123] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_trunc"), 0, 1, &stvector);
- intrinsics[Intrinsic_124] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpack2sh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_125] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpack2sl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_126] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpack2uh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_127] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpack2ul"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_128] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpackh"), 0, 1, &stvector);
- intrinsics[Intrinsic_129] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_unpackl"), 0, 1, &stvector);
- intrinsics[Intrinsic_130] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_xor"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_131] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_eq"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_132] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_ge"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_133] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_gt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_134] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_in"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_135] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_le"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_136] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_lt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_137] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_nan"), 0, 1, &stvector);
- intrinsics[Intrinsic_138] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_ne"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_139] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_nge"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_140] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_ngt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_141] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_nle"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_142] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_nlt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_143] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_all_numeric"), 0, 1, &stvector);
- intrinsics[Intrinsic_144] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_eq"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_145] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_ge"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_146] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_gt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_147] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_le"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_148] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_lt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_149] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_nan"), 0, 1, &stvector);
- intrinsics[Intrinsic_150] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_ne"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_151] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_nge"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_152] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_ngt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_153] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_nle"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_154] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_nlt"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_155] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_numeric"), 0, 1, &stvector);
- intrinsics[Intrinsic_156] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_any_out"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_157] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddubm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_158] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vadduhm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_159] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vadduwm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_160] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_161] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddcuw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_162] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddubs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_163] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddsbs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_164] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vadduhs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_165] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddshs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_166] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vadduws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_167] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vaddsws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_168] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vand"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_169] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vandc"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_170] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavgub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_171] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavgsb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_172] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavguh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_173] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavgsh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_174] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavguw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_175] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vavgsw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_176] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrfip"), 0, 1, &stvector);
- intrinsics[Intrinsic_177] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpbfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_178] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpequb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_179] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpequh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_180] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpequw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_181] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpeqfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_182] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgefp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_183] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_184] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtsb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_185] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtuh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_186] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtsh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_187] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtuw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_188] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtsw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_189] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcmpgtfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_190] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcfux"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_191] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vcfsx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_192] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vctsxs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_193] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vctuxs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_194] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vexptefp"), 0, 1, &stvector);
- intrinsics[Intrinsic_195] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrfim"), 0, 1, &stvector);
- intrinsics[Intrinsic_196] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_197] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvebx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_198] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvehx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_199] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvewx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_200] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_lvxl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_201] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vlogefp"), 0, 1, &stvector);
- intrinsics[Intrinsic_202] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaddfp"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_203] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmhaddshs"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_204] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_205] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxsb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_206] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxuh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_207] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxsh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_208] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxuw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_209] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxsw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_210] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmaxfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_211] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrghb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_212] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrghh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_213] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrghw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_214] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrglb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_215] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrglh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_216] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmrglw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_217] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_218] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminsb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_219] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminuh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_220] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminsh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_221] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminuw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_222] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminsw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_223] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vminfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_224] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmladduhm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_225] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmhraddshs"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_226] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsumubm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_227] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsumuhm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_228] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsummbm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_229] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsumshm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_230] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsumuhs"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_231] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmsumshs"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_232] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmuleub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_233] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmulesb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_234] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmuleuh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_235] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmulesh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_236] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmuloub"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_237] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmulosb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_238] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmulouh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_239] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vmulosh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_240] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vnmsubfp"), 0, 2, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_241] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vnor"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_242] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vor"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_243] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkuhum"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_244] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkuwum"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_245] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkpx"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_246] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkuhus"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_247] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkshss"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_248] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkuwus"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_249] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkswss"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_250] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkshus"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_251] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vpkswus"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_252] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vperm"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_253] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrefp"), 0, 1, &stvector);
- intrinsics[Intrinsic_254] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrlb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_255] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrlh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_256] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrlw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_257] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrfin"), 0, 1, &stvector);
- intrinsics[Intrinsic_258] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrsqrtefp"), 0, 1, &stvector);
- intrinsics[Intrinsic_259] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsel"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_260] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vslb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_261] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vslh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_262] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vslw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_263] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsldoi"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_264] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsl"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_265] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vslo"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_266] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vspltb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_267] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsplth"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_268] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vspltw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_269] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vspltisb"), 0, 1, &stvector);
- intrinsics[Intrinsic_270] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vspltish"), 0, 1, &stvector);
- intrinsics[Intrinsic_271] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vspltisw"), 0, 1, &stvector);
- intrinsics[Intrinsic_272] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsrb"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_273] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsrh"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_274] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsrw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_275] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsrab"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_276] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsrah"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_277] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsraw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_278] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsr"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_279] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsro"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_280] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stvx"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_281] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stvebx"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_282] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stvehx"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_283] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stvewx"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_284] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_stvxl"), 0, 3, &stvector, &stvector, &stvector);
- intrinsics[Intrinsic_285] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsububm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_286] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubuhm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_287] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubuwm"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_288] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubfp"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_289] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubcuw"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_290] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsububs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_291] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubsbs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_292] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubuhs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_293] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubshs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_294] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubuws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_295] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsubsws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_296] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsum4ubs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_297] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsum4sbs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_298] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsum4shs"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_299] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsum2sws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_300] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vsumsws"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_301] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vrfiz"), 0, 1, &stvector);
- intrinsics[Intrinsic_302] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupkhsb"), 0, 1, &stvector);
- intrinsics[Intrinsic_303] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupklsb"), 0, 1, &stvector);
- intrinsics[Intrinsic_304] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupkhpx"), 0, 1, &stvector);
- intrinsics[Intrinsic_305] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupklpx"), 0, 1, &stvector);
- intrinsics[Intrinsic_306] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupkhsh"), 0, 1, &stvector);
- intrinsics[Intrinsic_307] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vupklsh"), 0, 1, &stvector);
- intrinsics[Intrinsic_308] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_vxor"), 0, 2, &stvector, &stvector);
- intrinsics[Intrinsic_309] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_abs"), 0, 1, &stvector);
- intrinsics[Intrinsic_310] = CParser_NewRTFunc(TYPE(&stvector), GetHashNameNodeExport("vec_abss"), 0, 1, &stvector);
-
- for (i = 0; i < MaxIntrinsics; i++) {
- CError_ASSERT(6600, intrinsics[i]);
- intrinsics[i]->u.func.u.intrinsicid = i;
- TYPE_FUNC(intrinsics[i]->type)->flags |= FUNC_INTRINSIC;
- CScope_AddGlobalObject(intrinsics[i]);
- }
-
- copts.cplusplus = savecpp;
-}
-
-static Object *CheckRuntimeObject(char *name) {
- NameSpaceName *nsname = CScope_FindNameSpaceName(cscope_root, GetHashNameNodeExport(name));
-
- if (!nsname)
- return NULL;
-
- if (nsname->first.object && nsname->first.next == NULL)
- return OBJECT(nsname->first.object);
-
- return NULL;
-}
-
-Boolean Intrinsics_ReInitRuntimeObjects(Boolean flag) {
- if (flag) {
- if (!(intrinsics[Intrinsic_000] = CheckRuntimeObject("__eieio"))) return 0;
- if (!(intrinsics[Intrinsic_001] = CheckRuntimeObject("__sync"))) return 0;
- if (!(intrinsics[Intrinsic_002] = CheckRuntimeObject("__isync"))) return 0;
- if (!(intrinsics[Intrinsic_003] = CheckRuntimeObject("__abs"))) return 0;
- if (!(intrinsics[Intrinsic_004] = CheckRuntimeObject("__labs"))) return 0;
- if (!(intrinsics[Intrinsic_005] = CheckRuntimeObject("__fabs"))) return 0;
- if (!(intrinsics[Intrinsic_006] = CheckRuntimeObject("__fnabs"))) return 0;
- if (!(intrinsics[Intrinsic_007] = CheckRuntimeObject("__setflm"))) return 0;
- if (!(intrinsics[Intrinsic_033] = CheckRuntimeObject("__frsqrte"))) return 0;
- if (!(intrinsics[Intrinsic_008] = CheckRuntimeObject("__alloca"))) return 0;
- if (!(intrinsics[Intrinsic_009] = CheckRuntimeObject("__cntlzw"))) return 0;
- if (!(intrinsics[Intrinsic_010] = CheckRuntimeObject("__lhbrx"))) return 0;
- if (!(intrinsics[Intrinsic_011] = CheckRuntimeObject("__lwbrx"))) return 0;
- if (!(intrinsics[Intrinsic_012] = CheckRuntimeObject("__sthbrx"))) return 0;
- if (!(intrinsics[Intrinsic_013] = CheckRuntimeObject("__stwbrx"))) return 0;
- if (!(intrinsics[Intrinsic_014] = CheckRuntimeObject("__dcbf"))) return 0;
- if (!(intrinsics[Intrinsic_015] = CheckRuntimeObject("__dcbt"))) return 0;
- if (!(intrinsics[Intrinsic_016] = CheckRuntimeObject("__dcbst"))) return 0;
- if (!(intrinsics[Intrinsic_017] = CheckRuntimeObject("__dcbtst"))) return 0;
- if (!(intrinsics[Intrinsic_018] = CheckRuntimeObject("__dcbz"))) return 0;
- if (!(intrinsics[Intrinsic_019] = CheckRuntimeObject("__mulhw"))) return 0;
- if (!(intrinsics[Intrinsic_020] = CheckRuntimeObject("__mulhwu"))) return 0;
- if (!(intrinsics[Intrinsic_021] = CheckRuntimeObject("__divw"))) return 0;
- if (!(intrinsics[Intrinsic_022] = CheckRuntimeObject("__divwu"))) return 0;
- if (!(intrinsics[Intrinsic_023] = CheckRuntimeObject("__fmadd"))) return 0;
- if (!(intrinsics[Intrinsic_024] = CheckRuntimeObject("__fmsub"))) return 0;
- if (!(intrinsics[Intrinsic_025] = CheckRuntimeObject("__fnmadd"))) return 0;
- if (!(intrinsics[Intrinsic_026] = CheckRuntimeObject("__fnmsub"))) return 0;
- if (!(intrinsics[Intrinsic_034] = CheckRuntimeObject("__fsel"))) return 0;
- if (!(intrinsics[Intrinsic_027] = CheckRuntimeObject("__fmadds"))) return 0;
- if (!(intrinsics[Intrinsic_028] = CheckRuntimeObject("__fmsubs"))) return 0;
- if (!(intrinsics[Intrinsic_029] = CheckRuntimeObject("__fnmadds"))) return 0;
- if (!(intrinsics[Intrinsic_030] = CheckRuntimeObject("__fnmsubs"))) return 0;
- if (!(intrinsics[Intrinsic_031] = CheckRuntimeObject("__mffs"))) return 0;
- if (!(intrinsics[Intrinsic_032] = CheckRuntimeObject("__fres"))) return 0;
- if (!(intrinsics[Intrinsic_040] = CheckRuntimeObject("__fabsf"))) return 0;
- if (!(intrinsics[Intrinsic_041] = CheckRuntimeObject("__fnabsf"))) return 0;
- if (!(intrinsics[Intrinsic_035] = CheckRuntimeObject("__strcpy"))) return 0;
- if (!(intrinsics[Intrinsic_037] = CheckRuntimeObject("__rlwimi"))) return 0;
- if (!(intrinsics[Intrinsic_038] = CheckRuntimeObject("__rlwinm"))) return 0;
- if (!(intrinsics[Intrinsic_039] = CheckRuntimeObject("__rlwnm"))) return 0;
- if (!(intrinsics[Intrinsic_042] = CheckRuntimeObject("vec_add"))) return 0;
- if (!(intrinsics[Intrinsic_043] = CheckRuntimeObject("vec_addc"))) return 0;
- if (!(intrinsics[Intrinsic_044] = CheckRuntimeObject("vec_adds"))) return 0;
- if (!(intrinsics[Intrinsic_045] = CheckRuntimeObject("vec_and"))) return 0;
- if (!(intrinsics[Intrinsic_046] = CheckRuntimeObject("vec_andc"))) return 0;
- if (!(intrinsics[Intrinsic_047] = CheckRuntimeObject("vec_avg"))) return 0;
- if (!(intrinsics[Intrinsic_048] = CheckRuntimeObject("vec_ceil"))) return 0;
- if (!(intrinsics[Intrinsic_049] = CheckRuntimeObject("vec_cmpb"))) return 0;
- if (!(intrinsics[Intrinsic_050] = CheckRuntimeObject("vec_cmpeq"))) return 0;
- if (!(intrinsics[Intrinsic_051] = CheckRuntimeObject("vec_cmpge"))) return 0;
- if (!(intrinsics[Intrinsic_052] = CheckRuntimeObject("vec_cmple"))) return 0;
- if (!(intrinsics[Intrinsic_053] = CheckRuntimeObject("vec_cmpgt"))) return 0;
- if (!(intrinsics[Intrinsic_054] = CheckRuntimeObject("vec_cmplt"))) return 0;
- if (!(intrinsics[Intrinsic_055] = CheckRuntimeObject("vec_ctf"))) return 0;
- if (!(intrinsics[Intrinsic_056] = CheckRuntimeObject("vec_cts"))) return 0;
- if (!(intrinsics[Intrinsic_057] = CheckRuntimeObject("vec_ctu"))) return 0;
- if (!(intrinsics[Intrinsic_064] = CheckRuntimeObject("vec_expte"))) return 0;
- if (!(intrinsics[Intrinsic_065] = CheckRuntimeObject("vec_floor"))) return 0;
- if (!(intrinsics[Intrinsic_066] = CheckRuntimeObject("vec_ld"))) return 0;
- if (!(intrinsics[Intrinsic_067] = CheckRuntimeObject("vec_lde"))) return 0;
- if (!(intrinsics[Intrinsic_068] = CheckRuntimeObject("vec_ldl"))) return 0;
- if (!(intrinsics[Intrinsic_069] = CheckRuntimeObject("vec_loge"))) return 0;
- if (!(intrinsics[Intrinsic_070] = CheckRuntimeObject("vec_lvsl"))) return 0;
- if (!(intrinsics[Intrinsic_071] = CheckRuntimeObject("vec_lvsr"))) return 0;
- if (!(intrinsics[Intrinsic_072] = CheckRuntimeObject("vec_madd"))) return 0;
- if (!(intrinsics[Intrinsic_073] = CheckRuntimeObject("vec_madds"))) return 0;
- if (!(intrinsics[Intrinsic_074] = CheckRuntimeObject("vec_max"))) return 0;
- if (!(intrinsics[Intrinsic_075] = CheckRuntimeObject("vec_mergeh"))) return 0;
- if (!(intrinsics[Intrinsic_076] = CheckRuntimeObject("vec_mergel"))) return 0;
- if (!(intrinsics[Intrinsic_077] = CheckRuntimeObject("vec_mfvscr"))) return 0;
- if (!(intrinsics[Intrinsic_078] = CheckRuntimeObject("vec_min"))) return 0;
- if (!(intrinsics[Intrinsic_079] = CheckRuntimeObject("vec_mladd"))) return 0;
- if (!(intrinsics[Intrinsic_080] = CheckRuntimeObject("vec_mradds"))) return 0;
- if (!(intrinsics[Intrinsic_081] = CheckRuntimeObject("vec_msum"))) return 0;
- if (!(intrinsics[Intrinsic_082] = CheckRuntimeObject("vec_msums"))) return 0;
- if (!(intrinsics[Intrinsic_083] = CheckRuntimeObject("vec_mtvscr"))) return 0;
- if (!(intrinsics[Intrinsic_084] = CheckRuntimeObject("vec_mule"))) return 0;
- if (!(intrinsics[Intrinsic_085] = CheckRuntimeObject("vec_mulo"))) return 0;
- if (!(intrinsics[Intrinsic_086] = CheckRuntimeObject("vec_nmsub"))) return 0;
- if (!(intrinsics[Intrinsic_087] = CheckRuntimeObject("vec_nor"))) return 0;
- if (!(intrinsics[Intrinsic_088] = CheckRuntimeObject("vec_or"))) return 0;
- if (!(intrinsics[Intrinsic_089] = CheckRuntimeObject("vec_pack"))) return 0;
- if (!(intrinsics[Intrinsic_090] = CheckRuntimeObject("vec_packpx"))) return 0;
- if (!(intrinsics[Intrinsic_091] = CheckRuntimeObject("vec_packs"))) return 0;
- if (!(intrinsics[Intrinsic_092] = CheckRuntimeObject("vec_packsu"))) return 0;
- if (!(intrinsics[Intrinsic_093] = CheckRuntimeObject("vec_perm"))) return 0;
- if (!(intrinsics[Intrinsic_094] = CheckRuntimeObject("vec_re"))) return 0;
- if (!(intrinsics[Intrinsic_095] = CheckRuntimeObject("vec_rl"))) return 0;
- if (!(intrinsics[Intrinsic_096] = CheckRuntimeObject("vec_round"))) return 0;
- if (!(intrinsics[Intrinsic_097] = CheckRuntimeObject("vec_rsqrte"))) return 0;
- if (!(intrinsics[Intrinsic_098] = CheckRuntimeObject("vec_sel"))) return 0;
- if (!(intrinsics[Intrinsic_099] = CheckRuntimeObject("vec_sl"))) return 0;
- if (!(intrinsics[Intrinsic_100] = CheckRuntimeObject("vec_sld"))) return 0;
- if (!(intrinsics[Intrinsic_101] = CheckRuntimeObject("vec_sll"))) return 0;
- if (!(intrinsics[Intrinsic_102] = CheckRuntimeObject("vec_slo"))) return 0;
- if (!(intrinsics[Intrinsic_103] = CheckRuntimeObject("vec_splat"))) return 0;
- if (!(intrinsics[Intrinsic_104] = CheckRuntimeObject("vec_splat_s8"))) return 0;
- if (!(intrinsics[Intrinsic_105] = CheckRuntimeObject("vec_splat_s16"))) return 0;
- if (!(intrinsics[Intrinsic_106] = CheckRuntimeObject("vec_splat_s32"))) return 0;
- if (!(intrinsics[Intrinsic_107] = CheckRuntimeObject("vec_splat_u8"))) return 0;
- if (!(intrinsics[Intrinsic_108] = CheckRuntimeObject("vec_splat_u16"))) return 0;
- if (!(intrinsics[Intrinsic_109] = CheckRuntimeObject("vec_splat_u32"))) return 0;
- if (!(intrinsics[Intrinsic_110] = CheckRuntimeObject("vec_sr"))) return 0;
- if (!(intrinsics[Intrinsic_111] = CheckRuntimeObject("vec_sra"))) return 0;
- if (!(intrinsics[Intrinsic_112] = CheckRuntimeObject("vec_srl"))) return 0;
- if (!(intrinsics[Intrinsic_113] = CheckRuntimeObject("vec_sro"))) return 0;
- if (!(intrinsics[Intrinsic_114] = CheckRuntimeObject("vec_st"))) return 0;
- if (!(intrinsics[Intrinsic_115] = CheckRuntimeObject("vec_ste"))) return 0;
- if (!(intrinsics[Intrinsic_116] = CheckRuntimeObject("vec_stl"))) return 0;
- if (!(intrinsics[Intrinsic_117] = CheckRuntimeObject("vec_sub"))) return 0;
- if (!(intrinsics[Intrinsic_118] = CheckRuntimeObject("vec_subc"))) return 0;
- if (!(intrinsics[Intrinsic_119] = CheckRuntimeObject("vec_subs"))) return 0;
- if (!(intrinsics[Intrinsic_120] = CheckRuntimeObject("vec_sum4s"))) return 0;
- if (!(intrinsics[Intrinsic_121] = CheckRuntimeObject("vec_sum2s"))) return 0;
- if (!(intrinsics[Intrinsic_122] = CheckRuntimeObject("vec_sums"))) return 0;
- if (!(intrinsics[Intrinsic_123] = CheckRuntimeObject("vec_trunc"))) return 0;
- if (!(intrinsics[Intrinsic_124] = CheckRuntimeObject("vec_unpack2sh"))) return 0;
- if (!(intrinsics[Intrinsic_125] = CheckRuntimeObject("vec_unpack2sl"))) return 0;
- if (!(intrinsics[Intrinsic_126] = CheckRuntimeObject("vec_unpack2uh"))) return 0;
- if (!(intrinsics[Intrinsic_127] = CheckRuntimeObject("vec_unpack2ul"))) return 0;
- if (!(intrinsics[Intrinsic_128] = CheckRuntimeObject("vec_unpackh"))) return 0;
- if (!(intrinsics[Intrinsic_129] = CheckRuntimeObject("vec_unpackl"))) return 0;
- if (!(intrinsics[Intrinsic_130] = CheckRuntimeObject("vec_xor"))) return 0;
- if (!(intrinsics[Intrinsic_131] = CheckRuntimeObject("vec_all_eq"))) return 0;
- if (!(intrinsics[Intrinsic_132] = CheckRuntimeObject("vec_all_ge"))) return 0;
- if (!(intrinsics[Intrinsic_133] = CheckRuntimeObject("vec_all_gt"))) return 0;
- if (!(intrinsics[Intrinsic_134] = CheckRuntimeObject("vec_all_in"))) return 0;
- if (!(intrinsics[Intrinsic_135] = CheckRuntimeObject("vec_all_le"))) return 0;
- if (!(intrinsics[Intrinsic_136] = CheckRuntimeObject("vec_all_lt"))) return 0;
- if (!(intrinsics[Intrinsic_137] = CheckRuntimeObject("vec_all_nan"))) return 0;
- if (!(intrinsics[Intrinsic_138] = CheckRuntimeObject("vec_all_ne"))) return 0;
- if (!(intrinsics[Intrinsic_139] = CheckRuntimeObject("vec_all_nge"))) return 0;
- if (!(intrinsics[Intrinsic_140] = CheckRuntimeObject("vec_all_ngt"))) return 0;
- if (!(intrinsics[Intrinsic_141] = CheckRuntimeObject("vec_all_nle"))) return 0;
- if (!(intrinsics[Intrinsic_142] = CheckRuntimeObject("vec_all_nlt"))) return 0;
- if (!(intrinsics[Intrinsic_143] = CheckRuntimeObject("vec_all_numeric"))) return 0;
- if (!(intrinsics[Intrinsic_144] = CheckRuntimeObject("vec_any_eq"))) return 0;
- if (!(intrinsics[Intrinsic_145] = CheckRuntimeObject("vec_any_ge"))) return 0;
- if (!(intrinsics[Intrinsic_146] = CheckRuntimeObject("vec_any_gt"))) return 0;
- if (!(intrinsics[Intrinsic_147] = CheckRuntimeObject("vec_any_le"))) return 0;
- if (!(intrinsics[Intrinsic_148] = CheckRuntimeObject("vec_any_lt"))) return 0;
- if (!(intrinsics[Intrinsic_149] = CheckRuntimeObject("vec_any_nan"))) return 0;
- if (!(intrinsics[Intrinsic_150] = CheckRuntimeObject("vec_any_ne"))) return 0;
- if (!(intrinsics[Intrinsic_151] = CheckRuntimeObject("vec_any_nge"))) return 0;
- if (!(intrinsics[Intrinsic_152] = CheckRuntimeObject("vec_any_ngt"))) return 0;
- if (!(intrinsics[Intrinsic_153] = CheckRuntimeObject("vec_any_nle"))) return 0;
- if (!(intrinsics[Intrinsic_154] = CheckRuntimeObject("vec_any_nlt"))) return 0;
- if (!(intrinsics[Intrinsic_155] = CheckRuntimeObject("vec_any_numeric"))) return 0;
- if (!(intrinsics[Intrinsic_156] = CheckRuntimeObject("vec_any_out"))) return 0;
- if (!(intrinsics[Intrinsic_157] = CheckRuntimeObject("vec_vaddubm"))) return 0;
- if (!(intrinsics[Intrinsic_158] = CheckRuntimeObject("vec_vadduhm"))) return 0;
- if (!(intrinsics[Intrinsic_159] = CheckRuntimeObject("vec_vadduwm"))) return 0;
- if (!(intrinsics[Intrinsic_160] = CheckRuntimeObject("vec_vaddfp"))) return 0;
- if (!(intrinsics[Intrinsic_161] = CheckRuntimeObject("vec_vaddcuw"))) return 0;
- if (!(intrinsics[Intrinsic_162] = CheckRuntimeObject("vec_vaddubs"))) return 0;
- if (!(intrinsics[Intrinsic_163] = CheckRuntimeObject("vec_vaddubs"))) return 0;
- if (!(intrinsics[Intrinsic_164] = CheckRuntimeObject("vec_vadduhs"))) return 0;
- if (!(intrinsics[Intrinsic_165] = CheckRuntimeObject("vec_vadduhs"))) return 0;
- if (!(intrinsics[Intrinsic_166] = CheckRuntimeObject("vec_vadduws"))) return 0;
- if (!(intrinsics[Intrinsic_167] = CheckRuntimeObject("vec_vadduws"))) return 0;
- if (!(intrinsics[Intrinsic_168] = CheckRuntimeObject("vec_vand"))) return 0;
- if (!(intrinsics[Intrinsic_169] = CheckRuntimeObject("vec_vandc"))) return 0;
- if (!(intrinsics[Intrinsic_170] = CheckRuntimeObject("vec_vavgub"))) return 0;
- if (!(intrinsics[Intrinsic_171] = CheckRuntimeObject("vec_vavgsb"))) return 0;
- if (!(intrinsics[Intrinsic_172] = CheckRuntimeObject("vec_vavguh"))) return 0;
- if (!(intrinsics[Intrinsic_173] = CheckRuntimeObject("vec_vavgsh"))) return 0;
- if (!(intrinsics[Intrinsic_174] = CheckRuntimeObject("vec_vavguw"))) return 0;
- if (!(intrinsics[Intrinsic_175] = CheckRuntimeObject("vec_vavgsw"))) return 0;
- if (!(intrinsics[Intrinsic_176] = CheckRuntimeObject("vec_vrfip"))) return 0;
- if (!(intrinsics[Intrinsic_177] = CheckRuntimeObject("vec_vcmpbfp"))) return 0;
- if (!(intrinsics[Intrinsic_178] = CheckRuntimeObject("vec_vcmpequb"))) return 0;
- if (!(intrinsics[Intrinsic_179] = CheckRuntimeObject("vec_vcmpequh"))) return 0;
- if (!(intrinsics[Intrinsic_180] = CheckRuntimeObject("vec_vcmpequw"))) return 0;
- if (!(intrinsics[Intrinsic_181] = CheckRuntimeObject("vec_vcmpeqfp"))) return 0;
- if (!(intrinsics[Intrinsic_182] = CheckRuntimeObject("vec_vcmpgefp"))) return 0;
- if (!(intrinsics[Intrinsic_183] = CheckRuntimeObject("vec_vcmpgtub"))) return 0;
- if (!(intrinsics[Intrinsic_184] = CheckRuntimeObject("vec_vcmpgtsb"))) return 0;
- if (!(intrinsics[Intrinsic_185] = CheckRuntimeObject("vec_vcmpgtuh"))) return 0;
- if (!(intrinsics[Intrinsic_186] = CheckRuntimeObject("vec_vcmpgtsh"))) return 0;
- if (!(intrinsics[Intrinsic_187] = CheckRuntimeObject("vec_vcmpgtuw"))) return 0;
- if (!(intrinsics[Intrinsic_188] = CheckRuntimeObject("vec_vcmpgtsw"))) return 0;
- if (!(intrinsics[Intrinsic_189] = CheckRuntimeObject("vec_vcmpgtfp"))) return 0;
- if (!(intrinsics[Intrinsic_190] = CheckRuntimeObject("vec_vcfux"))) return 0;
- if (!(intrinsics[Intrinsic_191] = CheckRuntimeObject("vec_vcfsx"))) return 0;
- if (!(intrinsics[Intrinsic_192] = CheckRuntimeObject("vec_vctsxs"))) return 0;
- if (!(intrinsics[Intrinsic_193] = CheckRuntimeObject("vec_vctuxs"))) return 0;
- if (!(intrinsics[Intrinsic_194] = CheckRuntimeObject("vec_vexptefp"))) return 0;
- if (!(intrinsics[Intrinsic_195] = CheckRuntimeObject("vec_vrfim"))) return 0;
- if (!(intrinsics[Intrinsic_196] = CheckRuntimeObject("vec_lvx"))) return 0;
- if (!(intrinsics[Intrinsic_197] = CheckRuntimeObject("vec_lvebx"))) return 0;
- if (!(intrinsics[Intrinsic_198] = CheckRuntimeObject("vec_lvehx"))) return 0;
- if (!(intrinsics[Intrinsic_199] = CheckRuntimeObject("vec_lvewx"))) return 0;
- if (!(intrinsics[Intrinsic_200] = CheckRuntimeObject("vec_lvxl"))) return 0;
- if (!(intrinsics[Intrinsic_201] = CheckRuntimeObject("vec_vlogefp"))) return 0;
- if (!(intrinsics[Intrinsic_202] = CheckRuntimeObject("vec_vmaddfp"))) return 0;
- if (!(intrinsics[Intrinsic_203] = CheckRuntimeObject("vec_vmhaddshs"))) return 0;
- if (!(intrinsics[Intrinsic_204] = CheckRuntimeObject("vec_vmaxub"))) return 0;
- if (!(intrinsics[Intrinsic_205] = CheckRuntimeObject("vec_vmaxsb"))) return 0;
- if (!(intrinsics[Intrinsic_206] = CheckRuntimeObject("vec_vmaxuh"))) return 0;
- if (!(intrinsics[Intrinsic_207] = CheckRuntimeObject("vec_vmaxsh"))) return 0;
- if (!(intrinsics[Intrinsic_208] = CheckRuntimeObject("vec_vmaxuw"))) return 0;
- if (!(intrinsics[Intrinsic_209] = CheckRuntimeObject("vec_vmaxsw"))) return 0;
- if (!(intrinsics[Intrinsic_210] = CheckRuntimeObject("vec_vmaxfp"))) return 0;
- if (!(intrinsics[Intrinsic_211] = CheckRuntimeObject("vec_vmrghb"))) return 0;
- if (!(intrinsics[Intrinsic_212] = CheckRuntimeObject("vec_vmrghh"))) return 0;
- if (!(intrinsics[Intrinsic_213] = CheckRuntimeObject("vec_vmrghw"))) return 0;
- if (!(intrinsics[Intrinsic_214] = CheckRuntimeObject("vec_vmrglb"))) return 0;
- if (!(intrinsics[Intrinsic_215] = CheckRuntimeObject("vec_vmrglh"))) return 0;
- if (!(intrinsics[Intrinsic_216] = CheckRuntimeObject("vec_vmrglw"))) return 0;
- if (!(intrinsics[Intrinsic_204] = CheckRuntimeObject("vec_vminub"))) return 0;
- if (!(intrinsics[Intrinsic_205] = CheckRuntimeObject("vec_vminsb"))) return 0;
- if (!(intrinsics[Intrinsic_206] = CheckRuntimeObject("vec_vminuh"))) return 0;
- if (!(intrinsics[Intrinsic_207] = CheckRuntimeObject("vec_vminsh"))) return 0;
- if (!(intrinsics[Intrinsic_208] = CheckRuntimeObject("vec_vminuw"))) return 0;
- if (!(intrinsics[Intrinsic_209] = CheckRuntimeObject("vec_vminsw"))) return 0;
- if (!(intrinsics[Intrinsic_210] = CheckRuntimeObject("vec_vminfp"))) return 0;
- if (!(intrinsics[Intrinsic_224] = CheckRuntimeObject("vec_vmladduhm"))) return 0;
- if (!(intrinsics[Intrinsic_225] = CheckRuntimeObject("vec_vmhraddshs"))) return 0;
- if (!(intrinsics[Intrinsic_226] = CheckRuntimeObject("vec_vmsumubm"))) return 0;
- if (!(intrinsics[Intrinsic_227] = CheckRuntimeObject("vec_vmsumuhm"))) return 0;
- if (!(intrinsics[Intrinsic_228] = CheckRuntimeObject("vec_vmsummbm"))) return 0;
- if (!(intrinsics[Intrinsic_229] = CheckRuntimeObject("vec_vmsumshm"))) return 0;
- if (!(intrinsics[Intrinsic_230] = CheckRuntimeObject("vec_vmsumuhs"))) return 0;
- if (!(intrinsics[Intrinsic_231] = CheckRuntimeObject("vec_vmsumshs"))) return 0;
- if (!(intrinsics[Intrinsic_232] = CheckRuntimeObject("vec_vmuleub"))) return 0;
- if (!(intrinsics[Intrinsic_233] = CheckRuntimeObject("vec_vmulesb"))) return 0;
- if (!(intrinsics[Intrinsic_234] = CheckRuntimeObject("vec_vmuleuh"))) return 0;
- if (!(intrinsics[Intrinsic_235] = CheckRuntimeObject("vec_vmulesh"))) return 0;
- if (!(intrinsics[Intrinsic_236] = CheckRuntimeObject("vec_vmuloub"))) return 0;
- if (!(intrinsics[Intrinsic_237] = CheckRuntimeObject("vec_vmulosb"))) return 0;
- if (!(intrinsics[Intrinsic_238] = CheckRuntimeObject("vec_vmulouh"))) return 0;
- if (!(intrinsics[Intrinsic_239] = CheckRuntimeObject("vec_vmulosh"))) return 0;
- if (!(intrinsics[Intrinsic_240] = CheckRuntimeObject("vec_vnmsubfp"))) return 0;
- if (!(intrinsics[Intrinsic_241] = CheckRuntimeObject("vec_vnor"))) return 0;
- if (!(intrinsics[Intrinsic_242] = CheckRuntimeObject("vec_vor"))) return 0;
- if (!(intrinsics[Intrinsic_243] = CheckRuntimeObject("vec_vpkuhum"))) return 0;
- if (!(intrinsics[Intrinsic_244] = CheckRuntimeObject("vec_vpkuwum"))) return 0;
- if (!(intrinsics[Intrinsic_245] = CheckRuntimeObject("vec_vpkpx"))) return 0;
- if (!(intrinsics[Intrinsic_246] = CheckRuntimeObject("vec_vpkuhus"))) return 0;
- if (!(intrinsics[Intrinsic_247] = CheckRuntimeObject("vec_vpkshss"))) return 0;
- if (!(intrinsics[Intrinsic_248] = CheckRuntimeObject("vec_vpkuwus"))) return 0;
- if (!(intrinsics[Intrinsic_249] = CheckRuntimeObject("vec_vpkswss"))) return 0;
- if (!(intrinsics[Intrinsic_250] = CheckRuntimeObject("vec_vpkshus"))) return 0;
- if (!(intrinsics[Intrinsic_251] = CheckRuntimeObject("vec_vpkswus"))) return 0;
- if (!(intrinsics[Intrinsic_252] = CheckRuntimeObject("vec_vperm"))) return 0;
- if (!(intrinsics[Intrinsic_253] = CheckRuntimeObject("vec_vrefp"))) return 0;
- if (!(intrinsics[Intrinsic_254] = CheckRuntimeObject("vec_vrlb"))) return 0;
- if (!(intrinsics[Intrinsic_255] = CheckRuntimeObject("vec_vrlh"))) return 0;
- if (!(intrinsics[Intrinsic_256] = CheckRuntimeObject("vec_vrlw"))) return 0;
- if (!(intrinsics[Intrinsic_257] = CheckRuntimeObject("vec_vrfin"))) return 0;
- if (!(intrinsics[Intrinsic_258] = CheckRuntimeObject("vec_vrsqrtefp"))) return 0;
- if (!(intrinsics[Intrinsic_259] = CheckRuntimeObject("vec_vsel"))) return 0;
- if (!(intrinsics[Intrinsic_260] = CheckRuntimeObject("vec_vslb"))) return 0;
- if (!(intrinsics[Intrinsic_261] = CheckRuntimeObject("vec_vslh"))) return 0;
- if (!(intrinsics[Intrinsic_262] = CheckRuntimeObject("vec_vslw"))) return 0;
- if (!(intrinsics[Intrinsic_263] = CheckRuntimeObject("vec_vsldoi"))) return 0;
- if (!(intrinsics[Intrinsic_264] = CheckRuntimeObject("vec_vsl"))) return 0;
- if (!(intrinsics[Intrinsic_265] = CheckRuntimeObject("vec_vslo"))) return 0;
- if (!(intrinsics[Intrinsic_266] = CheckRuntimeObject("vec_vspltb"))) return 0;
- if (!(intrinsics[Intrinsic_267] = CheckRuntimeObject("vec_vsplth"))) return 0;
- if (!(intrinsics[Intrinsic_268] = CheckRuntimeObject("vec_vspltw"))) return 0;
- if (!(intrinsics[Intrinsic_269] = CheckRuntimeObject("vec_vspltisb"))) return 0;
- if (!(intrinsics[Intrinsic_270] = CheckRuntimeObject("vec_vspltish"))) return 0;
- if (!(intrinsics[Intrinsic_271] = CheckRuntimeObject("vec_vspltisw"))) return 0;
- if (!(intrinsics[Intrinsic_272] = CheckRuntimeObject("vec_vsrb"))) return 0;
- if (!(intrinsics[Intrinsic_273] = CheckRuntimeObject("vec_vsrh"))) return 0;
- if (!(intrinsics[Intrinsic_274] = CheckRuntimeObject("vec_vsrw"))) return 0;
- if (!(intrinsics[Intrinsic_275] = CheckRuntimeObject("vec_vsrab"))) return 0;
- if (!(intrinsics[Intrinsic_276] = CheckRuntimeObject("vec_vsrah"))) return 0;
- if (!(intrinsics[Intrinsic_277] = CheckRuntimeObject("vec_vsraw"))) return 0;
- if (!(intrinsics[Intrinsic_278] = CheckRuntimeObject("vec_vsr"))) return 0;
- if (!(intrinsics[Intrinsic_279] = CheckRuntimeObject("vec_vsro"))) return 0;
- if (!(intrinsics[Intrinsic_280] = CheckRuntimeObject("vec_stvx"))) return 0;
- if (!(intrinsics[Intrinsic_281] = CheckRuntimeObject("vec_stvebx"))) return 0;
- if (!(intrinsics[Intrinsic_282] = CheckRuntimeObject("vec_stvehx"))) return 0;
- if (!(intrinsics[Intrinsic_283] = CheckRuntimeObject("vec_stvewx"))) return 0;
- if (!(intrinsics[Intrinsic_284] = CheckRuntimeObject("vec_stvxl"))) return 0;
- if (!(intrinsics[Intrinsic_285] = CheckRuntimeObject("vec_vsububm"))) return 0;
- if (!(intrinsics[Intrinsic_286] = CheckRuntimeObject("vec_vsubuhm"))) return 0;
- if (!(intrinsics[Intrinsic_287] = CheckRuntimeObject("vec_vsubuwm"))) return 0;
- if (!(intrinsics[Intrinsic_288] = CheckRuntimeObject("vec_vsubfp"))) return 0;
- if (!(intrinsics[Intrinsic_289] = CheckRuntimeObject("vec_vsubcuw"))) return 0;
- if (!(intrinsics[Intrinsic_290] = CheckRuntimeObject("vec_vsububs"))) return 0;
- if (!(intrinsics[Intrinsic_291] = CheckRuntimeObject("vec_vsubsbs"))) return 0;
- if (!(intrinsics[Intrinsic_292] = CheckRuntimeObject("vec_vsubuhs"))) return 0;
- if (!(intrinsics[Intrinsic_293] = CheckRuntimeObject("vec_vsubshs"))) return 0;
- if (!(intrinsics[Intrinsic_294] = CheckRuntimeObject("vec_vsubuws"))) return 0;
- if (!(intrinsics[Intrinsic_295] = CheckRuntimeObject("vec_vsubsws"))) return 0;
- if (!(intrinsics[Intrinsic_296] = CheckRuntimeObject("vec_vsum4ubs"))) return 0;
- if (!(intrinsics[Intrinsic_297] = CheckRuntimeObject("vec_vsum4sbs"))) return 0;
- if (!(intrinsics[Intrinsic_298] = CheckRuntimeObject("vec_vsum4shs"))) return 0;
- if (!(intrinsics[Intrinsic_299] = CheckRuntimeObject("vec_vsum2sws"))) return 0;
- if (!(intrinsics[Intrinsic_300] = CheckRuntimeObject("vec_vsumsws"))) return 0;
- if (!(intrinsics[Intrinsic_301] = CheckRuntimeObject("vec_vrfiz"))) return 0;
- if (!(intrinsics[Intrinsic_302] = CheckRuntimeObject("vec_vupkhsb"))) return 0;
- if (!(intrinsics[Intrinsic_303] = CheckRuntimeObject("vec_vupklsb"))) return 0;
- if (!(intrinsics[Intrinsic_304] = CheckRuntimeObject("vec_vupkhpx"))) return 0;
- if (!(intrinsics[Intrinsic_305] = CheckRuntimeObject("vec_vupklpx"))) return 0;
- if (!(intrinsics[Intrinsic_306] = CheckRuntimeObject("vec_vupkhsh"))) return 0;
- if (!(intrinsics[Intrinsic_307] = CheckRuntimeObject("vec_vupklsh"))) return 0;
- if (!(intrinsics[Intrinsic_308] = CheckRuntimeObject("vec_vxor"))) return 0;
- if (!(intrinsics[Intrinsic_309] = CheckRuntimeObject("vec_abs"))) return 0;
- if (!(intrinsics[Intrinsic_310] = CheckRuntimeObject("vec_abss"))) return 0;
- }
-
- return 1;
-}
-
-Boolean Intrinsics_IsPublicRuntimeObject(Object *object) {
- int i;
-
- for (i = 0; i < MaxIntrinsics; i++) {
- if (object == intrinsics[i])
- return 1;
- }
-
- return 0;
-}
diff --git a/compiler_and_linker/unsorted/IrOptimizer.c b/compiler_and_linker/unsorted/IrOptimizer.c
deleted file mode 100644
index c9544a2..0000000
--- a/compiler_and_linker/unsorted/IrOptimizer.c
+++ /dev/null
@@ -1,400 +0,0 @@
-#include "compiler/IrOptimizer.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroEval.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroSubable.h"
-#include "compiler/IroTransform.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/objects.h"
-#include "compiler/IroPropagate.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroJump.h"
-#include "compiler/IroRangePropagation.h"
-#include "compiler/IroEmptyLoop.h"
-#include "compiler/IroUnrollLoop.h"
-#include "compiler/IroLoop.h"
-#include "compiler/IroExprRegeneration.h"
-
-Boolean DoScalarize;
-Boolean DoLinearize;
-Boolean EarlyReturn;
-Boolean IRO_CPFirstTime;
-Boolean VectorPhaseCalledFromUnroll;
-Boolean IRO_Log;
-static Boolean stIsSetup;
-
-static void CountRefToObject(Object *object, int depth) {
- static unsigned short LoopUsage[] = {1, 4, 16, 64};
-
- if (depth > 3)
- depth = 3;
-
- object->u.var.info->usage += LoopUsage[depth];
- object->u.var.info->used = 1;
-}
-
-static void CountARef(IROLinear *node, int depth) {
- Object *object;
-
- object = node->u.node->data.objref;
- CError_ASSERT(78, object->datatype != DALIAS);
-
- if (object->datatype == DLOCAL && object->u.var.info) {
- CountRefToObject(object, depth);
- if ((node->flags & IROLF_Used) && (node->flags & IROLF_Assigned))
- CountRefToObject(object, depth);
-
- if (!(node->flags & IROLF_Immind) && !object->u.var.info->noregister)
- object->u.var.info->noregister = 2;
- }
-}
-
-static void CountDoubleInd(IROLinear *node, int depth) {
- if (IRO_IsVariable(node)) {
- CountARef(node->u.monadic, depth);
- } else if (node->type == IROLinearOp2Arg) {
- if (node->nodetype == EADD) {
- CountDoubleInd(node->u.diadic.left, depth);
- CountDoubleInd(node->u.diadic.right, depth);
- } else if (IRO_IsAddressMultiply(node)) {
- if (IRO_IsVariable(node->u.diadic.left))
- CountARef(node->u.diadic.left->u.monadic, depth);
- }
- }
-}
-
-static void CountUsage(void) {
- IRONode *fnode = IRO_FirstNode;
- IROLinear *node;
-
- if (IRO_FirstNode) {
- for (; fnode; fnode = fnode->nextnode) {
- for (node = fnode->first; node; node = node->next) {
- if (IS_LINEAR_ENODE(node, EOBJREF))
- CountARef(node, fnode->loopdepth);
- else if (IS_LINEAR_MONADIC(node, EINDIRECT))
- CountDoubleInd(node->u.monadic, fnode->loopdepth);
-
- if (node->type == IROLinearAsm) {
- IAEffects effects;
- int i;
-
- CodeGen_GetAsmEffects(node->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++) {
- Object *object = effects.operands[i].object;
- if (object->datatype == DLOCAL && object->u.var.info) {
- CountRefToObject(object, fnode->loopdepth);
- if (effects.operands[i].type == IAOpnd_3 && !object->u.var.info->noregister)
- object->u.var.info->noregister = 2;
- }
- }
- }
-
- if (node == fnode->last)
- break;
- }
- }
- } else {
- for (node = IRO_FirstLinear; node; node = node->next) {
- if (IS_LINEAR_ENODE(node, EOBJREF))
- CountARef(node, 0);
- else if (IS_LINEAR_MONADIC(node, EINDIRECT))
- CountDoubleInd(node->u.monadic, 0);
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-Statement *IRO_Optimizer(Object *func, Statement *statements) {
- Boolean changed;
- int pass;
- int passCount;
-
- CError_ASSERT(234, stIsSetup);
-
-#ifdef CW_ENABLE_IRO_DEBUG
- if (copts.debuglisting)
- IRO_Log = 1;
-#endif
-
- DisableDueToAsm = 0;
- FunctionName = func;
- DoScalarize = 1;
- DoLinearize = 1;
- EarlyReturn = 0;
- IRO_Depends = NULL;
- LoopOptimizerRun = 0;
- IRO_IsLeafFunction = 1;
- IRO_FunctionHasReturn = 0;
-
- IRO_SetupForUserBreakChecking();
-
- IRO_Dump("Starting function %s\n", func ? func->name->name : "Init-code");
- IRO_Dump("--------------------------------------------------------------------------------\n");
-
- if (DoLinearize)
- IRO_PreLinearize(statements);
- if (copts.optimizationlevel > 0)
- IRO_TransformTree(statements);
-
- VectorPhaseCalledFromUnroll = 0;
-
- IRO_Linearize(statements);
-
- CurStat = NULL;
-
- IRO_FirstExpr = NULL;
- IRO_LastExpr = NULL;
- IRO_FirstAssign = NULL;
- IRO_LastAssign = NULL;
- IRO_FirstVarUse = NULL;
- IRO_LastVarUse = NULL;
- IRO_FirstNode = NULL;
- IRO_LastNode = NULL;
-
- if (copts.optimizationlevel > 0)
- IRO_DoTransformations();
-
- IRO_BuildFlowgraph(IRO_FirstLinear);
- IRO_DumpAfterPhase("IRO_BuildflowGraph", 0);
-
- IRO_FindAllVars();
- IRO_CheckInit();
-
- if (!DisableDueToAsm && copts.optimizationlevel > 0 && copts.opt_pointer_analysis && func) {
- IRO_AnalyzePointers(func);
- if (copts.propagation && IRO_EvaluateDefinitePointers(func)) {
- IRO_UpdateFlagsOnInts();
- IRO_UpdateVars();
- IRO_DumpAfterPhase("IRO_EvaluateDefinitePointers", 0);
- }
- }
-
- if (copts.optimizationlevel > 0) {
- changed = IRO_EvaluateConditionals();
-
- if (!DisableDueToAsm) {
- changed |= IRO_RemoveUnreachable();
- IRO_DumpAfterPhase("IRO_RemoveUnreachable", 0);
- }
-
- changed |= IRO_RemoveRedundantJumps();
- IRO_DumpAfterPhase("IRO_RemoveRedundantJumps", 0);
-
- if (!DisableDueToAsm) {
- changed |= IRO_RemoveLabels();
- IRO_DumpAfterPhase("IRO_RemoveLabels()", 0);
- }
-
- if (changed) {
- IRO_BuildFlowgraph(IRO_FirstLinear);
- IRO_DumpAfterPhase("IRO_BuildflowGraph--1", 0);
- }
- }
-
- if (!DisableDueToAsm && copts.optimizationlevel > 0) {
- passCount = copts.multiplepasses ? 2 : 1;
- IRO_CPFirstTime = 1;
- for (pass = 0; pass < passCount; pass++) {
- IRO_Dump("*****************\n");
- IRO_Dump("Dumps for pass=%d\n", pass);
- IRO_Dump("*****************\n");
-
- if (DoScalarize)
- IRO_ScalarizeClassDataMembers();
- IRO_DumpAfterPhase("IRO_ScalarizeClassDataMembers", 0);
-
- if (copts.propagation) {
- IRO_CopyAndConstantPropagation();
- IRO_CPFirstTime = 0;
- IRO_ExpressionPropagation();
- IRO_DumpAfterPhase("Copy and constant propagation", 0);
-
- IRO_RangePropagateInFNode();
- IRO_DumpAfterPhase("IRO_RangePropagateInFNode", 0);
- IRO_UpdateFlagsOnInts();
- }
-
- IRO_DumpAfterPhase("IRO_ExpressionPropagation", 0);
-
- if (copts.deadstore || copts.propagation)
- IRO_UseDef(copts.deadstore, copts.propagation);
- IRO_DumpAfterPhase("after IRO_UseDef", 0);
-
- IRO_UpdateVars();
- IRO_ConstantFolding();
- IRO_DumpAfterPhase("IRO_ConstantFolding", 0);
-
- IRO_EvaluateConditionals();
- IRO_RemoveUnreachable();
- IRO_SimplifyConditionals();
-
- if (pass == 1 && copts.optimizationlevel > 2) {
- IRO_RenumberInts();
- IRO_DumpAfterPhase("Before IRO_FindEmptyLoops", 0);
- IRO_FindEmptyLoops();
- IRO_DumpAfterPhase("After IRO_FindEmptyLoops", 0);
- IRO_RenumberInts();
- }
-
- if (copts.unrolling && !copts.optimizesize && pass == 0) {
- IRO_DumpAfterPhase("Before IRO_LoopUnroller", 0);
- IRO_LoopUnroller();
- IRO_DumpAfterPhase("After IRO_LoopUnroller", 0);
- IRO_RenumberInts();
- }
-
- VectorPhaseCalledFromUnroll = 0;
-
- if (pass == 0 && (copts.loopinvariants || copts.strengthreduction)) {
- IRO_DumpAfterPhase("Before IRO_FindLoops", 0);
- IRO_FindLoops();
- LoopOptimizerRun = 1;
- IRO_SetLoopDepth();
- }
- IRO_DumpAfterPhase("After IRO_FindLoops", 0);
-
- if (copts.propagation) {
- IRO_CopyAndConstantPropagation();
- IRO_ConstantFolding();
- IRO_EvaluateConditionals();
- }
-
- IRO_DumpAfterPhase("Second pass:IRO_CopyAndConstantPropagation, IRO_ConstantFolding, IRO_EvaluateConditionals", 0);
-
- if (copts.commonsubs)
- IRO_FindExpressions(NULL, 0);
-
- if (copts.commonsubs) {
- IRO_ComputeAvail();
- IRO_CommonSubs();
- }
- IRO_DumpAfterPhase("IRO_CommonSubs", 0);
-
- IRO_UpdateFlagsOnInts();
- IRO_UpdateVars();
- IRO_DoTransformations();
- IRO_ConstantFolding();
-
- do {
- IRO_UpdateFlagsOnInts();
-
- if (copts.deadcode)
- IRO_RemoveUnreachable();
- IRO_DumpAfterPhase("IRO_RemoveUnreachable", 0);
-
- changed = IRO_RemoveRedundantJumps();
- IRO_DumpAfterPhase("IRO_RemoveRedundantJumps", 0);
-
- changed |= IRO_RemoveLabels();
- IRO_DumpAfterPhase("IRO_RemoveLabels", 0);
-
- changed |= IRO_DoJumpChaining();
- IRO_DumpAfterPhase("IRO_DoJumpChaining", 0);
-
- if (copts.propagation) {
- IRO_RenumberInts();
- IRO_DumpAfterPhase("Before IRO_CopyAndConstantPropagation", 0);
- changed |= IRO_CopyAndConstantPropagation();
- IRO_DumpAfterPhase("After IRO_CopyAndConstantPropagation", 0);
- IRO_ConstantFolding();
- }
-
- if (copts.deadstore || copts.propagation)
- changed |= IRO_UseDef(copts.deadstore, copts.propagation);
- IRO_DumpAfterPhase("IRO_UseDef", 0);
-
- changed |= IRO_EvaluateConditionals();
- IRO_DumpAfterPhase("IRO_EvaluateConditionals", 0);
- } while (changed);
- }
-
- if (copts.lifetimes) {
- IRO_UseDef(0, 0);
- IRO_SplitLifetimes();
- }
-
- IRO_DoTransformations();
- IRO_DumpAfterPhase("Before RebuildCondExpressions", 0);
- }
-
- IRO_RenumberInts();
- IRO_DumpAfterPhase("before IRO_RewriteBitFieldTemps", 0);
- IRO_RewriteBitFieldTemps();
- IRO_DumpAfterPhase("After IRO_RewriteBitFieldTemps", 0);
-
- CountUsage();
-
- if (!DisableDueToAsm) {
- IRO_RegenerateExpressions();
- IRO_DumpAfterPhase("IRO_RegenerateExpressions", 0);
- }
-
- IRO_DumpAfterPhase("After IRO_Optimizer", 0);
-
- statements = IRO_Delinearize(IRO_FirstNode, NULL);
-
- IRO_ZapVarPtrs();
- freeoheap();
- return statements;
-}
-
-void IRO_Setup(void) {
- static Boolean ENodeArraysHaveBeenInitialized;
-
- if (!stIsSetup) {
- IRO_Log = 0;
- IRO_SetupDump();
- if (!ENodeArraysHaveBeenInitialized) {
- IRO_InitializeNodeNamesArray();
- IRO_InitializeIsAssociativeENodeTypeArray();
- IRO_InitializeIsSubableOpArray();
- IRO_InitializeAssignmentOpArray();
- IRO_InitializeComplementaryOpArray();
- IRO_InitializeComplementaryOpLogicalArray();
- IRO_InitializeNonAssignmentOpArray();
- IRO_InitializeAssignmentFoldingFunctionArray();
- IRO_InitializeIRO_IsModifyOpArray();
- IRO_InitializeIRO_IsAssignOpArray();
- ENodeArraysHaveBeenInitialized = 1;
- }
- stIsSetup = 1;
- }
-}
-
-void IRO_Cleanup(void) {
- if (stIsSetup) {
- IRO_CleanupDump();
- stIsSetup = 0;
- }
-}
-
-void CodeGen_UpdateOptimizerOptions(void) {
- Boolean flag;
-
- flag = copts.optimizationlevel >= 1;
- copts.deadcode = flag;
-
- flag = copts.optimizationlevel >= 2;
- copts.propagation = flag;
- copts.commonsubs = flag;
-
- flag = copts.optimizationlevel >= 3;
- copts.vectorizeloops = flag;
- copts.unrolling = flag;
- copts.deadstore = flag;
- copts.lifetimes = flag;
- copts.strengthreduction = flag;
- copts.loopinvariants = flag;
-
- flag = copts.optimizationlevel >= 4;
- copts.multiplepasses = flag;
-}
diff --git a/compiler_and_linker/unsorted/IroBitVect.c b/compiler_and_linker/unsorted/IroBitVect.c
deleted file mode 100644
index 29bc28a..0000000
--- a/compiler_and_linker/unsorted/IroBitVect.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "compiler/BitVector.h"
-#include "compiler/CompilerTools.h"
-
-void Bv_AllocVector(BitVector **bv, UInt32 size) {
- UInt32 long_size = (size / 32) + 1;
- *bv = oalloc(sizeof(BitVector) + sizeof(UInt32) * long_size);
- (*bv)->size = long_size;
- Bv_Clear(*bv);
-}
-
-void Bv_AllocVectorLocal(BitVector **bv, UInt32 size) {
- UInt32 long_size = (size / 32) + 1;
- *bv = lalloc(sizeof(BitVector) + sizeof(UInt32) * long_size);
- (*bv)->size = long_size;
- Bv_Clear(*bv);
-}
-
-void Bv_ClearBit(UInt32 bit, BitVector *bv) {
- if ((bit / 32) < bv->size)
- bv->data[bit / 32] &= ~(1 << (bit & 31));
- else
- CError_FATAL(73);
-}
-
-void Bv_And(const BitVector *a, BitVector *b) {
- UInt32 i;
- for (i = 0; i < b->size; i++)
- b->data[i] &= a->data[i];
-}
-
-void Bv_Or(const BitVector *a, BitVector *b) {
- UInt32 i, len;
-
- len = a->size;
- if (b->size < len)
- len = b->size;
-
- for (i = 0; i < len; i++) {
- b->data[i] |= a->data[i];
- }
-}
-
-Boolean Bv_BitsInCommon(const BitVector *a, const BitVector *b) {
- UInt32 len;
- UInt32 i;
-
- len = a->size;
- if (b->size < len)
- len = b->size;
-
- for (i = 0; i < len; i++) {
- if (a->data[i] & b->data[i])
- return 1;
- }
-
- return 0;
-}
-
-Boolean Bv_Compare(const BitVector *a, const BitVector *b) {
- UInt32 i;
- for (i = 0; i < a->size; i++) {
- if (a->data[i] != b->data[i])
- return 0;
- }
-
- return 1;
-}
-
-void Bv_Minus(const BitVector *a, BitVector *b) {
- UInt32 i;
- for (i = 0; i < b->size; i++)
- b->data[i] &= ~a->data[i];
-}
-
-void Bv_Copy(const BitVector *src, BitVector *dst) {
- memcpy(dst->data, src->data, sizeof(UInt32) * dst->size);
-}
-
-void Bv_Clear(BitVector *bv) {
- memset(bv->data, 0, sizeof(UInt32) * bv->size);
-}
-
-void Bv_Set(BitVector *bv) {
- memset(bv->data, 0xFF, sizeof(UInt32) * bv->size);
-}
-
-Boolean Bv_IsSubset(const BitVector *a, const BitVector *b) {
- UInt32 i;
-
- for (i = 0; i < a->size; i++) {
- if (b->size < i) {
- if (a->data[i])
- return 0;
- } else {
- if (a->data[i] & ~(b->data[i]))
- return 0;
- }
- }
-
- return 1;
-}
-
-Boolean Bv_IsEmpty(const BitVector *bv) {
- UInt32 i;
-
- for (i = 0; i < bv->size; i++) {
- if (bv->data[i])
- return 0;
- }
-
- return 1;
-}
diff --git a/compiler_and_linker/unsorted/IroCSE.c b/compiler_and_linker/unsorted/IroCSE.c
deleted file mode 100644
index 5fa9849..0000000
--- a/compiler_and_linker/unsorted/IroCSE.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroSubable.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-
-BitVector *IRO_Depends;
-Boolean IRO_NotSubable;
-Boolean IRO_IsVolatile;
-Boolean IRO_CouldError;
-IROExpr *IRO_FirstExpr;
-IROExpr *IRO_LastExpr;
-SInt32 IRO_NumExprs;
-static Boolean HasVectorOperand;
-
-// forward decls
-static void IRO_DependsOnForDataFlow(IROLinear *linear, Boolean flag);
-
-static void GetDependsOfIndirect(IROLinear *nd) {
- IROListNode *resultList;
- IROListNode *next;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *scannd;
- Object *obj;
- VarRecord *var;
- int index;
- Boolean result;
- Boolean foundObjRef;
-
- result = 0;
-
- if (nd && copts.opt_pointer_analysis && nd->pointsToFunction && FunctionName) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, nd, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- break;
- }
- }
-
- if (!foundObjRef) {
- result = 1;
- break;
- }
- }
-
- if (!result) {
- while (list) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- CError_ASSERT(119, obj != NULL);
- var = IRO_FindVar(obj, 1, 1);
- CError_ASSERT(121, var != NULL);
- index = var->index;
- CError_ASSERT(123, index != 0);
-
- if (is_volatile_object(obj)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
- Bv_SetBit(index, IRO_Depends);
- }
- }
- list = list->nextList;
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result) {
- nd = nd->u.monadic;
- if (nd->type == IROLinearOp1Arg && nd->nodetype == EBITFIELD)
- nd = nd->u.monadic;
-
- if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD) {
- IRO_BaseTerms = 0;
- IRO_VarTerms = 0;
- IRO_DecomposeAddressExpression_Cheap(nd);
- if (IRO_BaseTerms != 1) {
- IRO_CouldError = 1;
- Bv_SetBit(0, IRO_Depends);
- Bv_Or(IRO_FuncKills, IRO_Depends);
- }
- if (IRO_VarTerms)
- IRO_CouldError = 1;
- } else {
- IRO_CouldError = 1;
- Bv_SetBit(0, IRO_Depends);
- Bv_Or(IRO_FuncKills, IRO_Depends);
- }
- }
-}
-
-static void GetDependsOfFunctionCallForDataFlow(IROLinear *nd) {
- IROLinear *innernd;
- IROListNode *resultList;
- IROListNode *next;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *scannd;
- Object *obj;
- VarRecord *var;
- int index;
- Boolean result;
- Boolean foundObjRef;
- ObjectList *olist;
- ObjectList *depsList;
-
- result = 0;
- innernd = nd->u.funccall.linear8;
-
- if (innernd && copts.opt_pointer_analysis && innernd->pointsToFunction && FunctionName) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, innernd, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = scannd->u.node->data.objref;
- CError_ASSERT(234, obj != NULL);
-
- depsList = NULL;
- PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList);
-
- for (olist = depsList; olist; olist = olist->next) {
- if (!olist->object) {
- result = 1;
- break;
- }
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
-
- if (result)
- break;
- }
- }
-
- if (!foundObjRef)
- result = 1;
- if (result)
- break;
- }
-
- if (!result) {
- for (list = resultList; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
-
- depsList = NULL;
- PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList);
-
- for (olist = depsList; olist; olist = olist->next) {
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(285, var != NULL);
- index = var->index;
- CError_ASSERT(287, index != 0);
-
- if (is_volatile_object(olist->object)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
- Bv_SetBit(index, IRO_Depends);
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result) {
- IRO_DependsOnForDataFlow(nd->u.funccall.linear8, 0);
- Bv_Or(IRO_FuncKills, IRO_Depends);
-
- for (index = nd->u.funccall.argCount - 1; index >= 0; index--)
- IRO_DependsOnForDataFlow(nd->u.funccall.args[index], 0);
- }
-}
-
-static void IRO_DependsOn(IROLinear *linear, Boolean flag) {
- VarRecord *var;
- IROLinear *inner;
-
- if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
-
- if (!IRO_NotSubable) {
- switch (linear->type) {
- case IROLinearOperand:
- if (flag && linear->u.node->type == EOBJREF) {
- if ((var = IRO_FindVar(linear->u.node->data.objref, 0, 1))) {
- if (is_volatile_object(var->object)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
- Bv_SetBit(var->index, IRO_Depends);
- } else {
- IRO_NotSubable = 1;
- }
- }
- break;
- case IROLinearOp1Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- IRO_NotSubable = 1;
- } else {
- inner = linear->u.monadic;
- if (linear->nodetype == EINDIRECT) {
- if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD)
- inner = inner->u.monadic;
- if (inner->type != IROLinearOperand || inner->u.node->type != EOBJREF)
- GetDependsOfIndirect(linear);
- }
-
- IRO_DependsOn(inner, linear->nodetype == EINDIRECT);
- }
- break;
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- IRO_NotSubable = 1;
- } else {
- if (linear->nodetype == EDIV || linear->nodetype == EMODULO) {
- if (IRO_IsIntConstant(linear->u.diadic.right)) {
- if (CInt64_Equal(linear->u.diadic.right->u.node->data.intval, cint64_zero))
- IRO_CouldError = 1;
- } else {
- IRO_CouldError = 1;
- }
- }
-
- IRO_DependsOn(linear->u.diadic.left, flag);
- IRO_DependsOn(linear->u.diadic.right, flag);
- }
- break;
- case IROLinearOp3Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- IRO_NotSubable = 1;
- } else {
- IRO_DependsOn(linear->u.args3.a, flag);
- IRO_DependsOn(linear->u.args3.b, flag);
- IRO_DependsOn(linear->u.args3.c, flag);
- }
- break;
- case IROLinearFunccall:
- IRO_NotSubable = 1;
- break;
- default:
- CError_FATAL(479);
- }
- }
-}
-
-static void IRO_DependsOnForDataFlow(IROLinear *linear, Boolean flag) {
- VarRecord *var;
- IROLinear *inner;
-
- if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
-
- switch (linear->type) {
- case IROLinearOperand:
- if (flag && linear->u.node->type == EOBJREF) {
- if ((var = IRO_FindVar(linear->u.node->data.objref, 0, 1))) {
- if (is_volatile_object(var->object)) {
- IRO_IsVolatile = 1;
- IRO_NotSubable = 1;
- }
- Bv_SetBit(var->index, IRO_Depends);
- } else {
- IRO_NotSubable = 1;
- }
- }
- break;
- case IROLinearOp1Arg:
- if (IRO_IsAssignOp[linear->nodetype])
- IRO_NotSubable = 1;
-
- inner = linear->u.monadic;
- if (linear->nodetype == EINDIRECT) {
- if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD)
- inner = inner->u.monadic;
- if (inner->type != IROLinearOperand || inner->u.node->type != EOBJREF)
- GetDependsOfIndirect(linear);
- }
-
- IRO_DependsOnForDataFlow(inner, linear->nodetype == EINDIRECT);
- break;
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype])
- IRO_NotSubable = 1;
-
- if (linear->nodetype == EDIV || linear->nodetype == EMODULO) {
- if (IRO_IsIntConstant(linear->u.diadic.right)) {
- if (CInt64_Equal(linear->u.diadic.right->u.node->data.intval, cint64_zero))
- IRO_CouldError = 1;
- } else {
- IRO_CouldError = 1;
- }
- }
-
- IRO_DependsOnForDataFlow(linear->u.diadic.left, flag);
- IRO_DependsOnForDataFlow(linear->u.diadic.right, flag);
- break;
- case IROLinearOp3Arg:
- if (IRO_IsAssignOp[linear->nodetype])
- IRO_NotSubable = 1;
-
- IRO_DependsOnForDataFlow(linear->u.args3.a, flag);
- IRO_DependsOnForDataFlow(linear->u.args3.b, flag);
- IRO_DependsOnForDataFlow(linear->u.args3.c, flag);
- break;
- case IROLinearFunccall:
- IRO_NotSubable = 1;
- GetDependsOfFunctionCallForDataFlow(linear);
- break;
- default:
- CError_FATAL(650);
- }
-}
-
-void IRO_FindDepends_NoAlloc(IROLinear *linear) {
- Bv_Clear(IRO_Depends);
- IRO_CouldError = 0;
- IRO_NotSubable = 0;
- IRO_IsVolatile = 0;
- IRO_DependsOnForDataFlow(linear, 0);
-}
-
-void IRO_FindDepends(IROLinear *linear) {
- Bv_AllocVector(&IRO_Depends, IRO_NumVars + 1);
- IRO_CouldError = 0;
- IRO_NotSubable = 0;
- IRO_DependsOn(linear, 0);
-}
-
-static void VecAct(IROLinear *linear, Boolean isFirst) {
- if (!isFirst && (linear->flags & IROLF_VecOpBase))
- HasVectorOperand = 1;
-}
-
-static Boolean IRO_DoesNotHaveVectorOperand(IROLinear *linear) {
- HasVectorOperand = 0;
- IRO_WalkTree(linear, VecAct);
- return HasVectorOperand == 0;
-}
-
-static void IRO_AddExpression(IROLinear *linear, IRONode *node, Boolean flag) {
- IROExpr *expr;
-
- if ((linear->flags & IROLF_Reffed) && IRO_IsSubableExpression(linear) && IRO_DoesNotHaveVectorOperand(linear)) {
- expr = oalloc(sizeof(IROExpr));
- expr->x0 = 0;
- expr->index = ++IRO_NumExprs;
- expr->linear = linear;
- expr->x8 = NULL;
- expr->node = node;
- IRO_FindDepends(linear);
- expr->depends = IRO_Depends;
- expr->notSubable = IRO_NotSubable;
- expr->couldError = IRO_CouldError;
- expr->next = NULL;
- expr->x14 = NULL;
- if (IRO_FirstExpr)
- IRO_LastExpr->next = expr;
- else
- IRO_FirstExpr = expr;
- IRO_LastExpr = expr;
- linear->expr = expr;
- }
-}
-
-void IRO_FindExpressions(BitVector *bv, Boolean flag) {
- IROLinear *nd;
- IRONode *fnode;
-
- IRO_FirstExpr = IRO_LastExpr = NULL;
- IRO_NumExprs = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (!bv || Bv_IsBitSet(fnode->index, bv)) {
- for (nd = fnode->first; nd; nd = nd->next) {
- nd->expr = NULL;
- IRO_AddExpression(nd, fnode, flag);
- if (nd == fnode->last)
- break;
- }
- } else {
- for (nd = fnode->first; nd; nd = nd->next) {
- nd->expr = NULL;
- if (nd == fnode->last)
- break;
- }
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-void IRO_RemoveExpr(IROExpr *expr) {
- IROExpr *prev;
- IROExpr *scan;
-
- scan = IRO_FirstExpr;
- prev = NULL;
- while (scan != expr) {
- prev = scan;
- scan = scan->next;
- CError_ASSERT(809, scan);
- }
-
- expr->linear->expr = NULL;
- if (prev)
- prev->next = expr->next;
- else
- IRO_FirstExpr = expr->next;
-}
-
-static void GetExprKillsByIndirectAssignment(IROLinear *linear) {
- IROLinear *inner;
- IROListNode *resultList;
- IROListNode *next;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *scannd;
- Object *obj;
- VarRecord *var;
- int index;
- Boolean result;
- Boolean foundObjRef;
- IROExpr *expr;
-
- result = 0;
- if (linear->type == IROLinearOp2Arg)
- linear = linear->u.diadic.left;
- else
- linear = linear->u.monadic;
-
- if (
- linear &&
- linear->type == IROLinearOp1Arg &&
- linear->nodetype == EINDIRECT &&
- (inner = linear->u.monadic) &&
- copts.opt_pointer_analysis &&
- inner->pointsToFunction &&
- FunctionName
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- break;
- }
- }
-
- if (!foundObjRef) {
- result = 1;
- break;
- }
- }
-
- if (!result) {
- while (list) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- CError_ASSERT(893, obj != NULL);
- var = IRO_FindVar(obj, 1, 1);
- CError_ASSERT(895, var != NULL);
- index = var->index;
-
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_IsBitSet(index, expr->depends))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- }
- }
- list = list->nextList;
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result) {
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_BitsInCommon(expr->depends, IRO_FuncKills))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- }
-}
-
-static void GetExprKillsByFunctionCall(IROLinear *funccall) {
- IROLinear *innernd;
- IROListNode *resultList;
- IROListNode *next;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *scannd;
- Object *obj;
- VarRecord *var;
- int index;
- Boolean result;
- Boolean foundObjRef;
- ObjectList *olist;
- ObjectList *depsList;
- IROExpr *expr;
-
- result = 0;
- innernd = funccall->u.funccall.linear8;
-
- if (innernd && copts.opt_pointer_analysis && innernd->pointsToFunction && FunctionName) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, innernd, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = scannd->u.node->data.objref;
- CError_ASSERT(991, obj != NULL);
-
- depsList = NULL;
- PointerAnalysis_GetFunctionKills(obj, funccall, &depsList);
-
- for (olist = depsList; olist; olist = olist->next) {
- if (!olist->object) {
- result = 1;
- break;
- }
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
-
- if (result)
- break;
- }
- }
-
- if (!foundObjRef)
- result = 1;
- if (result)
- break;
- }
-
- if (!result) {
- for (list = resultList; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
-
- depsList = NULL;
- PointerAnalysis_GetFunctionKills(obj, funccall, &depsList);
-
- for (olist = depsList; olist; olist = olist->next) {
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(1042, var != NULL);
- index = var->index;
- CError_ASSERT(1044, index != 0);
-
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_IsBitSet(index, expr->depends))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- }
-
- while (depsList) {
- olist = depsList->next;
- IRO_free(depsList);
- depsList = olist;
- }
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result) {
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_BitsInCommon(expr->depends, IRO_FuncKills))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- }
-}
-
-static void IRO_GetExprKills(IROLinear *linear) {
- Bv_Clear(IRO_ExprKills);
- switch (linear->type) {
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- VarRecord *var;
- int index;
-
- var = IRO_FindAssigned(linear);
- index = 0;
- if (var)
- index = var->index;
- if (!index) {
- GetExprKillsByIndirectAssignment(linear);
- } else {
- IROExpr *expr;
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_IsBitSet(index, expr->depends))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- }
- }
- break;
- case IROLinearAsm: {
- IROExpr *expr;
- IRO_GetKills(linear);
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (Bv_BitsInCommon(expr->depends, IRO_VarKills))
- Bv_SetBit(expr->index, IRO_ExprKills);
- }
- break;
- }
- case IROLinearFunccall:
- GetExprKillsByFunctionCall(linear);
- break;
- }
-}
-
-void IRO_ComputeAvail(void) {
- IRONode *node;
- IROLinear *linear;
- SInt32 counter;
- BitVector *bv;
- Boolean flag;
-
- counter = 0;
- node = IRO_FirstNode;
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- Bv_AllocVector(&IRO_ExprKills, IRO_NumExprs + 1);
-
- while (node) {
- Bv_AllocVector(&node->x16, IRO_NumExprs);
- if (node->numpred)
- Bv_Set(node->x16);
- Bv_AllocVector(&node->x22, IRO_NumExprs);
- Bv_AllocVector(&node->x1E, IRO_NumExprs);
- Bv_AllocVector(&node->x1A, IRO_NumExprs);
-
- for (linear = node->first; linear; linear = linear->next) {
- if (linear->expr)
- Bv_SetBit(linear->expr->index, node->x1E);
- IRO_GetExprKills(linear);
- Bv_Or(IRO_ExprKills, node->x22);
- Bv_Minus(IRO_ExprKills, node->x1E);
- if (linear == node->last)
- break;
-
- if (counter > 250) {
- IRO_CheckForUserBreak();
- counter = 0;
- } else {
- counter++;
- }
- }
-
- Bv_Copy(node->x16, node->x1A);
- Bv_Minus(node->x22, node->x1A);
- Bv_Or(node->x1E, node->x1A);
- node = node->nextnode;
- }
-
- IRO_CheckForUserBreak();
-
- Bv_AllocVector(&bv, IRO_NumExprs);
- do {
- flag = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (!node->numpred) {
- Bv_Clear(bv);
- } else {
- UInt16 i;
- Bv_Set(bv);
- for (i = 0; i < node->numpred; i++)
- Bv_And(IRO_NodeTable[node->pred[i]]->x1A, bv);
- }
-
- if (!Bv_Compare(bv, node->x16)) {
- flag = 1;
- Bv_Copy(bv, node->x16);
- }
-
- Bv_Copy(node->x16, node->x1A);
- Bv_Minus(node->x22, node->x1A);
- Bv_Or(node->x1E, node->x1A);
- }
- IRO_CheckForUserBreak();
- } while (flag);
-}
-
-static void IRO_MakeReplacementEmbedded(IROExpr *expr) {
- IROLinear *opnd;
- IROLinear *ind;
- IROLinear *ass;
-
- IRO_GetTemp(expr);
-
- opnd = IRO_NewLinear(IROLinearOperand);
- opnd->u.node = create_objectrefnode(expr->x8);
- opnd->rtype = opnd->u.node->data.objref->type;
- opnd->index = ++IRO_NumLinear;
- opnd->flags |= IROLF_Reffed | IROLF_Assigned | IROLF_Ind;
-
- ind = IRO_NewLinear(IROLinearOp1Arg);
- ind->nodetype = EINDIRECT;
- ind->rtype = expr->linear->rtype;
- ind->u.monadic = opnd;
- ind->index = ++IRO_NumLinear;
- ind->flags |= IROLF_Reffed | IROLF_Assigned;
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->nodetype = EASS;
- ass->u.diadic.left = ind;
- ass->u.diadic.right = expr->linear;
- ass->rtype = expr->linear->rtype;
- ass->index = ++IRO_NumLinear;
-
- opnd->next = ind;
- ind->next = ass;
- IRO_ReplaceReferenceWithNode(expr->linear, ass);
- IRO_PasteAfter(opnd, ass, expr->linear);
-}
-
-static void IRO_ActUnmarkSubExpressions(IROLinear *linear, Boolean isFirst) {
- if (isFirst)
- linear->flags &= ~IROLF_8;
-}
-
-static void CheckCommonSub(IROLinear *linear) {
- IROExpr *expr;
-
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (expr->linear != linear && !expr->x14) {
- if (Bv_IsBitSet(expr->index, IRO_Avail) && !expr->notSubable && IRO_ExprsSame(linear, expr->linear)) {
- IRO_WalkTree(linear, IRO_ActUnmarkSubExpressions);
- linear->flags |= IROLF_8;
- linear->expr->x14 = expr;
- break;
- }
- }
- }
-}
-
-static void MoveCommonSub(IROExpr *expr) {
- SInt32 best;
- SInt32 sz1;
- SInt32 sz2;
- SInt32 i1;
- SInt32 i2;
- IROLinear *scan;
- IROLinear *array1[64];
- IROLinear *array2[64];
- IROExpr *scanexpr;
-
- sz1 = 0;
- scan = expr->linear;
- do {
- scan = IRO_LocateFather(scan);
- if (scan) {
- if (sz1 == 64)
- return;
- array1[sz1++] = scan;
- }
- } while (scan);
-
- best = -1;
- for (scanexpr = IRO_FirstExpr; scanexpr; scanexpr = scanexpr->next) {
- if (scanexpr->x14 == expr) {
- sz2 = 0;
- scan = scanexpr->linear;
- do {
- scan = IRO_LocateFather(scan);
- if (scan) {
- if (sz2 == 64)
- return;
- array2[sz2++] = scan;
- }
- } while (scan);
-
- i1 = sz1;
- i2 = sz2;
- while (i1 && i2 && array1[i1 - 1] == array2[i2 - 1]) {
- i1--;
- i2--;
- }
-
- if (i1 != sz1 && i1 > best)
- best = i1;
- }
- }
-
- if (best < 0) {
- IRO_MakeReplacementEmbedded(expr);
- } else {
- IROLinear *start;
- IROLinear *comma;
- IRO_Dump("Moving common sub from node %d to %d\n", expr->linear->index, array1[best]->index);
- start = IRO_FindStart(array1[best]);
- IRO_GetTemp(expr);
- IRO_ReplaceReference(expr->linear, expr->x8, expr->linear);
- IRO_MoveExpression(expr, start);
-
- comma = IRO_NewLinear(IROLinearOp2Arg);
- comma->nodetype = ECOMMA;
- comma->rtype = array1[best]->rtype;
- comma->u.diadic.left = IRO_AssignToTemp(expr);
- comma->u.diadic.right = array1[best];
- comma->stmt = array1[best]->stmt;
- IRO_ReplaceReferenceWithNode(array1[best], comma);
- IRO_PasteAfter(comma, comma, array1[best]);
- }
-}
-
-static void ReplaceCommonSub(IROLinear *linear) {
- IROExpr *expr = linear->expr->x14;
- if (!expr->x8) {
- MoveCommonSub(expr);
- if (!expr->x8)
- return;
- }
-
- IRO_Dump("Replacing common sub at %d with %d\n", linear->index, expr->linear->index);
- IRO_ReplaceReference(linear, expr->x8, linear);
- IRO_RemoveExpr(linear->expr);
- IRO_NopOut(linear);
-}
-
-void IRO_CommonSubs(void) {
- IRONode *node;
- IROLinear *linear;
- SInt32 counter;
-
- counter = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- IRO_Avail = node->x16;
- linear = node->first;
- while (1) {
- if (!linear)
- break;
- if (linear->expr && !linear->expr->notSubable)
- CheckCommonSub(linear);
- if (linear->expr)
- Bv_SetBit(linear->expr->index, IRO_Avail);
- IRO_GetExprKills(linear);
- Bv_Minus(IRO_ExprKills, IRO_Avail);
- if (linear == node->last)
- break;
- if (counter > 250) {
- IRO_CheckForUserBreak();
- counter = 0;
- } else {
- counter++;
- }
- linear = linear->next;
- }
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- for (linear = node->first; linear; linear = linear->next) {
- if (linear->expr && (linear->flags & IROLF_8) && !IRO_HasSideEffect(linear))
- ReplaceCommonSub(linear);
- if (linear == node->last)
- break;
- if (counter > 250) {
- IRO_CheckForUserBreak();
- counter = 0;
- } else {
- counter++;
- }
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean CountThisSubableOperandUse(IROUse *use) {
- return use->x1C != 0;
-}
-
-static int GetSubableOperandUseCount(VarRecord *var) {
- int count = 0;
- IROUse *use;
-
- if (var->uses) {
- for (use = var->uses; use; use = use->varnext) {
- if (CountThisSubableOperandUse(use))
- count++;
- }
- }
-
- return count;
-}
-
-static void IRO_MakeTopLevelExprForSubableOperand(IROLinear *linear) {
- IROLinear *copy = IRO_NewLinear(IROLinearOperand);
- memcpy(copy, linear, sizeof(IROLinear));
- copy->index = ++IRO_NumLinear;
-
- if (IRO_FirstLinear && IRO_FirstLinear->type == IROLinearNop)
- IRO_PasteAfter(copy, copy, IRO_FirstLinear);
- else
- IRO_Paste(copy, copy, IRO_FirstLinear);
-}
-
-void IRO_GenerateTopLevelExprsForSubableOperands(void) {
- IROLinear *nd;
- IRONode *fnode;
- VarRecord *var;
- BitVector *bv;
-
- Bv_AllocVector(&bv, IRO_NumVars + 1);
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- for (nd = fnode->first; nd; nd = nd->next) {
- nd->expr = NULL;
- if ((nd->flags & IROLF_Reffed) && IRO_IsSubableExpression(nd) && IRO_DoesNotHaveVectorOperand(nd)) {
- if (nd->type == IROLinearOperand && nd->u.node && nd->u.node->type == EOBJREF) {
- if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 1))) {
- if (!Bv_IsBitSet(var->index, bv)) {
- IRO_MakeTopLevelExprForSubableOperand(nd);
- Bv_SetBit(var->index, bv);
- }
- }
- }
- }
-
- if (nd == fnode->last)
- break;
- }
- }
-}
diff --git a/compiler_and_linker/unsorted/IroDump.c b/compiler_and_linker/unsorted/IroDump.c
deleted file mode 100644
index e7ca940..0000000
--- a/compiler_and_linker/unsorted/IroDump.c
+++ /dev/null
@@ -1,660 +0,0 @@
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroPropagate.h"
-#include "compiler/IroUtil.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/objects.h"
-#include "compiler/IroVars.h"
-#include "compiler/IroCSE.h"
-
-static FILE *DumpFile;
-static char *nodenames[MAXEXPR];
-
-char *IRO_NodeName(ENodeType nodetype) {
- return nodenames[nodetype];
-}
-
-void IRO_InitializeNodeNamesArray(void) {
- int i;
- for (i = 0; i < MAXEXPR; i++)
- nodenames[i] = "";
-
- nodenames[EPOSTINC] = "EPOSTINC";
- nodenames[EPOSTDEC] = "EPOSTDEC";
- nodenames[EPREINC] = "EPREINC";
- nodenames[EPREDEC] = "EPREDEC";
- nodenames[EINDIRECT] = "EINDIRECT";
- nodenames[EMONMIN] = "EMONMIN";
- nodenames[EBINNOT] = "EBINNOT";
- nodenames[ELOGNOT] = "ELOGNOT";
- nodenames[EFORCELOAD] = "EFORCELOAD";
- nodenames[EMUL] = "EMUL";
- nodenames[EMULV] = "EMULV";
- nodenames[EDIV] = "EDIV";
- nodenames[EMODULO] = "EMODULO";
- nodenames[EADDV] = "EADDV";
- nodenames[ESUBV] = "ESUBV";
- nodenames[EADD] = "EADD";
- nodenames[ESUB] = "ESUB";
- nodenames[ESHL] = "ESHL";
- nodenames[ESHR] = "ESHR";
- nodenames[ELESS] = "ELESS";
- nodenames[EGREATER] = "EGREATER";
- nodenames[ELESSEQU] = "ELESSEQU";
- nodenames[EGREATEREQU] = "EGREATEREQU";
- nodenames[EEQU] = "EEQU";
- nodenames[ENOTEQU] = "ENOTEQU";
- nodenames[EAND] = "EAND";
- nodenames[EXOR] = "EXOR";
- nodenames[EOR] = "EOR";
- nodenames[ELAND] = "ELAND";
- nodenames[ELOR] = "ELOR";
- nodenames[EASS] = "EASS";
- nodenames[EMULASS] = "EMULASS";
- nodenames[EDIVASS] = "EDIVASS";
- nodenames[EMODASS] = "EMODASS";
- nodenames[EADDASS] = "EADDASS";
- nodenames[ESUBASS] = "ESUBASS";
- nodenames[ESHLASS] = "ESHLASS";
- nodenames[ESHRASS] = "ESHRASS";
- nodenames[EANDASS] = "EANDASS";
- nodenames[EXORASS] = "EXORASS";
- nodenames[EORASS] = "EORASS";
- nodenames[ECOMMA] = "ECOMMA";
- nodenames[EPMODULO] = "EPMODULO";
- nodenames[EROTL] = "EROTL";
- nodenames[EROTR] = "EROTR";
- nodenames[EBCLR] = "EBCLR";
- nodenames[EBTST] = "EBTST";
- nodenames[EBSET] = "EBSET";
- nodenames[ETYPCON] = "ETYPCON";
- nodenames[EBITFIELD] = "EBITFIELD";
- nodenames[EINTCONST] = "EINTCONST";
- nodenames[EFLOATCONST] = "EFLOATCONST";
- nodenames[ESTRINGCONST] = "ESTRINGCONST";
- nodenames[ECOND] = "ECOND";
- nodenames[EFUNCCALL] = "EFUNCCALL";
- nodenames[EFUNCCALLP] = "EFUNCCALLP";
- nodenames[EOBJREF] = "EOBJREF";
- nodenames[EMFPOINTER] = "EMFPOINTER";
- nodenames[ENULLCHECK] = "ENULLCHECK";
- nodenames[EPRECOMP] = "EPRECOMP";
- nodenames[ETEMP] = "ETEMP";
- nodenames[EARGOBJ] = "EARGOBJ";
- nodenames[ELOCOBJ] = "ELOCOBJ";
- nodenames[ELABEL] = "ELABEL";
- nodenames[ESETCONST] = "ESETCONST";
- nodenames[ENEWEXCEPTION] = "ENEWEXCEPTION";
- nodenames[ENEWEXCEPTIONARRAY] = "ENEWEXCEPTIONARRAY";
- nodenames[EOBJLIST] = "EOBJLIST";
- nodenames[EMEMBER] = "EMEMBER";
- nodenames[ETEMPLDEP] = "ETEMPLDEP";
- nodenames[EINSTRUCTION] = "EINSTRUCTION";
- nodenames[EDEFINE] = "EDEFINE";
- nodenames[EREUSE] = "EREUSE";
- nodenames[EASSBLK] = "EASSBLK";
- nodenames[EVECTOR128CONST] = "EVECTOR128CONST";
- nodenames[ECONDASS] = "ECONDASS";
-}
-
-static void DumpENode(ENode *enode) {
- char buf[64];
-
- if (IRO_Log) {
- switch (enode->type) {
- case EOBJREF:
- fprintf(DumpFile, "%s", enode->data.objref->name->name);
- break;
- case EINTCONST:
- CInt64_PrintDec(buf, enode->data.intval);
- fprintf(DumpFile, "%s", buf);
- break;
- case EFLOATCONST:
- fprintf(DumpFile, "%g", enode->data.floatval.value);
- break;
- case EVECTOR128CONST:
- fprintf(DumpFile, "%.8lX%.8lX%.8lX%.8lX",
- enode->data.vector128val.ul[0],
- enode->data.vector128val.ul[1],
- enode->data.vector128val.ul[2],
- enode->data.vector128val.ul[3]
- );
- break;
- }
- }
-}
-
-static void DumpLinearNode(IROLinear *linear) {
- int i;
-
- if (IRO_Log) {
- fprintf(DumpFile, "%4d: ", linear->index);
- switch (linear->type) {
- case IROLinearNop:
- fprintf(DumpFile, "Nop");
- break;
- case IROLinearOperand:
- fprintf(DumpFile, "Operand ");
- DumpENode(linear->u.node);
- break;
- case IROLinearOp1Arg:
- fprintf(DumpFile, "%s %d", nodenames[linear->nodetype], linear->u.monadic->index);
- break;
- case IROLinearOp2Arg:
- fprintf(DumpFile, "%s %d %d", nodenames[linear->nodetype], linear->u.diadic.left->index, linear->u.diadic.right->index);
- break;
- case IROLinearGoto:
- fprintf(DumpFile, "Goto %s", linear->u.label.label->name->name);
- break;
- case IROLinearIf:
- fprintf(DumpFile, "If %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
- break;
- case IROLinearIfNot:
- fprintf(DumpFile, "IfNot %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
- break;
- case IROLinearReturn:
- fprintf(DumpFile, "Return ");
- if (linear->u.monadic)
- fprintf(DumpFile, "%d", linear->u.monadic->index);
- break;
- case IROLinearLabel:
- fprintf(DumpFile, "Label %s", linear->u.label.label->name->name);
- break;
- case IROLinearSwitch:
- fprintf(DumpFile, "Switch %d", linear->u.swtch.x4->index);
- break;
- case IROLinearOp3Arg:
- fprintf(DumpFile, "%s %d %d %d",
- nodenames[linear->nodetype],
- linear->u.args3.a->index,
- linear->u.args3.b->index,
- linear->u.args3.c->index);
- break;
- case IROLinearFunccall:
- fprintf(DumpFile, "Funccall %d(", linear->u.funccall.linear8->index);
- for (i = 0; i < linear->u.funccall.argCount; i++) {
- fprintf(DumpFile, "%d", linear->u.funccall.args[i]->index);
- if (i < (linear->u.funccall.argCount - 1))
- fprintf(DumpFile, ",");
- }
- fprintf(DumpFile, ")");
- break;
- case IROLinearBeginCatch:
- fprintf(DumpFile, "BeginCatch %d", linear->u.ctch.linear->index);
- break;
- case IROLinearEndCatch:
- fprintf(DumpFile, "EndCatch %d", linear->u.monadic->index);
- break;
- case IROLinearEndCatchDtor:
- fprintf(DumpFile, "EndCatchDtor %d", linear->u.monadic->index);
- break;
- case IROLinearEnd:
- fprintf(DumpFile, "End");
- break;
- }
-
- if (linear->flags & IROLF_Assigned) fprintf(DumpFile, " <assigned>");
- if (linear->flags & IROLF_Used) fprintf(DumpFile, " <used>");
- if (linear->flags & IROLF_Ind) fprintf(DumpFile, " <ind>");
- if (linear->flags & IROLF_Subs) fprintf(DumpFile, " <subs>");
- if (linear->flags & IROLF_LoopInvariant) fprintf(DumpFile, " <loop invariant>");
- if (linear->flags & IROLF_BeginLoop) fprintf(DumpFile, " <begin loop>");
- if (linear->flags & IROLF_EndLoop) fprintf(DumpFile, " <end loop>");
- if (linear->flags & IROLF_Ris) fprintf(DumpFile, " <ris>");
- if (linear->flags & IROLF_Immind) fprintf(DumpFile, " <immind>");
- if (linear->flags & IROLF_Reffed) fprintf(DumpFile, " <reffed>");
- if (linear->flags & IROLF_VecOp) fprintf(DumpFile, " <vec op>");
- if (linear->flags & IROLF_VecOpBase) fprintf(DumpFile, " <vec op_base>");
- if (linear->flags & IROLF_CounterLoop) fprintf(DumpFile, " <counter loop>");
- if (linear->flags & IROLF_BitfieldIndirect) fprintf(DumpFile, " <bitfield_indirect>");
- if (linear->flags & IROLF_CouldError) fprintf(DumpFile, " <could_error>");
-
- if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS))
- fprintf(DumpFile, " <volatile>");
-
- if (IS_LINEAR_ENODE(linear, EOBJREF)) {
- VarRecord *var = IRO_FindVar(linear->u.node->data.objref, 0, 1);
- if (var && is_volatile_object(var->object))
- fprintf(DumpFile, " <volatile obj>");
- }
-
- fprintf(DumpFile, "\n");
- }
-}
-
-static void DumpAct(IROLinear *linear, Boolean isFirst) {
- if (!isFirst)
- DumpLinearNode(linear);
-}
-
-void IRO_DumpIntTree(IROLinear *linear) {
- IRO_WalkTree(linear, DumpAct);
-}
-
-void IRO_DumpLinearList(IROLinear *linear) {
- if (!IRO_Log)
- return;
-
- while (linear) {
- DumpLinearNode(linear);
- linear = linear->next;
- }
- fprintf(DumpFile, "\n");
-}
-
-static void DumpList(int num, UInt16 *list) {
- int i;
-
- if (IRO_Log) {
- for (i = 0; i < num; i++)
- fprintf(DumpFile, "%d ", list[i]);
- fprintf(DumpFile, "\n");
- }
-}
-
-void IRO_DumpBits(char *name, BitVector *bv) {
- SInt32 i;
- SInt32 rangeStart;
- Boolean inRange = 0;
- Boolean isFirst = 1;
-
- if (!IRO_Log)
- return;
-
- fprintf(DumpFile, name);
- if (!bv) {
- fprintf(DumpFile, "NULL");
- } else {
- for (i = 0; i < (bv->size * 32); i++) {
- if (Bv_IsBitSet(i, bv)) {
- if (!inRange) {
- if (!isFirst)
- fputc(',', DumpFile);
- isFirst = 0;
- fprintf(DumpFile, "%d", i);
- inRange = 1;
- rangeStart = i;
- }
- } else {
- if (inRange) {
- inRange = 0;
- if (i != (rangeStart + 1))
- fprintf(DumpFile, "-%d", i - 1);
- }
- }
- }
-
- if (inRange && i != (rangeStart + 1))
- fprintf(DumpFile, "-%d", i - 1);
- }
-
- fprintf(DumpFile, "\n");
-}
-
-void IRO_DumpAfterPhase(char *str, Boolean flag) {
-#ifdef CW_ENABLE_IRO_DEBUG
- if (copts.debuglisting)
- flag = 1;
-#endif
- if (flag) {
- IRO_Dump("Dumping function %s after %s \n", FunctionName ? FunctionName->name->name : "Init-code", str);
- IRO_Dump("--------------------------------------------------------------------------------\n");
- IRO_DumpFlowgraph();
- }
-}
-
-void IRO_LogForFunction(char *name) {
- if (FunctionName) {
- if (!strcmp(FunctionName->name->name, name))
- IRO_Log = 1;
- else
- IRO_Log = 0;
- }
-}
-
-void IRO_DumpFlowgraph(void) {
- IRONode *node;
- IROLinear *linear;
-
- if (IRO_Log && DumpFile) {
- fprintf(DumpFile, "\nFlowgraph\n");
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index, node->last->index);
-
- fprintf(DumpFile, "Succ = ");
- DumpList(node->numsucc, node->succ);
- fprintf(DumpFile, "Pred = ");
- DumpList(node->numpred, node->pred);
-
- fprintf(DumpFile, "MustReach = %d, MustReach1=%d\n", node->mustreach, node->mustreach1);
- fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
-
- IRO_DumpBits("Dom: ", node->dom);
- if ((linear = node->first)) {
- while (1) {
- DumpLinearNode(linear);
- if (linear == node->last)
- break;
- linear = linear->next;
- }
- }
-
- fprintf(DumpFile, "\n\n");
- }
- fprintf(DumpFile, "\n");
- fflush(DumpFile);
- }
-}
-
-void IRO_DumpNode(IRONode *node) {
- IROLinear *linear;
-
- if (IRO_Log) {
- if (!DumpFile)
- return;
-
- while (node) {
- fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index,
- node->last->index);
-
- fprintf(DumpFile, "Succ = ");
- DumpList(node->numsucc, node->succ);
- fprintf(DumpFile, "Pred = ");
- DumpList(node->numpred, node->pred);
-
- fprintf(DumpFile, "MustReach = %d MustReach1 = %d\n", node->mustreach, node->mustreach1);
- fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
-
- IRO_DumpBits("Dom: ", node->dom);
- if ((linear = node->first)) {
- while (1) {
- DumpLinearNode(linear);
- if (linear == node->last)
- break;
- linear = linear->next;
- }
- }
-
- fprintf(DumpFile, "\n\n");
- node = node->nextnode;
- }
-
- fprintf(DumpFile, "\n");
- fflush(DumpFile);
- }
-}
-
-void IRO_DumpAssignments(void) {
- IROAssign *assign;
-
- if (IRO_Log) {
- fprintf(DumpFile, "\nAssignments\n\n");
- for (assign = IRO_FirstAssign; assign; assign = assign->next) {
- fprintf(DumpFile, "%5d ", assign->index);
- DumpLinearNode(assign->linear);
- fprintf(DumpFile, "\n");
- }
- fprintf(DumpFile, "\n");
- }
-}
-
-void IRO_DumpVars(void) {
- VarRecord *var;
-
- if (IRO_Log) {
- fprintf(DumpFile, "\nVariables\n");
- for (var = IRO_FirstVar; var; var = var->next) {
- fprintf(DumpFile, "%5d %s %s\n", var->index, var->object->name->name, var->xB ? "<addressed>" : "");
- }
- fprintf(DumpFile, "\n");
- }
-}
-
-void IRO_DumpDf(void) {
- IRONode *node;
-
- if (IRO_Log) {
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- fprintf(DumpFile, "Node %d\n", node->index);
- if (node->x16) IRO_DumpBits("In: ", node->x16);
- if (node->x1E) IRO_DumpBits("Gen: ", node->x1E);
- if (node->x22) IRO_DumpBits("Kill: ", node->x22);
- if (node->x1A) IRO_DumpBits("Out: ", node->x1A);
- if (node->x2A) IRO_DumpBits("AA: ", node->x2A);
- fprintf(DumpFile, "\n");
- }
- fprintf(DumpFile, "\n");
- }
-}
-
-void IRO_DumpExprs(void) {
- IROExpr *expr;
-
- if (IRO_Log) {
- fprintf(DumpFile, "Expressions\n\n");
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- fprintf(DumpFile, "%4d: %d FN:%d CE:%d NS:%d ", expr->index, expr->linear->index, expr->node->index, expr->couldError, expr->notSubable);
- IRO_DumpBits("Depends: ", expr->depends);
- fprintf(DumpFile, "\n");
- }
- fprintf(DumpFile, "\n");
- }
-}
-
-void IRO_SetupDump(void) {
-#ifdef CW_ENABLE_IRO_DEBUG
- IRO_Log = 1;
-#endif
-
- if (IRO_Log) {
- if ((DumpFile = fopen("OPT.LOG", "wt")) == NULL)
- IRO_Log = 0;
- }
-}
-
-void IRO_CleanupDump(void) {
- if (DumpFile)
- fclose(DumpFile);
-}
-
-void IRO_Dump(char *format, ...) {
- va_list va;
- if (IRO_Log) {
- va_start(va, format);
- vfprintf(DumpFile, format, va);
- va_end(va);
- }
-}
-
-void IRO_DumpAddr(IROAddrRecord *rec) {
- IROElmList *list;
-
- if (IRO_Log && DumpFile) {
- fprintf(DumpFile, "\n");
- fprintf(DumpFile, "Address :\n");
- IRO_DumpIntTree(rec->linear);
- fprintf(DumpFile, "\n");
- fprintf(DumpFile, "BaseTerms:\n");
- for (list = rec->objRefs; list; list = list->next) {
- IRO_DumpIntTree(list->element);
- fprintf(DumpFile, "\n");
- }
- fprintf(DumpFile, "VarTerms:\n");
- for (list = rec->misc; list; list = list->next) {
- IRO_DumpIntTree(list->element);
- fprintf(DumpFile, "\n");
- }
- fprintf(DumpFile, "ConstTerms:\n");
- for (list = rec->ints; list; list = list->next) {
- IRO_DumpIntTree(list->element);
- fprintf(DumpFile, "\n");
- }
- }
-}
-
-static void IRO_DumpType(Type *type) {
- char buf[256];
- IRO_SpellType(type, buf);
- fprintf(DumpFile, " (%s)", buf);
-}
-
-void IRO_SpellType(Type *type, char *buf) {
- char mybuf[256];
- char mybuf2[256];
-
- switch (type->type) {
- case TYPEVOID:
- strcpy(buf, "void");
- break;
- case TYPEINT:
- switch (TYPE_INTEGRAL(type)->integral) {
- case IT_BOOL:
- strcpy(buf, "bool");
- break;
- case IT_CHAR:
- strcpy(buf, "char");
- break;
- case IT_WCHAR_T:
- strcpy(buf, "wchar_t");
- break;
- case IT_SCHAR:
- strcpy(buf, "signed char");
- break;
- case IT_UCHAR:
- strcpy(buf, "unsigned char");
- break;
- case IT_SHORT:
- strcpy(buf, "short");
- break;
- case IT_USHORT:
- strcpy(buf, "unsigned short");
- break;
- case IT_INT:
- strcpy(buf, "int");
- break;
- case IT_UINT:
- strcpy(buf, "unsigned int");
- break;
- case IT_LONG:
- strcpy(buf, "long");
- break;
- case IT_ULONG:
- strcpy(buf, "unsigned long");
- break;
- case IT_LONGLONG:
- strcpy(buf, "long long");
- break;
- case IT_ULONGLONG:
- strcpy(buf, "unsigned long long");
- break;
- }
- break;
- case TYPEFLOAT:
- switch (TYPE_INTEGRAL(type)->integral) {
- case IT_FLOAT:
- strcpy(buf, "float");
- break;
- case IT_SHORTDOUBLE:
- strcpy(buf, "short double");
- break;
- case IT_DOUBLE:
- strcpy(buf, "double");
- break;
- case IT_LONGDOUBLE:
- strcpy(buf, "long double");
- break;
- }
- break;
- case TYPEENUM:
- strcpy(buf, "enum ");
- if (TYPE_ENUM(type)->enumname)
- strcat(buf, TYPE_ENUM(type)->enumname->name);
- break;
- case TYPESTRUCT:
- if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) {
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- strcpy(buf, "vector unsigned char ");
- break;
- case STRUCT_VECTOR_SCHAR:
- strcpy(buf, "vector signed char ");
- break;
- case STRUCT_VECTOR_BCHAR:
- strcpy(buf, "vector bool char ");
- break;
- case STRUCT_VECTOR_USHORT:
- strcpy(buf, "vector unsigned short ");
- break;
- case STRUCT_VECTOR_SSHORT:
- strcpy(buf, "vector signed short ");
- break;
- case STRUCT_VECTOR_BSHORT:
- strcpy(buf, "vector bool short ");
- break;
- case STRUCT_VECTOR_UINT:
- strcpy(buf, "vector unsigned long ");
- break;
- case STRUCT_VECTOR_SINT:
- strcpy(buf, "vector signed long ");
- break;
- case STRUCT_VECTOR_BINT:
- strcpy(buf, "vector bool long ");
- break;
- case STRUCT_VECTOR_FLOAT:
- strcpy(buf, "vector float ");
- break;
- case STRUCT_VECTOR_PIXEL:
- strcpy(buf, "vector pixel ");
- break;
- }
- } else {
- strcpy(buf, "struct ");
- }
- if (TYPE_STRUCT(type)->name)
- strcat(buf, TYPE_STRUCT(type)->name->name);
- break;
- case TYPECLASS:
- strcpy(buf, "class ");
- if (TYPE_CLASS(type)->classname)
- strcat(buf, TYPE_CLASS(type)->classname->name);
- break;
- case TYPEFUNC:
- IRO_SpellType(TYPE_FUNC(type)->functype, mybuf);
- strcpy(buf, "freturns(");
- strcat(buf, mybuf);
- strcat(buf, ")");
- break;
- case TYPEBITFIELD:
- IRO_SpellType(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
- sprintf(buf, "bitfield(%s){%d:%d}", mybuf, TYPE_BITFIELD(type)->offset, TYPE_BITFIELD(type)->bitlength);
- break;
- case TYPELABEL:
- strcpy(buf, "label");
- break;
- case TYPEPOINTER:
- IRO_SpellType(TPTR_TARGET(type), mybuf);
- strcpy(buf, "pointer(");
- strcat(buf, mybuf);
- strcat(buf, ")");
- break;
- case TYPEARRAY:
- IRO_SpellType(TPTR_TARGET(type), mybuf);
- strcpy(buf, "array(");
- strcat(buf, mybuf);
- strcat(buf, ")");
- break;
- case TYPEMEMBERPOINTER:
- IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
- IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
- strcpy(buf, "memberpointer(");
- strcat(buf, mybuf);
- strcat(buf, ",");
- strcat(buf, mybuf2);
- strcat(buf, ")");
- break;
- }
-}
-
diff --git a/compiler_and_linker/unsorted/IroEmptyLoop.c b/compiler_and_linker/unsorted/IroEmptyLoop.c
deleted file mode 100644
index 1e319ab..0000000
--- a/compiler_and_linker/unsorted/IroEmptyLoop.c
+++ /dev/null
@@ -1,560 +0,0 @@
-#include "compiler/IroEmptyLoop.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroLoop.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CInt64.h"
-
-// forward decls
-static Boolean EmptyLoop(IRONode *fnode);
-static int CanRemoveRedundantLoop(IROLoop *loop);
-static int CanRemoveRedundantLoop1(IROLoop *loop);
-static int RedundantLoopCheck(IROLoop *loop);
-static int CheckStepOverFlow1_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val2);
-static int CheckStepOverFlow2_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val2);
-
-void IRO_FindEmptyLoops(void) {
- IRONode *fnode;
- IRONode *pred;
- UInt16 i;
- UInt16 x;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- x = 0;
- for (i = 0; i < fnode->numpred; i++) {
- pred = IRO_NodeTable[fnode->pred[i]];
- if (Bv_IsBitSet(fnode->index, pred->dom)) {
- if (!x) {
- Bv_AllocVector(&InLoop, IRO_NumNodes + 1);
- Bv_Clear(InLoop);
- Bv_SetBit(fnode->index, InLoop);
- }
- x = 1;
- Bv_SetBit(pred->index, InLoop);
- if (pred != fnode)
- AddPreds(pred);
- }
- }
-
- if (x) {
- IRO_Dump("IRO_FindEmptyLoops:Found loop with header %d\n", fnode->index);
- IRO_DumpBits("Loop includes: ", InLoop);
- EmptyLoop(fnode);
- IRO_UpdateFlagsOnInts();
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean EmptyLoop(IRONode *fnode) {
- VarRecord *var;
- IRONode *bestpred;
- IRONode *pred;
- UInt16 i;
- int flag2;
- IRONode *r24;
- Boolean flag;
- int counter;
- int j;
- IRONode *succ;
- IRONode *bestsucc;
- int counter2;
- UInt32 counter3;
- IROLoop *loop;
- IRONode *r21;
- IRONode *r20;
- IROLinear *constnd;
- Type *type20;
- ENode *enode;
- IROLinear *save;
-
- flag = 0;
- counter = 0;
- LoopNode = fnode;
- FindMustReach();
-
- for (var = IRO_FirstVar; var; var = var->next)
- var->xA = 1;
-
- ComputeLoopKills();
- ComputeLoopInvariance();
- ComputeLoopInduction();
-
- LoopNode = fnode;
- ConditionalHeaderAtBottom = 0;
-
- bestpred = NULL;
- flag2 = 0;
- for (i = 0; i < LoopNode->numpred; i++) {
- pred = IRO_NodeTable[LoopNode->pred[i]];
- if (!Bv_IsBitSet(pred->index, InLoop)) {
- flag2 = 1;
- if (pred->nextnode == fnode) {
- CError_ASSERT(173, !bestpred || pred == bestpred);
- bestpred = pred;
- }
- }
- }
-
- if (!flag2) {
- IRO_Dump("No predecessor outside the loop\n");
- return 0;
- }
-
- bestsucc = NULL;
- for (i = 0; i < LoopNode->numsucc; i++) {
- succ = IRO_NodeTable[LoopNode->succ[i]];
- if (Bv_IsBitSet(succ->index, InLoop)) {
- bestsucc = succ;
- counter++;
- }
- }
-
- if (LoopNode == bestsucc && counter == 1)
- flag = 1;
-
- if (LoopNode->last->type != IROLinearIf || LoopNode->last->type != IROLinearIfNot || flag) {
- counter2 = 0;
- for (j = 0; j < LoopNode->numpred; j++) {
- if (Bv_IsBitSet(IRO_NodeTable[LoopNode->pred[j]]->index, InLoop)) {
- r21 = IRO_NodeTable[LoopNode->pred[j]];
- counter2++;
- }
- }
-
- r24 = NULL;
- counter3 = 0;
- for (j = 0; j < LoopNode->numpred; j++) {
- if (!Bv_IsBitSet(IRO_NodeTable[LoopNode->pred[j]]->index, InLoop)) {
- r24 = IRO_NodeTable[LoopNode->pred[j]];
- counter3++;
- }
- }
-
- if (counter2 == 1 && counter3 == 1) {
- if (r21->last->type == IROLinearIf) {
- if ((Bv_IsBitSet(LoopNode->nextnode->index, InLoop) && !Bv_IsBitSet(r21->nextnode->index, InLoop)) || flag) {
- IRO_Dump("Standard while loop layout\n");
- loop = ExtractLoopInfo(r21);
- if (flag)
- loop->flags |= LoopFlags_20000;
- FindAssignmenttoInductionVar(loop, r24);
- r20 = r24;
- while (r20 && !loop->nd14 && r20->numpred == 1 && IRO_NodeTable[r20->pred[0]]->numsucc == 1) {
- FindAssignmenttoInductionVar(loop, IRO_NodeTable[r20->pred[0]]);
- r20 = IRO_NodeTable[r20->pred[0]];
- }
-
- if (CanRemoveRedundantLoop(loop)) {
- IRO_Dump("EmptyLoop: # of iterations =%" PRId32 ", FinalStoreVal=%" PRId32 "\n", CInt64_GetULong(&loop->x28), CInt64_GetULong(&loop->x30));
- IRO_NopOut(r21->last->u.label.x4);
- r21->last->type = IROLinearNop;
- type20 = loop->induction->nd->rtype;
- constnd = IRO_NewLinear(IROLinearOperand);
- constnd->index = ++IRO_NumLinear;
- enode = IRO_NewENode(EINTCONST);
- enode->rtype = type20;
- enode->data.intval = loop->x30;
- constnd->u.node = enode;
- constnd->rtype = type20;
-
- if (loop->induction->nd->type == IROLinearOp1Arg) {
- save = loop->induction->nd->u.monadic;
- loop->induction->nd->type = IROLinearOp2Arg;
- loop->induction->nd->nodetype = EASS;
- loop->induction->nd->u.diadic.left = save;
- loop->induction->nd->u.diadic.right = constnd;
- IRO_Paste(constnd, constnd, loop->induction->nd);
- } else if (loop->induction->nd->type == IROLinearOp2Arg) {
- loop->induction->nd->nodetype = EASS;
- IRO_NopOut(loop->induction->nd->u.diadic.right);
- loop->induction->nd->u.diadic.right = constnd;
- IRO_Paste(constnd, constnd, loop->induction->nd);
- }
- } else if (CanRemoveRedundantLoop1(loop)) {
- IRO_Dump("EmptyLoop: self recursive dowhile(--n ) loop\n");
-
- r21->last->type = IROLinearNop;
- type20 = loop->induction->nd->rtype;
- constnd = IRO_NewLinear(IROLinearOperand);
- constnd->index = ++IRO_NumLinear;
- enode = IRO_NewENode(EINTCONST);
- enode->rtype = type20;
- enode->data.intval = cint64_zero;
- constnd->u.node = enode;
- constnd->rtype = type20;
-
- save = loop->induction->nd->u.monadic;
- loop->induction->nd->type = IROLinearOp2Arg;
- loop->induction->nd->nodetype = EASS;
- loop->induction->nd->u.diadic.left = save;
- loop->induction->nd->u.diadic.right = constnd;
- IRO_Paste(constnd, constnd, loop->induction->nd);
- }
- } else {
- IRO_Dump("NonStandard while loop layout\n");
- }
- } else {
- IRO_Dump("NonStandard while loop layout\n");
- }
- } else {
- IRO_Dump("Cannot handle Do While Loop with multiple tails\n");
- }
- }
-
- return 0;
-}
-
-static int CanRemoveRedundantLoop(IROLoop *loop) {
- IROLinear *inner;
-
- if (loop->flags & LoopFlags_10000) {
- IRO_Dump("CanRemoveRedundantLoop:No because detection of dowhile(n--) loop not supported\n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HAS_ASM) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_LOOP_HAS_ASM \n");
- return 0;
- }
-
- if (loop->flags & LP_IFEXPR_NON_CANONICAL) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_IFEXPR_NON_CANONICAL \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HAS_CALLS) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_LOOP_HAS_CALLS \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HAS_CNTRLFLOW) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_LOOP_HAS_CNTRLFLOW \n");
- return 0;
- }
-
- if (loop->flags & LP_INDUCTION_NOT_FOUND) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_INDUCTION_NOT_FOUND \n");
- return 0;
- }
-
- if (loop->flags & LP_HAS_MULTIPLE_INDUCTIONS) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_HAS_MULTIPLE_INDUCTIONS \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HDR_HAS_SIDEEFFECTS) {
- IRO_Dump("CanRemoveRedundantLoop:No due to LP_LOOP_HDR_HAS_SIDEEFFECTS \n");
- return 0;
- }
-
- if (!(loop->flags & LoopFlags_200)) {
- IRO_Dump("CanRemoveRedundantLoop:No because header does not follow induction update \n");
- return 0;
- }
-
- if (!(loop->flags & LoopFlags_10000)) {
- inner = loop->nd18->u.diadic.right;
- if (!IRO_IsIntConstant(inner) && !(inner->flags & IROLF_LoopInvariant)) {
- IRO_Dump("CanRemoveRedundantLoop:No because Loop Upper Bound is Variant in the loop\n");
- return 0;
- }
-
- if (!loop->nd14) {
- IRO_Dump("CanRemoveRedundantLoop:No because there is no initialization of loop index in PreHeader\n");
- return 0;
- }
-
- if (!IRO_IsVariable(loop->nd14->u.diadic.left)) {
- IRO_Dump("CanRemoveRedundantLoop:No because initial value of induction stored thru pointer\n");
- return 0;
- }
-
- if (!IRO_IsUnsignedType(loop->nd14->rtype)) {
- if (IRO_IsIntConstant(loop->nd14->u.diadic.right)) {
- if (!CInt64_GreaterEqual(loop->nd14->u.diadic.right->u.node->data.intval, cint64_zero)) {
- IRO_Dump("CanRemoveRedundantLoop:No because initial value of induction is signed but < 0\n");
- return 0;
- }
- } else {
- IRO_Dump("CanRemoveRedundantLoop:No because initial value of induction is signed and not constant\n");
- return 0;
- }
- }
-
- if (!(loop->flags & LP_LOOP_STEP_ISPOS) && !(loop->flags & LP_LOOP_STEP_ISNEG)) {
- IRO_Dump("CanRemoveRedundantLoop:No because LP_LOOP_STEP_ISPOS/LP_LOOP_STEP_ISNEG is not set\n");
- return 0;
- }
-
- if ((loop->flags & LP_LOOP_STEP_ISPOS) && CheckStepOverFlow1_EmptyLoop(loop, &loop->x28, &loop->x30)) {
- IRO_Dump("CanRemoveRedundantLoop:No because Final Value of indution will overflow\n");
- return 0;
- }
-
- if ((loop->flags & LP_LOOP_STEP_ISNEG) && CheckStepOverFlow2_EmptyLoop(loop, &loop->x28, &loop->x30)) {
- IRO_Dump("CanRemoveRedundantLoop:No because Final Value of indution will overflow\n");
- return 0;
- }
- }
-
- return RedundantLoopCheck(loop) != 0;
-}
-
-static int CanRemoveRedundantLoop1(IROLoop *loop) {
- if ((loop->flags & LoopFlags_10000) && (loop->flags & LoopFlags_20000)) {
- if (loop->flags & LP_LOOP_HAS_ASM) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_LOOP_HAS_ASM \n");
- return 0;
- }
-
- if (loop->flags & LP_IFEXPR_NON_CANONICAL) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_IFEXPR_NON_CANONICAL \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HAS_CALLS) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_LOOP_HAS_CALLS \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HAS_CNTRLFLOW) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_LOOP_HAS_CNTRLFLOW \n");
- return 0;
- }
-
- if (loop->flags & LP_INDUCTION_NOT_FOUND) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_INDUCTION_NOT_FOUND \n");
- return 0;
- }
-
- if (loop->flags & LP_HAS_MULTIPLE_INDUCTIONS) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_HAS_MULTIPLE_INDUCTIONS \n");
- return 0;
- }
-
- if (loop->flags & LP_LOOP_HDR_HAS_SIDEEFFECTS) {
- IRO_Dump("CanRemoveRedundantLoop1:No due to LP_LOOP_HDR_HAS_SIDEEFFECTS \n");
- return 0;
- }
-
- if (!(loop->flags & LoopFlags_200)) {
- IRO_Dump("CanRemoveRedundantLoop1:No because header does not follow induction update \n");
- return 0;
- }
-
- if (loop->induction->nd->type == IROLinearOp1Arg && loop->induction->nd->nodetype == EPREDEC) {
- if (IRO_IsUnsignedType(loop->induction->nd->rtype))
- return 1;
- IRO_Dump("CanRemoveRedundantLoop1:No because induction not of the right type \n");
- return 0;
- }
-
- IRO_Dump("CanRemoveRedundantLoop1:No because induction operator not a predec \n");
- return 0;
- } else {
- return 0;
- }
-}
-
-static int RedundantLoopCheck(IROLoop *loop) {
- IRONode *fnode;
- IROLinear *nd;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop) && fnode != loop->fnode && (nd = fnode->first)) {
- while (1) {
- if ((nd->index < loop->index20 || nd->index > loop->index24) && nd->type != IROLinearNop && nd->type != IROLinearLabel) {
- if (IS_LINEAR_DIADIC(nd, EASS)) {
- if (!(nd->flags & IROLF_Reffed)) {
- if (IS_LINEAR_MONADIC(nd->u.diadic.left, EINDIRECT)) {
- if (nd->u.diadic.left->rtype && CParser_IsVolatile(nd->u.diadic.left->rtype, nd->u.diadic.left->nodeflags & ENODE_FLAG_QUALS)) {
- IRO_Dump(" EASS at %d fail as store to volatile memory \n", nd->index);
- return 0;
- }
-
- if ((nd->u.diadic.left->u.monadic->flags & IROLF_LoopInvariant) && (nd->u.diadic.right->flags & IROLF_LoopInvariant)) {
- IRO_Dump(" EASS at %d pass\n", nd->index);
- } else {
- IRO_Dump(" EASS at %d fail, either LHS address or RHS is variant \n", nd->index);
- return 0;
- }
- } else {
- IRO_Dump("Found EASS nodes whose lhs root is not a EINDIRECT node\n");
- return 0;
- }
- } else {
- IRO_Dump("Found EASS node that is referenced i.e embedded assignment\n");
- return 0;
- }
- } else {
- if (!(nd->flags & IROLF_Reffed)) {
- IRO_Dump("Found non EASS top level node in the loop\n");
- return 0;
- }
- }
- }
-
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
- }
- }
-
- return 1;
-}
-
-static int CheckStepOverFlow1_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val2) {
- Boolean isUnsigned;
- IROLinear *nd2;
- IROLinear *nd1;
- CInt64 nd2value;
- CInt64 nd1value;
- CInt64 addConst;
- CInt64 work;
- CInt64 neg1;
-
- nd2 = loop->nd14->u.diadic.right;
- nd1 = loop->nd18->u.diadic.right;
- isUnsigned = IRO_IsUnsignedType(loop->nd18->u.diadic.right->rtype);
-
- if (IRO_IsIntConstant(nd2) && IRO_IsIntConstant(nd1)) {
- nd2value = nd2->u.node->data.intval;
- nd1value = nd1->u.node->data.intval;
- if (isUnsigned) {
- if (CInt64_LessEqualU(nd1value, nd2value))
- return 1;
- } else {
- if (CInt64_LessEqual(nd1value, nd2value))
- return 1;
- }
-
- CInt64_SetLong(&addConst, loop->induction->addConst);
- CInt64_SetLong(&neg1, -1);
- *val1 = CInt64_Sub(nd1value, nd2value);
- *val1 = CInt64_Add(*val1, addConst);
- if (IS_LINEAR_DIADIC(loop->nd18, ELESS))
- *val1 = CInt64_Add(*val1, neg1);
-
- CError_ASSERT(855, !CInt64_IsZero(&addConst));
-
- if (isUnsigned)
- *val1 = CInt64_DivU(*val1, addConst);
- else
- *val1 = CInt64_Div(*val1, addConst);
-
- if (CInt64_Equal(*val1, cint64_zero))
- return 1;
-
- if (isUnsigned) {
- if (CInt64_LessEqualU(*val1, cint64_zero))
- CError_FATAL(877);
- } else {
- if (CInt64_LessEqual(*val1, cint64_zero))
- CError_FATAL(886);
- }
-
- if (isUnsigned) {
- *val2 = CInt64_MulU(*val1, addConst);
- *val2 = CInt64_Add(*val2, nd2value);
- } else {
- *val2 = CInt64_Mul(*val1, addConst);
- *val2 = CInt64_Add(*val2, nd2value);
- }
- } else {
- return 1;
- }
-
- CInt64_SetLong(&addConst, loop->induction->addConst);
- work = CInt64_Add(nd1value, addConst);
-
- if (isUnsigned) {
- if (CInt64_LessU(work, nd1value))
- return 1;
- } else {
- if (CInt64_Less(work, nd1value))
- return 1;
- }
-
- return 0;
-}
-
-static int CheckStepOverFlow2_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val2) {
- Boolean isUnsigned;
- IROLinear *nd2;
- IROLinear *nd1;
- CInt64 nd2value;
- CInt64 nd1value;
- CInt64 addConst;
- CInt64 work;
- CInt64 neg1;
-
- nd1 = loop->nd14->u.diadic.right;
- nd2 = loop->nd18->u.diadic.right;
- isUnsigned = IRO_IsUnsignedType(loop->nd18->u.diadic.right->rtype);
-
- if (IRO_IsIntConstant(nd2) && IRO_IsIntConstant(nd1)) {
- nd2value = nd2->u.node->data.intval;
- nd1value = nd1->u.node->data.intval;
- if (isUnsigned) {
- if (CInt64_LessEqualU(nd1value, nd2value))
- return 1;
- } else {
- if (CInt64_LessEqual(nd1value, nd2value))
- return 1;
- }
-
- CInt64_SetLong(&addConst, loop->induction->addConst);
- CInt64_SetLong(&neg1, -1);
- *val1 = CInt64_Sub(nd1value, nd2value);
- *val1 = CInt64_Add(*val1, addConst);
- if (IS_LINEAR_DIADIC(loop->nd18, EGREATER))
- *val1 = CInt64_Add(*val1, neg1);
-
- CError_ASSERT(995, !CInt64_IsZero(&addConst));
-
- if (isUnsigned)
- *val1 = CInt64_DivU(*val1, addConst);
- else
- *val1 = CInt64_Div(*val1, addConst);
-
- if (CInt64_Equal(*val1, cint64_zero))
- return 1;
-
- if (isUnsigned) {
- if (CInt64_LessEqualU(*val1, cint64_zero))
- return 0;
- } else {
- if (CInt64_LessEqual(*val1, cint64_zero))
- return 0;
- }
-
- if (isUnsigned) {
- *val2 = CInt64_MulU(*val1, addConst);
- *val2 = CInt64_Sub(nd1value, *val2);
- } else {
- *val2 = CInt64_Mul(*val1, addConst);
- *val2 = CInt64_Sub(nd1value, *val2);
- }
- } else {
- return 1;
- }
-
- CInt64_SetLong(&addConst, loop->induction->addConst);
- work = CInt64_Sub(nd2value, addConst);
-
- if (isUnsigned) {
- if (CInt64_GreaterU(work, nd2value))
- return 1;
- } else {
- if (CInt64_Greater(work, nd1value))
- return 1;
- }
-
- return 0;
-}
-
diff --git a/compiler_and_linker/unsorted/IroEval.c b/compiler_and_linker/unsorted/IroEval.c
deleted file mode 100644
index adf74b8..0000000
--- a/compiler_and_linker/unsorted/IroEval.c
+++ /dev/null
@@ -1,914 +0,0 @@
-#include "compiler/IroEval.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-static Boolean IsAssociativeENodeType[MAXEXPR];
-
-void IRO_InitializeIsAssociativeENodeTypeArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- IsAssociativeENodeType[i] = 0;
-
- IsAssociativeENodeType[EPOSTINC] = 0;
- IsAssociativeENodeType[EPOSTDEC] = 0;
- IsAssociativeENodeType[EPREINC] = 0;
- IsAssociativeENodeType[EPREDEC] = 0;
- IsAssociativeENodeType[EINDIRECT] = 0;
- IsAssociativeENodeType[EMONMIN] = 0;
- IsAssociativeENodeType[EBINNOT] = 0;
- IsAssociativeENodeType[ELOGNOT] = 0;
- IsAssociativeENodeType[EFORCELOAD] = 0;
- IsAssociativeENodeType[EMUL] = 1;
- IsAssociativeENodeType[EMULV] = 1;
- IsAssociativeENodeType[EDIV] = 0;
- IsAssociativeENodeType[EMODULO] = 0;
- IsAssociativeENodeType[EADDV] = 1;
- IsAssociativeENodeType[ESUBV] = 0;
- IsAssociativeENodeType[EADD] = 1;
- IsAssociativeENodeType[ESUB] = 0;
- IsAssociativeENodeType[ESHL] = 0;
- IsAssociativeENodeType[ESHR] = 0;
- IsAssociativeENodeType[ELESS] = 0;
- IsAssociativeENodeType[EGREATER] = 0;
- IsAssociativeENodeType[ELESSEQU] = 0;
- IsAssociativeENodeType[EGREATEREQU] = 0;
- IsAssociativeENodeType[EEQU] = 0;
- IsAssociativeENodeType[ENOTEQU] = 0;
- IsAssociativeENodeType[EAND] = 1;
- IsAssociativeENodeType[EXOR] = 1;
- IsAssociativeENodeType[EOR] = 1;
- IsAssociativeENodeType[ELAND] = 0;
- IsAssociativeENodeType[ELOR] = 0;
- IsAssociativeENodeType[EASS] = 0;
- IsAssociativeENodeType[EMULASS] = 0;
- IsAssociativeENodeType[EDIVASS] = 0;
- IsAssociativeENodeType[EMODASS] = 0;
- IsAssociativeENodeType[EADDASS] = 0;
- IsAssociativeENodeType[ESUBASS] = 0;
- IsAssociativeENodeType[ESHLASS] = 0;
- IsAssociativeENodeType[ESHRASS] = 0;
- IsAssociativeENodeType[EANDASS] = 0;
- IsAssociativeENodeType[EXORASS] = 0;
- IsAssociativeENodeType[EORASS] = 0;
- IsAssociativeENodeType[ECOMMA] = 0;
- IsAssociativeENodeType[EPMODULO] = 0;
- IsAssociativeENodeType[EROTL] = 0;
- IsAssociativeENodeType[EROTR] = 0;
- IsAssociativeENodeType[EBCLR] = 0;
- IsAssociativeENodeType[EBTST] = 0;
- IsAssociativeENodeType[EBSET] = 0;
- IsAssociativeENodeType[ETYPCON] = 0;
- IsAssociativeENodeType[EBITFIELD] = 0;
- IsAssociativeENodeType[EINTCONST] = 0;
- IsAssociativeENodeType[EFLOATCONST] = 0;
- IsAssociativeENodeType[ESTRINGCONST] = 0;
- IsAssociativeENodeType[ECOND] = 0;
- IsAssociativeENodeType[EFUNCCALL] = 0;
- IsAssociativeENodeType[EFUNCCALLP] = 0;
- IsAssociativeENodeType[EOBJREF] = 0;
- IsAssociativeENodeType[EMFPOINTER] = 0;
- IsAssociativeENodeType[ENULLCHECK] = 0;
- IsAssociativeENodeType[EPRECOMP] = 0;
- IsAssociativeENodeType[ETEMP] = 0;
- IsAssociativeENodeType[EARGOBJ] = 0;
- IsAssociativeENodeType[ELOCOBJ] = 0;
- IsAssociativeENodeType[ELABEL] = 0;
- IsAssociativeENodeType[ESETCONST] = 0;
- IsAssociativeENodeType[ENEWEXCEPTION] = 0;
- IsAssociativeENodeType[ENEWEXCEPTIONARRAY] = 0;
- IsAssociativeENodeType[EOBJLIST] = 0;
- IsAssociativeENodeType[EMEMBER] = 0;
- IsAssociativeENodeType[ETEMPLDEP] = 0;
- IsAssociativeENodeType[EINSTRUCTION] = 0;
- IsAssociativeENodeType[EDEFINE] = 0;
- IsAssociativeENodeType[EREUSE] = 0;
- IsAssociativeENodeType[EASSBLK] = 0;
- IsAssociativeENodeType[EVECTOR128CONST] = 0;
- IsAssociativeENodeType[ECONDASS] = 0;
-}
-
-void IRO_TruncateValueToType(CInt64 *val, Type *type) {
- if (IRO_IsUnsignedType(type)) {
- switch (type->size) {
- case 1:
- CInt64_ConvertUInt8(val);
- break;
- case 2:
- CInt64_ConvertUInt16(val);
- break;
- case 4:
- CInt64_ConvertUInt32(val);
- break;
- }
- } else {
- switch (type->size) {
- case 1:
- CInt64_ConvertInt8(val);
- break;
- case 2:
- CInt64_ConvertInt16(val);
- break;
- case 4:
- CInt64_ConvertInt32(val);
- break;
- }
- }
-}
-
-void IRO_TruncateBitfieldValueToType(CInt64 *val, Type *type, Type *type2) {
- UInt32 limit;
- UInt32 i;
- UInt32 j;
- CInt64 work;
-
- work = cint64_zero;
- limit = TYPE_BITFIELD(type2)->bitlength;
- for (i = 0; i < limit; i++)
- work = CInt64_Or(work, CInt64_Shl(cint64_one, IRO_MakeULong(i)));
- *val = CInt64_And(*val, work);
-
- if (!IRO_IsUnsignedType(type)) {
- work = cint64_zero;
- for (j = 0; j <= (i - 1); j++) {
- if (j == (i - 1))
- work = CInt64_Or(work, CInt64_Shl(cint64_one, IRO_MakeULong(j)));
- }
- if (CInt64_NotEqual(CInt64_And(work, *val), cint64_zero)) {
- for (j = i - 1; j < 64; j++)
- *val = CInt64_Or(*val, CInt64_Shl(cint64_one, IRO_MakeULong(j)));
- }
- }
-
- IRO_TruncateValueToType(val, type);
-}
-
-void IRO_ConstantFolding(void) {
- IROLinear *nd;
- ENode *expr;
- int isCompare;
- int flag;
- CInt64 val;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- switch (nd->type) {
- case IROLinearOp1Arg:
- if (IRO_IsIntConstant(nd->u.monadic)) {
- expr = NULL;
- flag = 0;
- val = nd->u.monadic->u.node->data.intval;
- if (nd->nodetype == ETYPCON && IS_TYPE_FLOAT(nd->rtype)) {
- expr = IRO_NewENode(EFLOATCONST);
- if (!IRO_IsUnsignedType(nd->u.monadic->rtype))
- expr->data.floatval.value = CInt64_ConvertToLongDouble(&val);
- else
- expr->data.floatval.value = CInt64_ConvertUToLongDouble(&val);
- expr->rtype = nd->rtype;
- } else {
- switch (nd->nodetype) {
- case ETYPCON:
- flag = 1;
- break;
- case ELOGNOT:
- val = CInt64_Not(val);
- flag = 1;
- break;
- case EBINNOT:
- val = CInt64_Inv(val);
- flag = 1;
- break;
- case EMONMIN:
- val = CInt64_Neg(val);
- flag = 1;
- break;
- }
-
- if (flag) {
- IRO_TruncateValueToType(&val, nd->rtype);
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = nd->rtype;
- expr->data.intval = val;
- }
- }
-
- if (expr) {
- nd->u.monadic->type = IROLinearNop;
- nd->type = IROLinearOperand;
- nd->u.node = expr;
- }
- }
- break;
-
- case IROLinearOp2Arg:
- if (IRO_IsIntConstant(nd->u.diadic.left) && !IRO_IsIntConstant(nd->u.diadic.right) && IsAssociativeENodeType[nd->nodetype]) {
- IROLinear *tmp = nd->u.diadic.right;
- nd->u.diadic.right = nd->u.diadic.left;
- nd->u.diadic.left = tmp;
- }
-
- if (IRO_IsIntConstant(nd->u.diadic.right) && nd->nodetype == ESUB) {
- nd->nodetype = EADD;
- if (IRO_IsIntConstant(nd->u.diadic.right)) {
- CInt64 v;
- v = CInt64_Neg(nd->u.diadic.right->u.node->data.intval);
- nd->u.diadic.right->u.node->data.intval = v;
- } else {
- Float f;
- f = CMach_CalcFloatMonadic(
- nd->u.diadic.right->rtype,
- '-',
- nd->u.diadic.right->u.node->data.floatval);
- nd->u.diadic.right->u.node->data.floatval = f;
- }
- }
-
- if (
- IRO_IsIntConstant(nd->u.diadic.right) &&
- IsAssociativeENodeType[nd->nodetype] &&
- nd->u.diadic.left->type == IROLinearOp2Arg &&
- nd->u.diadic.left->nodetype == nd->nodetype &&
- nd->u.diadic.left->rtype == nd->rtype &&
- IRO_IsIntConstant(nd->u.diadic.left->u.diadic.right) &&
- nd->u.diadic.left->u.diadic.right->rtype == nd->u.diadic.right->rtype
- )
- {
- IROLinear *tmp = nd->u.diadic.left;
- nd->u.diadic.left = tmp->u.diadic.left;
- tmp->u.diadic.left = tmp->u.diadic.right;
- tmp->u.diadic.right = nd->u.diadic.right;
- tmp->rtype = tmp->u.diadic.left->rtype;
- nd->u.diadic.right = tmp;
- nd = tmp;
- }
-
- if (IRO_IsIntConstant(nd->u.diadic.left) && IRO_IsIntConstant(nd->u.diadic.right)) {
- CInt64 val1 = nd->u.diadic.left->u.node->data.intval;
- CInt64 val2 = nd->u.diadic.right->u.node->data.intval;
- flag = 0;
- switch (nd->nodetype) {
- case EADD:
- val = CInt64_Add(val1, val2);
- flag = 1;
- break;
- case ESUB:
- val = CInt64_Sub(val1, val2);
- flag = 1;
- break;
- case EMUL:
- if (IRO_IsUnsignedType(nd->rtype))
- val = CInt64_MulU(val1, val2);
- else
- val = CInt64_Mul(val1, val2);
- flag = 1;
- break;
- case EDIV:
- if (!CInt64_IsZero(&val2)) {
- if (IRO_IsUnsignedType(nd->rtype))
- val = CInt64_DivU(val1, val2);
- else
- val = CInt64_Div(val1, val2);
- flag = 1;
- }
- break;
- case EMODULO:
- if (!CInt64_IsZero(&val2)) {
- if (IRO_IsUnsignedType(nd->rtype))
- val = CInt64_ModU(val1, val2);
- else
- val = CInt64_Mod(val1, val2);
- flag = 1;
- }
- break;
- case ESHL:
- val = CInt64_Shl(val1, val2);
- flag = 1;
- break;
- case ESHR:
- if (IRO_IsUnsignedType(nd->rtype))
- val = CInt64_ShrU(val1, val2);
- else
- val = CInt64_Shr(val1, val2);
- flag = 1;
- break;
- case EAND:
- val = CInt64_And(val1, val2);
- flag = 1;
- break;
- case EOR:
- val = CInt64_Or(val1, val2);
- flag = 1;
- break;
- case EXOR:
- val = CInt64_Xor(val1, val2);
- flag = 1;
- break;
- case ELESS:
- if (IRO_IsUnsignedType(nd->u.diadic.left->rtype))
- CInt64_SetULong(&val, CInt64_LessU(val1, val2));
- else
- CInt64_SetULong(&val, CInt64_Less(val1, val2));
- flag = 1;
- break;
- case EGREATER:
- if (IRO_IsUnsignedType(nd->u.diadic.left->rtype))
- CInt64_SetULong(&val, CInt64_GreaterU(val1, val2));
- else
- CInt64_SetULong(&val, CInt64_Greater(val1, val2));
- flag = 1;
- break;
- case ELESSEQU:
- if (IRO_IsUnsignedType(nd->u.diadic.left->rtype))
- CInt64_SetULong(&val, CInt64_LessEqualU(val1, val2));
- else
- CInt64_SetULong(&val, CInt64_LessEqual(val1, val2));
- flag = 1;
- break;
- case EGREATEREQU:
- if (IRO_IsUnsignedType(nd->u.diadic.left->rtype))
- CInt64_SetULong(&val, CInt64_GreaterEqualU(val1, val2));
- else
- CInt64_SetULong(&val, CInt64_GreaterEqual(val1, val2));
- flag = 1;
- break;
- case EEQU:
- CInt64_SetULong(&val, CInt64_Equal(val1, val2));
- flag = 1;
- break;
- case ENOTEQU:
- CInt64_SetULong(&val, CInt64_NotEqual(val1, val2));
- flag = 1;
- break;
- }
-
- if (flag) {
- IRO_TruncateValueToType(&val, nd->rtype);
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = nd->rtype;
- expr->data.intval = val;
- nd->u.diadic.left->type = IROLinearNop;
- nd->u.diadic.right->type = IROLinearNop;
- nd->type = IROLinearOperand;
- nd->u.node = expr;
- }
- }
-
- if (IRO_IsFloatConstant(nd->u.diadic.left) && IRO_IsFloatConstant(nd->u.diadic.right)) {
- Float fval1 = nd->u.diadic.left->u.node->data.floatval;
- Float fval2 = nd->u.diadic.right->u.node->data.floatval;
- Float fval;
- flag = 0;
- isCompare = 0;
- switch (nd->nodetype) {
- case EADD:
- fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '+', fval2);
- flag = 1;
- break;
- case ESUB:
- fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '-', fval2);
- flag = 1;
- break;
- case EMUL:
- fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '*', fval2);
- flag = 1;
- break;
- case EDIV:
- fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '/', fval2);
- flag = 1;
- break;
- case ELESS:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, '<', fval2));
- flag = 1;
- isCompare = 1;
- break;
- case EGREATER:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, '>', fval2));
- flag = 1;
- isCompare = 1;
- break;
- case ELESSEQU:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LESS_EQUAL, fval2));
- flag = 1;
- isCompare = 1;
- break;
- case EGREATEREQU:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_GREATER_EQUAL, fval2));
- flag = 1;
- isCompare = 1;
- break;
- case EEQU:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LOGICAL_EQ, fval2));
- flag = 1;
- isCompare = 1;
- break;
- case ENOTEQU:
- CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LOGICAL_NE, fval2));
- flag = 1;
- isCompare = 1;
- break;
- }
-
- if (flag) {
- if (isCompare) {
- IRO_TruncateValueToType(&val, nd->rtype);
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = nd->rtype;
- expr->data.intval = val;
- nd->u.diadic.left->type = IROLinearNop;
- nd->u.diadic.right->type = IROLinearNop;
- nd->type = IROLinearOperand;
- nd->u.node = expr;
- } else {
- expr = IRO_NewENode(EFLOATCONST);
- expr->rtype = nd->rtype;
- expr->data.floatval = fval;
- nd->u.diadic.left->type = IROLinearNop;
- nd->u.diadic.right->type = IROLinearNop;
- nd->type = IROLinearOperand;
- nd->u.node = expr;
- }
- }
- }
-
- break;
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-Boolean IRO_EvaluateConditionals(void) {
- IRONode *fnode;
- IROLinear *nd;
- Boolean changed = 0;
- SwitchInfo *switchInfo;
- SwitchCase *swcase;
- char found;
- CInt64 val;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- nd = fnode->last;
- switch (nd->type) {
- case IROLinearIf:
- case IROLinearIfNot:
- if (IRO_IsIntConstant(nd->u.label.x4)) {
- Boolean isZero = CInt64_IsZero(&nd->u.label.x4->u.node->data.intval);
- IRO_NopOut(nd->u.label.x4);
- if ((isZero == 0) == (nd->type == IROLinearIf))
- nd->type = IROLinearGoto;
- else
- nd->type = IROLinearNop;
- changed = 1;
- }
- break;
-
- case IROLinearSwitch:
- if (IRO_IsIntConstant(nd->u.swtch.x4)) {
- val = nd->u.swtch.x4->u.node->data.intval;
- switchInfo = nd->u.swtch.info;
- swcase = switchInfo->cases;
-
- IRO_NopOut(nd->u.swtch.x4);
- nd->type = IROLinearGoto;
-
- found = 0;
- while (swcase) {
- if (CInt64_GreaterEqual(val, swcase->min) && CInt64_LessEqual(val, swcase->max)) {
- found = 1;
- nd->u.label.label = swcase->label;
- break;
- }
- swcase = swcase->next;
- }
-
- if (!found)
- nd->u.label.label = switchInfo->defaultlabel;
- changed = 1;
- }
- break;
- }
- }
-
- if (changed) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
- IRO_CheckForUserBreak();
-
- return changed;
-}
-
-static int EEquConst(IROLinear *nd) {
- return nd && (nd->nodetype == EEQU) && IRO_IsIntConstant(nd->u.diadic.right);
-}
-
-static Object *VEquConst(IROLinear *nd) {
- if (EEquConst(nd))
- return IRO_IsVariable(nd->u.diadic.left);
- else
- return NULL;
-}
-
-static int IsConsecutive(CInt64 a, CInt64 b) {
- CInt64 diff;
-
- if (!CInt64_Equal(a, cint64_min) && !CInt64_Equal(b, cint64_min)) {
- diff = CInt64_Sub(b, a);
- return CInt64_Equal(diff, cint64_one) || CInt64_Equal(diff, cint64_negone);
- }
-
- return 0;
-}
-
-static IROLinear *findLabel(CLabel *label) {
- IROLinear *nd;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- if (nd->type == IROLinearLabel && nd->u.label.label == label)
- break;
- }
-
- return nd;
-}
-
-static IROLinear *leftLeaveOf(IROLinear *nd) {
- switch (nd->type) {
- case IROLinearOp1Arg:
- return leftLeaveOf(nd->u.monadic);
- case IROLinearOp2Arg:
- return leftLeaveOf(nd->u.diadic.left);
- case IROLinearOperand:
- return nd;
- default:
- return NULL;
- }
-}
-
-static int checkNode(IRONode *fnode) {
- IROLinear *nd;
-
- if (fnode->numpred <= 1) {
- nd = fnode->first;
- while (nd != fnode->last && (nd->type == IROLinearNop || nd->type == IROLinearLabel))
- nd = nd->next;
-
- if (nd == leftLeaveOf(fnode->last->u.label.x4))
- return 1;
- }
-
- return 0;
-}
-
-static int checkLabel(CLabel *label, IRONode *fnode) {
- switch (fnode->last->type) {
- case IROLinearIf:
- if (label == fnode->last->u.label.label)
- return 1;
- break;
- }
-
- return 0;
-}
-
-static Object *checkExpr(Object *a, IROLinear *nd) {
- Object *b = VEquConst(nd);
-
- if ((!a || a == b) && !IRO_HasSideEffect(nd))
- return b;
-
- return NULL;
-}
-
-static int checkStruct(IRONode *fnode1, IRONode *fnode2) {
- CLabel *label;
- Object *var;
-
- if (fnode1 == fnode2)
- return (int) checkExpr(NULL, fnode1->last->u.label.x4);
-
- label = fnode1->last->u.label.label;
- var = IRO_IsVariable(fnode1->last->u.label.x4->u.monadic);
- return checkNode(fnode2) && checkLabel(label, fnode2) && checkExpr(var, fnode2->last->u.label.x4);
-}
-
-typedef struct ReduceInfo {
- int x0;
- int x4;
- Object *x8;
- IRONode *fnode;
- struct ReduceInfo *next;
- CInt64 val;
-} ReduceInfo;
-
-static int MarkPattern1(ReduceInfo *info1, ReduceInfo *info2, CInt64 *val) {
- ReduceInfo *scan;
-
- if (!info2)
- return 0;
-
- if (info2->x0)
- return MarkPattern1(info1, info2->next, val);
-
- for (scan = info1; scan; scan = scan->next) {
- if (scan->x0 == 2) {
- if (CInt64_Equal(info2->val, scan->val)) {
- IRO_NopOut(scan->fnode->last);
- IRO_NopOut(scan->fnode->last->u.label.x4); // right union?
- scan->x0 = -1;
- return MarkPattern1(info1, info2->next, val);
- }
-
- if (IsConsecutive(info2->val, scan->val)) {
- info2->x0 = 2;
- if (CInt64_Greater(*val, scan->val))
- *val = scan->val;
- if (CInt64_Greater(*val, info2->val))
- *val = info2->val;
- MarkPattern1(scan->next, info2, val);
- MarkPattern1(info1, info1->next, val);
- return 1;
- }
- }
- }
-
- return MarkPattern1(info1, info2->next, val);
-}
-
-static int DoReducible1(ReduceInfo *info, CInt64 val) {
- ReduceInfo *last;
- ReduceInfo *scan;
- IROLinear *right;
- IROLinear *left;
- IROLinear *typconRight;
- IROLinear *typconLeft;
- IROLinear *cond;
- int count;
-
- count = 0;
- for (scan = info; scan; scan = scan->next) {
- if (scan->x0 == 2) {
- last = scan;
- count++;
- }
- }
-
- if (!count)
- return 0;
-
- for (scan = info; scan != last; scan = scan->next) {
- if (scan->x0 == 2) {
- scan->x0 = -1;
- IRO_NopOut(scan->fnode->last);
- IRO_NopOut(scan->fnode->last->u.label.x4);
- }
- }
-
- last->x0 = -1;
-
- cond = last->fnode->last;
- cond->u.label.x4->nodetype = ELESSEQU;
- CInt64_SetULong(&cond->u.label.x4->u.diadic.right->u.node->data.intval, count - 1);
-
- typconLeft = IRO_NewLinear(IROLinearOp1Arg);
- typconLeft->nodetype = ETYPCON;
- typconLeft->rtype = IRO_UnsignedType(cond->u.label.x4->u.diadic.left->rtype);
- typconLeft->index = ++IRO_NumLinear;
-
- typconRight = IRO_NewLinear(IROLinearOp1Arg);
- *typconRight = *typconLeft;
- typconRight->index = ++IRO_NumLinear;
-
- left = IRO_NewLinear(IROLinearOp2Arg);
- left->nodetype = EADD;
- left->rtype = cond->u.label.x4->u.diadic.left->rtype;
- left->index = ++IRO_NumLinear;
-
- right = IRO_NewLinear(IROLinearOperand);
- right->nodetype = EINTCONST;
- right->rtype = cond->u.label.x4->u.diadic.left->rtype;
- right->index = ++IRO_NumLinear;
- right->u.node = IRO_NewENode(EINTCONST);
- right->u.node->data.intval = CInt64_Neg(val);
- right->u.node->rtype = right->rtype;
-
- typconLeft->next = cond->u.label.x4->u.diadic.left->next;
- cond->u.label.x4->u.diadic.left->next = right;
- right->next = left;
- left->next = typconLeft;
-
- typconRight->next = cond->u.label.x4->u.diadic.right->next;
- cond->u.label.x4->u.diadic.right->next = typconRight;
-
- typconLeft->u.monadic = left;
- left->u.diadic.left = cond->u.label.x4->u.diadic.left;
- left->u.diadic.right = right;
- cond->u.label.x4->u.diadic.left = typconLeft;
- typconRight->u.monadic = cond->u.label.x4->u.diadic.right;
- cond->u.label.x4->u.diadic.right = typconRight;
-
- return count;
-};
-
-static int ReducePattern1(IRONode *startnode, IRONode *endnode) {
- ReduceInfo *infos;
- ReduceInfo *info;
- int changed = 0;
- int count;
- IRONode *fnode;
- int i;
- int j;
- CInt64 val;
-
- if (startnode == endnode)
- return 0;
-
- count = 0;
- for (fnode = startnode; fnode != endnode; fnode = fnode->nextnode)
- count++;
-
- infos = oalloc(sizeof(ReduceInfo) * ++count);
-
- fnode = startnode;
- for (i = 0; i < count; i++) {
- infos[i].x0 = 0;
- infos[i].x4 = 0;
- infos[i].fnode = fnode;
- infos[i].next = NULL;
- infos[i].x8 = VEquConst(fnode->last->u.label.x4);
- if (infos[i].x8) {
- infos[i].val = fnode->last->u.label.x4->u.diadic.right->u.node->data.intval;
- infos[i].x4 = 1;
- }
- fnode = fnode->nextnode;
- }
-
- for (j = 0; j < count; j++) {
- if (infos[j].x4 == 1 && infos[j].x8) {
- infos[j].x4 = -1;
- info = &infos[j];
- for (i = j + 1; i < count; i++) {
- if (infos[j].x8 == infos[i].x8) {
- info->next = &infos[i];
- info = &infos[i];
- infos[i].x4 = 0;
- }
- }
- }
- }
-
- for (j = 0; j < count; j++) {
- if (infos[j].x4 == -1) {
- for (info = &infos[j]; info; info = info->next) {
- if (info->x0 == 0) {
- info->x0 = 2;
- val = info->val;
- if (MarkPattern1(&infos[j], info->next, &val)) {
- changed = 1;
- DoReducible1(&infos[j], val);
- } else {
- info->x0 = -1;
- }
- }
- }
- }
- }
-
- return changed;
-}
-
-static int ReduceConsecutiveIf(IRONode *startnode, IRONode *endnode) {
- IRONode *node31;
- IRONode *node30;
- int changed = 0;
-
- while (startnode != endnode) {
- if (checkStruct(startnode, startnode))
- break;
- startnode = startnode->nextnode;
- }
-
- node31 = startnode;
- if (startnode != endnode) {
- node30 = startnode;
- node31 = startnode->nextnode;
- while (node31 != endnode) {
- if (checkStruct(startnode, node31)) {
- node30 = node31;
- node31 = node31->nextnode;
- } else {
- node31 = node30;
- break;
- }
- }
-
- if (node31 == endnode && !checkStruct(startnode, node31))
- node31 = node30;
-
- if (startnode != node31 && ReducePattern1(startnode, node31))
- changed = 1;
-
- if (node31 != endnode)
- node31 = node31->nextnode;
- }
-
- if (node31 != endnode && ReduceConsecutiveIf(node31, endnode))
- changed = 1;
-
- return changed;
-}
-
-int IRO_SimplifyConditionals(void) {
- IRONode *fnode;
- IRONode *start;
- IRONode *end;
- int changed = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (fnode->last->type == IROLinearIf) {
- start = end = fnode;
- while (fnode->nextnode && fnode->nextnode->last->type == IROLinearIf) {
- end = fnode = fnode->nextnode;
- }
- if (start != end && ReduceConsecutiveIf(start, end))
- changed = 1;
- }
- }
-
- if (changed) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
- IRO_CheckForUserBreak();
- return changed;
-}
-
-Boolean IRO_EvaluateDefinitePointers(Object *func) {
- IROLinear *nd;
- Boolean result; // r29
- Boolean changed; // r28
- Boolean changed2; // r26
- IROLinear *nd2; // r25
- IROListNode *scan; // r25
- IROListNode *list;
-
- if (!copts.opt_pointer_analysis)
- return 0;
-
- result = 0;
-
- do {
- changed = 0;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- if (
- nd->type == IROLinearOp1Arg &&
- nd->nodetype == EINDIRECT &&
- !(nd->flags & IROLF_Assigned) &&
- nd->pointsToFunction &&
- !IRO_HasSideEffect(nd) &&
- PointerAnalysis_IsLinearNodePointerExprDefinite(func, nd)
- )
- {
- list = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(func, nd, &list);
- if (list) {
- if (list->list.head && list->list.tail && !list->nextList) {
- changed2 = IRO_LocateFather_Cut_And_Paste(nd, list->list.tail) != NULL;
- if (changed2) {
- IRO_PasteAfter(list->list.head, list->list.tail, nd);
- for (nd2 = list->list.head; nd2 != list->list.tail->next; nd2 = nd2->next) {
- if (nd2->type == IROLinearOperand && nd2->u.node->type == EOBJREF) {
- if (nd2->u.node->data.objref->datatype == DDATA || nd2->u.node->data.objref->datatype == DLOCAL)
- IRO_FindVar(nd2->u.node->data.objref, 1, 1);
- else
- nd2->u.node->data.objref->varptr = NULL;
- }
- }
- }
- changed |= changed2;
- }
-
- while (list) {
- scan = list->nextList;
- IRO_free(list);
- list = scan;
- }
- }
- }
- }
-
- result |= changed;
- IRO_CheckForUserBreak();
- } while (changed);
-
- return result;
-}
diff --git a/compiler_and_linker/unsorted/IroExprRegeneration.c b/compiler_and_linker/unsorted/IroExprRegeneration.c
deleted file mode 100644
index f63622a..0000000
--- a/compiler_and_linker/unsorted/IroExprRegeneration.c
+++ /dev/null
@@ -1,1531 +0,0 @@
-#include "compiler/IroExprRegeneration.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroSubable.h"
-#include "compiler/IroTransform.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CDecl.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/objects.h"
-
-// forward decls
-static void GetExprUses(IROLinear *linear, Boolean isEntry);
-static void RebuildPossibleCondExpression(IRONode *fnode);
-static void AddNodeAndSuccessorsRecursively(IRONodes *nodes, IRONode *fnode1, IRONode *fnode2);
-
-static Boolean FindFlowgraphNodeThatStartsWithLabel(CLabel *label, IRONode **result1, IRONode **result2) {
- IRONode *prev;
- IRONode *iter;
-
- prev = IRO_FirstNode;
- if (prev != NULL)
- iter = prev->nextnode;
-
- while (iter) {
- if (iter->first->type == IROLinearLabel && iter->first->u.label.label == label) {
- *result1 = iter;
- *result2 = prev;
- return 1;
- }
-
- prev = iter;
- iter = iter->nextnode;
- }
-
- return 0;
-}
-
-static IROLinear *FindLastDiadicTopLevelAssignmentInFlowgraphNode(IRONode *fnode) {
- IROLinear *scan;
- IROLinear *result;
-
- result = NULL;
-
- for (scan = fnode->first; scan != fnode->last->next; scan = scan->next) {
- if (scan->type == IROLinearOp2Arg && scan->nodetype == EASS && !(scan->flags & IROLF_Reffed))
- result = scan;
- }
-
- return result;
-}
-
-static Boolean RewriteUse(IROUse *use, ENode *enode, IROLinear *nd, Boolean flag) {
- IROLinear *father;
- IROLinear *father2;
-
- if (
- use &&
- use->x1C &&
- use->linear &&
- use->linear->type == IROLinearOperand &&
- use->linear->u.node->type == EOBJREF &&
- use->linear->u.node->data.objref == enode->data.objref &&
- (father = IRO_LocateFather(use->linear)) &&
- father->type == IROLinearOp1Arg &&
- father->nodetype == EINDIRECT &&
- father->rtype == nd->rtype &&
- (father2 = IRO_LocateFather(father)) &&
- ((father2->type != IROLinearOp1Arg && father2->type != IROLinearOp2Arg) || !IRO_IsModifyOp[father2->nodetype])
- ) {
- if (flag)
- IRO_LocateFather_Cut_And_Paste(father, nd);
- return 1;
- }
-
- return 0;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-static struct {
- jmp_buf buf;
- UInt16 index;
- Boolean flag;
-} scuai;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void StatementContainsUseAction(IROLinear *linear, Boolean isFirst) {
- if (isFirst && linear->index == scuai.index) {
- scuai.flag = 1;
- longjmp(scuai.buf, 1);
- }
-}
-
-static Boolean StatementContainsUse(IROLinear *a, IROLinear *b) {
- memset(&scuai, 0, sizeof(scuai));
- scuai.index = b->index;
- scuai.flag = 0;
-
- if (!setjmp(scuai.buf))
- IRO_WalkInts(a, a, StatementContainsUseAction);
-
- return scuai.flag;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-static struct {
- jmp_buf buf;
- Boolean flag;
-} scseai;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void StatementContainsSideEffectAction(IROLinear *linear, Boolean isFirst) {
- if (isFirst) {
- switch (linear->type) {
- case IROLinearOperand:
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- case IROLinearOp3Arg:
- case IROLinearFunccall:
- case IROLinearAsm:
- if (IRO_HasSideEffect(linear)) {
- scseai.flag = 1;
- longjmp(scseai.buf, 1);
- }
- break;
- }
- }
-}
-
-static Boolean StatementContainsSideEffect(IROLinear *linear) {
- memset(&scseai, 0, sizeof(scseai));
- scseai.flag = 0;
-
- if (!setjmp(scseai.buf))
- IRO_WalkInts(linear, linear, StatementContainsSideEffectAction);
-
- return scseai.flag;
-}
-
-static Boolean HasSideEffectsBeforeUse(IRONode *fnode1, IRONode *fnode2, IRONode *fnode3, IROLinear *nd, Boolean flag) {
- IRONode *fnode;
- IROLinear *scannd;
- UInt16 i;
-
- if (fnode1 != fnode3) {
- if (flag) {
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode)
- fnode->x3C = 0;
- } else if (fnode1->x3C) {
- return 0;
- }
- fnode1->x3C = 1;
- }
-
- for (scannd = fnode1->first; scannd && scannd != fnode1->last->next; scannd = scannd->next) {
- if (!(scannd->flags & IROLF_Reffed)) {
- if (StatementContainsUse(scannd, nd))
- return 0;
- if (StatementContainsSideEffect(scannd))
- return 1;
- }
- }
-
- if (fnode1 != fnode3) {
- for (i = 0; i < fnode1->numsucc; i++) {
- if (HasSideEffectsBeforeUse(IRO_NodeTable[fnode1->succ[i]], fnode2, fnode3, nd, 0))
- return 1;
- }
- }
-
- return 0;
-}
-
-static Boolean UsesAKilledVarBeforeUse(IRONode *fnode1, IRONode *fnode2, IRONode *fnode3, IROLinear *nd, BitVector *bv, Boolean flag) {
- IRONode *fnode;
- UInt16 i;
- IROLinear *scannd;
-
- if (fnode1 != fnode3) {
- if (flag) {
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode)
- fnode->x3C = 0;
- } else if (fnode1->x3C) {
- return 0;
- }
- fnode1->x3C = 1;
- }
-
- for (scannd = fnode1->first; scannd && scannd != fnode1->last->next; scannd = scannd->next) {
- if (!(scannd->flags & IROLF_Reffed)) {
- if (StatementContainsUse(scannd, nd))
- return 0;
- Bv_Clear(IRO_VarKills);
- IRO_WalkInts(scannd, scannd, GetExprUses);
- if (Bv_BitsInCommon(bv, IRO_VarKills))
- return 1;
- }
- }
-
- if (fnode1 != fnode3) {
- for (i = 0; i < fnode1->numsucc; i++) {
- if (UsesAKilledVarBeforeUse(IRO_NodeTable[fnode1->succ[i]], fnode2, fnode3, nd, bv, 0))
- return 1;
- }
- }
-
- return 0;
-}
-
-static void GetExprUses(IROLinear *linear, Boolean isEntry) {
- Object *obj;
- VarRecord *var;
-
- if (isEntry) {
- if (linear->type == IROLinearOperand && linear->u.node->type == EOBJREF) {
- obj = linear->u.node->data.objref;
- if ((linear->flags & IROLF_Ind) && (!(linear->flags & IROLF_Assigned) || (linear->flags & IROLF_Used))) {
- if ((var = IRO_FindVar(obj, 0, 1)))
- Bv_SetBit(var->index, IRO_VarKills);
- }
- }
- }
-}
-
-static void GetExprKills(IROLinear *linear, Boolean isEntry) {
- if (isEntry)
- IRO_GetKills(linear);
-}
-
-static void CheckUnorderedRegionForSideEffectsAndUses(IROLinear *nd, BitVector *bv1, BitVector *bv2, Boolean *result) {
- if (IRO_HasSideEffect(nd)) {
- *result = 1;
- } else {
- Bv_Clear(bv2);
- Bv_Clear(IRO_VarKills);
- IRO_WalkTree(nd, GetExprUses);
- Bv_Or(IRO_VarKills, bv2);
-
- if (Bv_BitsInCommon(bv1, bv2))
- *result = 1;
- }
-}
-
-static void CheckUnorderedRegionsForSideEffectsAndUses(IROLinear *nd1, IROLinear *nd2, BitVector *bv1, BitVector *bv2, Boolean *result) {
- int i;
-
- switch (nd1->type) {
- case IROLinearOp2Arg:
- if (nd1->nodetype != ELAND && nd1->nodetype != ELOR && nd1->nodetype != ECOMMA) {
- if (nd1->u.diadic.left != nd2)
- CheckUnorderedRegionForSideEffectsAndUses(nd1->u.diadic.left, bv1, bv2, result);
- if (nd1->u.diadic.right != nd2)
- CheckUnorderedRegionForSideEffectsAndUses(nd1->u.diadic.right, bv1, bv2, result);
- }
- break;
- case IROLinearFunccall:
- if (nd1->u.funccall.linear8 != nd2)
- CheckUnorderedRegionForSideEffectsAndUses(nd1->u.funccall.linear8, bv1, bv2, result);
- for (i = 0; !*result && i < nd1->u.funccall.argCount; i++) {
- if (nd1->u.funccall.args[i] != nd2)
- CheckUnorderedRegionForSideEffectsAndUses(nd1->u.funccall.args[i], bv1, bv2, result);
- }
- break;
- }
-}
-
-static Boolean CheckThenOrElseBranch(IRONode *fnode1, IRONode *fnode2, IROLinear *nd, Boolean flag) {
- IRONode *fnode;
- IROLinear *scannd;
- IRONodes nodes;
- Boolean result;
-
- IROFlowgraph_sub_4C2140(&nodes);
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode)
- fnode->x3C = 0;
- AddNodeAndSuccessorsRecursively(&nodes, fnode1, fnode2);
-
- while (IROFlowgraph_sub_4C2040(&nodes)) {
- fnode = IRO_NodeTable[IROFlowgraph_sub_4C2100(&nodes)];
- if (fnode) {
- if (!Bv_IsBitSet(fnode1->index, fnode->dom)) {
- result = 0;
- goto done;
- }
-
- for (scannd = fnode->first; scannd && scannd != fnode->last->next; scannd = scannd->next) {
- if (!nd || scannd != nd) {
- if (!flag || (scannd->type != IROLinearReturn)) {
- if (fnode->numpred == 2 && scannd->type == IROLinearLabel)
- RebuildPossibleCondExpression(fnode);
-
- if (scannd->type != IROLinearNop &&
- scannd->type != IROLinearLabel &&
- scannd->type != IROLinearGoto &&
- !(scannd->flags & IROLF_Reffed)) {
- result = 0;
- goto done;
- }
- }
- }
- }
- }
- }
-
- result = 1;
-done:
- IROFlowgraph_sub_4C20E0(&nodes);
- return result;
-}
-
-static void RebuildPossibleCondExpression(IRONode *fnode) {
- IRONode *pred1;
- IRONode *pred2;
- IRONode *r30;
- IROLinear *leftAss;
- IROLinear *rightAss;
- IROLinear *r27;
- IROLinear *r13;
- IROLinear *var_58;
- IRONode *left;
- IRONode *right;
- IRONode *r24;
- ENode *r23;
- IRODef *r22;
- IRODef *r21;
- IRODef *def;
- IROUse *use;
- UInt32 r20;
- UInt32 r19;
- Boolean r18;
- Boolean r17;
- UInt32 i;
- Boolean compareType;
- Type *var_60;
- IROLinear copy1;
- IROLinear copy2;
- IROLinear copy3;
-
- if (
- !fnode ||
- fnode->numpred != 2 ||
- !fnode->first ||
- fnode->first->type != IROLinearLabel
- )
- return;
-
- pred1 = IRO_NodeTable[fnode->pred[0]];
- pred2 = IRO_NodeTable[fnode->pred[1]];
- if (
- !pred1 || !pred2 ||
- pred1->numsucc != 1 || pred2->numsucc != 1
- )
- return;
-
- r24 = NULL;
- for (i = 0; i < IRO_NumNodes; i++) {
- if (
- Bv_IsBitSet(i, fnode->dom) &&
- (r24 = IRO_NodeTable[i]) &&
- r24->last &&
- (r24->last->type == IROLinearIf || r24->last->type == IROLinearIfNot) &&
- r24->last->u.label.label &&
- r24->numsucc == 2
- ) {
- if (Bv_IsBitSet(r24->succ[0], pred1->dom) &&
- !Bv_IsBitSet(r24->succ[0], pred2->dom) &&
- Bv_IsBitSet(r24->succ[1], pred2->dom) &&
- !Bv_IsBitSet(r24->succ[1], pred1->dom))
- break;
-
- if (Bv_IsBitSet(r24->succ[0], pred2->dom) &&
- !Bv_IsBitSet(r24->succ[0], pred1->dom) &&
- Bv_IsBitSet(r24->succ[1], pred1->dom) &&
- !Bv_IsBitSet(r24->succ[1], pred2->dom))
- break;
- }
- }
-
- if (i >= IRO_NumNodes)
- return;
-
- /*if (
- (r30 = IRO_NodeTable[r24->succ[0]]) &&
- r30->numpred == 1 &&
- r30->first &&
- r30->first->type == IROLinearLabel &&
- r30->first->u.label.label == r24->last->u.label.label
- ) {
- goto ok;
- } else if (
- (r30 = IRO_NodeTable[r24->succ[1]]) &&
- r30->numpred == 1 &&
- r30->first &&
- r30->first->type == IROLinearLabel &&
- r30->first->u.label.label == r24->last->u.label.label
- ) {
- goto ok;
- } else {
- return;
- }*/
- /*if (
- (!(r30 = IRO_NodeTable[r24->succ[0]]) ||
- r30->numpred != 1 ||
- !r30->first ||
- r30->first->type != IROLinearLabel ||
- r30->first->u.label.label != r24->last->u.label.label)
- &&
- (!(r30 = IRO_NodeTable[r24->succ[1]]) ||
- r30->numpred != 1 ||
- !r30->first ||
- r30->first->type != IROLinearLabel ||
- r30->first->u.label.label != r24->last->u.label.label)
- )
- return;*/
- r30 = IRO_NodeTable[r24->succ[0]];
- if (
- r30 &&
- r30->numpred == 1 &&
- r30->first &&
- r30->first->type == IROLinearLabel &&
- r30->first->u.label.label == r24->last->u.label.label
- ) {
- (void)0;
- } else {
- r30 = IRO_NodeTable[r24->succ[1]];
- if (
- r30 &&
- r30->numpred == 1 &&
- r30->first &&
- r30->first->type == IROLinearLabel &&
- r30->first->u.label.label == r24->last->u.label.label
- ) {
- } else {
- return;
- }
- }
-
-ok:
- if (Bv_IsBitSet(r30->index, pred1->dom)) {
- left = pred2;
- right = pred1;
- } else {
- left = pred1;
- right = pred2;
- }
-
- leftAss = FindLastDiadicTopLevelAssignmentInFlowgraphNode(left);
- if (
- !leftAss ||
- leftAss->type != IROLinearOp2Arg ||
- !leftAss->u.diadic.left ||
- leftAss->u.diadic.left->type != IROLinearOp1Arg ||
- leftAss->u.diadic.left->nodetype != EINDIRECT ||
- !leftAss->u.diadic.left->u.monadic ||
- leftAss->u.diadic.left->u.monadic->type != IROLinearOperand ||
- !(r23 = leftAss->u.diadic.left->u.monadic->u.node) ||
- !r23->rtype ||
- !IS_TYPE_POINTER_ONLY(r23->rtype) ||
- !r23->data.objref ||
- is_volatile_object(r23->data.objref) ||
- r23->data.objref->datatype != DLOCAL
- )
- r23 = NULL;
-
- if (r23) {
- rightAss = FindLastDiadicTopLevelAssignmentInFlowgraphNode(right);
- if (
- !rightAss ||
- rightAss->type != IROLinearOp2Arg ||
- !rightAss->u.diadic.left ||
- rightAss->u.diadic.left->type != IROLinearOp1Arg ||
- rightAss->u.diadic.left->nodetype != EINDIRECT ||
- !rightAss->u.diadic.left->u.monadic ||
- rightAss->u.diadic.left->u.monadic->type != IROLinearOperand ||
- !rightAss->u.diadic.left->u.monadic->u.node ||
- !rightAss->u.diadic.left->u.monadic->u.node->rtype ||
- !IS_TYPE_POINTER_ONLY(rightAss->u.diadic.left->u.monadic->u.node->rtype) ||
- rightAss->u.diadic.left->u.monadic->u.node->type != EOBJREF ||
- rightAss->u.diadic.left->u.monadic->u.node->data.objref != r23->data.objref ||
- rightAss->rtype != leftAss->rtype
- )
- r23 = NULL;
- }
-
- if (r23) {
- if (!CheckThenOrElseBranch(r24->nextnode, left, leftAss, 0) || !CheckThenOrElseBranch(r30, right, rightAss, 0))
- return;
-
- r19 = 0;
- r20 = 0;
- r18 = 0;
- r17 = 0;
- if (!r23->data.objref->varptr || !r23->data.objref->varptr->uses || !r23->data.objref->varptr->defs) {
- r23 = NULL;
- } else {
- r21 = NULL;
- r22 = NULL;
- for (def = r23->data.objref->varptr->defs; def && (!r22 || !r21); def = def->varnext) {
- if (def->x18 && def->linear == leftAss)
- r22 = def;
- else if (def->x18 && def->linear == rightAss)
- r21 = def;
- }
-
- if (!r22 || !r21) {
- r23 = NULL;
- } else {
- for (use = r23->data.objref->varptr->uses; r23 && use; use = use->varnext) {
- if (use->x1C) {
- r20++;
- if (Bv_IsBitSet(r22->index, use->x18) && Bv_IsBitSet(r21->index, use->x18)) {
- for (i = 0; r23 && i < use->x18->size; i++) {
- if (i != r22->index && i != r21->index && Bv_IsBitSet(i, use->x18))
- r23 = NULL;
- }
-
- if (r23 && !Bv_IsBitSet(fnode->index, use->node->dom))
- r23 = NULL;
-
- if (r23) {
- if (RewriteUse(use, r23, rightAss, 0))
- r19++;
- else
- r23 = NULL;
- }
-
- if (r23 && !r17)
- r17 = HasSideEffectsBeforeUse(fnode, fnode, use->node, use->linear, 1);
-
- if (r23 && !r18 && (IRO_HasSideEffect(r24->last->u.label.x4) || IRO_HasSideEffect(leftAss->u.label.x4) ||
- IRO_HasSideEffect(rightAss->u.label.x4)))
- r18 = 1;
- } else if (Bv_IsBitSet(r22->index, use->x18) || Bv_IsBitSet(r21->index, use->x18)) {
- r23 = NULL;
- }
- }
- }
- }
- }
- }
-
- if (!r23)
- return;
-
- compareType = r24->last->type == IROLinearIf;
- r27 = r24->last->u.label.x4;
- r13 = leftAss->u.label.x4;
- var_58 = rightAss->u.label.x4;
- var_60 = rightAss->rtype;
- memcpy(&copy1, r13, sizeof(IROLinear));
- memcpy(&copy2, rightAss, sizeof(IROLinear));
-
- r24->last->type = IROLinearNop;
- r24->last->expr = NULL;
- r30->first->type = IROLinearNop;
- r30->first->expr = NULL;
- fnode->first->type = IROLinearNop;
- fnode->first->expr = NULL;
- if (left->last->type == IROLinearGoto) {
- left->last->type = IROLinearNop;
- left->last->expr = NULL;
- }
- if (right->last->type == IROLinearGoto) {
- right->last->type = IROLinearNop;
- right->last->expr = NULL;
- }
-
- if (r23) {
- IRO_NopOut(leftAss->u.diadic.left);
- leftAss->type = IROLinearNop;
- leftAss->expr = NULL;
- }
-
- memcpy(rightAss, &copy1, sizeof(IROLinear));
- rightAss->type = IROLinearOp3Arg;
- rightAss->nodetype = ECOND;
- rightAss->index = copy2.index;
- rightAss->u.args3.a = r27;
- rightAss->rtype = var_60;
- rightAss->next = copy2.next;
- if (compareType) {
- rightAss->u.args3.b = var_58;
- rightAss->u.args3.c = r13;
- } else {
- rightAss->u.args3.b = r13;
- rightAss->u.args3.c = var_58;
- }
- rightAss->flags |= IROLF_Reffed;
-
- if (r19 == 1 && !r17 && !r18 && !r23->data.objref->varptr->xB) {
- for (use = r23->data.objref->varptr->uses; use; use = use->varnext) {
- if (use->x1C && Bv_IsBitSet(r22->index, use->x18) && Bv_IsBitSet(r21->index, use->x18)) {
- RewriteUse(use, r23, rightAss, 1);
- if ((r18 = (use->linear->flags & IROLF_4000) && IRO_HasSideEffect(r27))) {
- IROLinear *tmp;
- Object *obj;
-
- tmp = IRO_NewLinear(IROLinearOperand);
- memcpy(tmp, copy2.u.diadic.left->u.monadic, sizeof(IROLinear));
- tmp->index = IRO_NumLinear++;
- tmp->rtype = r27->rtype;
- if (r20 == 1) {
- tmp->u.node->data.objref->type = r27->rtype;
- tmp->u.node->rtype = CDecl_NewPointerType(r27->rtype);
- } else {
- obj = create_temp_object(tmp->rtype);
- IRO_FindVar(obj, 1, 1);
- tmp->u.node = create_objectrefnode(obj);
- }
- IRO_PasteAfter(tmp, tmp, r27);
-
- tmp = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(tmp, copy2.u.diadic.left, sizeof(IROLinear));
- tmp->index = IRO_NumLinear++;
- tmp->u.monadic = r27->next;
- tmp->rtype = r27->rtype;
- IRO_PasteAfter(tmp, tmp, r27->next);
-
- tmp = IRO_NewLinear(IROLinearOp2Arg);
- memcpy(tmp, &copy2, sizeof(IROLinear));
- tmp->index = IRO_NumLinear++;
- tmp->u.diadic.right = r27;
- tmp->u.diadic.left = r27->next->next;
- tmp->rtype = r27->rtype;
- IRO_PasteAfter(tmp, tmp, r27->next->next);
-
- if (r20 != 1) {
- tmp = copy2.u.diadic.left->u.monadic;
- tmp->u.node = create_objectrefnode(obj);
- }
-
- rightAss->u.args3.a = copy2.u.diadic.left;
- rightAss->u.args3.a->rtype = r27->rtype;
-
- if (r20 == 1) {
- r21->linear = r27->next->next;
- if (Bv_IsBitSet(r21->index, right->x1A)) {
- Bv_ClearBit(r21->index, right->x1A);
- Bv_SetBit(r21->index, r24->x1A);
- }
- if (Bv_IsBitSet(r21->index, right->x1E)) {
- Bv_ClearBit(r21->index, right->x1E);
- Bv_SetBit(r21->index, r24->x1E);
- }
- if (Bv_IsBitSet(r21->index, right->x22)) {
- Bv_ClearBit(r21->index, right->x22);
- Bv_SetBit(r21->index, r24->x22);
- }
- }
- }
- }
- }
-
- if (!r18) {
- if (r20 == 1 && r23->data.objref->u.var.info) {
- r23->data.objref->u.var.info->usage = 0;
- r23->data.objref->u.var.info->used = 0;
- }
- r22->x18 = 0;
- IRO_NopOut(copy2.u.diadic.left);
- r21->x18 = 0;
- }
- } else {
- memcpy(&copy3, fnode->first, sizeof(IROLinear));
- memcpy(fnode->first, &copy2, sizeof(IROLinear));
-
- fnode->first->index = copy3.index;
- fnode->first->u.diadic.right = rightAss;
- fnode->first->next = copy3.next;
- r22->x18 = 0;
- r21->linear = fnode->first;
- if (Bv_IsBitSet(r21->index, right->x1A)) {
- Bv_ClearBit(r21->index, right->x1A);
- Bv_SetBit(r21->index, fnode->x1A);
- }
- if (Bv_IsBitSet(r21->index, right->x1E)) {
- Bv_ClearBit(r21->index, right->x1E);
- Bv_SetBit(r21->index, fnode->x1E);
- }
- if (Bv_IsBitSet(r21->index, right->x22)) {
- Bv_ClearBit(r21->index, right->x22);
- Bv_SetBit(r21->index, fnode->x22);
- }
- }
-}
-
-static void RebuildPossibleReturnCondExpression(IRONode *fnode) {
- IRONode *succ1;
- IRONode *succ2;
- IROLinear *node1;
- IROLinear *node2;
- IROLinear *node3;
- IRONode *r27;
- Boolean isIf;
- Type *type;
- IROList list;
-
- if (
- !fnode ||
- fnode->numsucc != 2 ||
- !fnode->last ||
- (fnode->last->type != IROLinearIf && fnode->last->type != IROLinearIfNot)
- )
- return;
-
- succ1 = IRO_NodeTable[fnode->succ[0]];
- succ2 = IRO_NodeTable[fnode->succ[1]];
- if (
- !succ1 || !succ2 ||
- succ1->numsucc != 0 || succ1->numpred != 1 ||
- succ2->numsucc != 0 || succ2->numpred != 1
- )
- return;
-
- if (succ1->first && succ1->first->type == IROLinearLabel && succ1->first->u.label.label == fnode->last->u.label.label) {
- r27 = succ1;
- } else if (succ2->first && succ2->first->type == IROLinearLabel && succ2->first->u.label.label == fnode->last->u.label.label) {
- r27 = succ2;
- } else {
- return;
- }
-
- if (r27->numpred != 1)
- return;
-
- if (!CheckThenOrElseBranch(fnode->nextnode, fnode->nextnode, NULL, 1) || !CheckThenOrElseBranch(r27, r27, NULL, 1))
- return;
-
- if (
- !fnode->nextnode->last ||
- fnode->nextnode->last->type != IROLinearReturn ||
- !fnode->nextnode->last->u.monadic ||
- !r27->last ||
- r27->last->type != IROLinearReturn ||
- !r27->last->u.monadic ||
- !IRO_TypesEqual(fnode->nextnode->last->u.monadic->rtype, r27->last->u.monadic->rtype)
- )
- return;
-
- isIf = fnode->last->type == IROLinearIf;
- node1 = fnode->last->u.diadic.right;
- node2 = fnode->nextnode->last->u.diadic.left;
- node3 = r27->last->u.diadic.left;
- type = node2->rtype;
-
- fnode->last->type = IROLinearNop;
- fnode->last->expr = NULL;
- r27->last->type = IROLinearNop;
- r27->last->expr = NULL;
- r27->first->type = IROLinearNop;
- r27->first->expr = NULL;
-
- if (IRO_IsIntConstant(node2) && IRO_IsIntConstant(node3) &&
- ((IRO_IsConstantOne(node2) && IRO_IsConstantZero(node3)) ||
- (IRO_IsConstantZero(node2) && IRO_IsConstantOne(node3)))) {
- if (!(node1->type == IROLinearOp1Arg && node1->nodetype == ELOGNOT && node1->rtype == type)) {
- IROLinear *tmp1;
- IROLinear *tmp2;
-
- tmp1 = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(tmp1, node2, sizeof(IROLinear));
- tmp1->type = IROLinearOp1Arg;
- tmp1->nodetype = ELOGNOT;
- tmp1->index = IRO_NumLinear++;
- tmp1->u.monadic = node1;
-
- tmp1->next = tmp2 = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(tmp2, node2, sizeof(IROLinear));
- tmp2->type = IROLinearOp1Arg;
- tmp2->nodetype = ELOGNOT;
- tmp2->index = IRO_NumLinear++;
- tmp2->u.monadic = tmp1;
-
- IRO_PasteAfter(tmp1, tmp2, node1);
- node1 = tmp2;
- }
-
- if ((IRO_IsConstantZero(node2) && !isIf) || (IRO_IsConstantOne(node2) && isIf)) {
- if (node1->type == IROLinearOp1Arg && node1->nodetype == ELOGNOT && node1->rtype == node1->u.monadic->rtype) {
- IROLinear *tmp = node1;
- node1 = node1->u.monadic;
- tmp->type = IROLinearNop;
- tmp->expr = NULL;
- } else {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(tmp, node2, sizeof(IROLinear));
- tmp->type = IROLinearOp1Arg;
- tmp->nodetype = ELOGNOT;
- tmp->index = IRO_NumLinear++;
- tmp->u.monadic = node1;
- IRO_PasteAfter(tmp, tmp, node1);
- node1 = tmp;
- }
- }
-
- node2->type = IROLinearNop;
- node2->expr = NULL;
- node3->type = IROLinearNop;
- node3->expr = NULL;
- fnode->nextnode->last->u.monadic = node1;
- } else {
- IROLinear *tmp1;
- IROLinear *tmp2;
-
- IRO_InitList(&list);
- tmp1 = IRO_DuplicateExpr(node3, &list);
- IRO_NopOut(node3);
- IRO_Paste(list.head, list.tail, fnode->nextnode->last);
-
- tmp2 = IRO_NewLinear(IROLinearOp3Arg);
- memcpy(tmp2, node2, sizeof(IROLinear));
- tmp2->type = IROLinearOp3Arg;
- tmp2->nodetype = ECOND;
- tmp2->index = IRO_NumLinear++;
- tmp2->u.args3.a = node1;
- tmp2->rtype = type;
- IRO_Paste(tmp2, tmp2, fnode->nextnode->last);
-
- if (isIf) {
- tmp2->u.args3.b = tmp1;
- tmp2->u.args3.c = node2;
- } else {
- tmp2->u.args3.b = node2;
- tmp2->u.args3.c = tmp1;
- }
-
- fnode->nextnode->last->u.monadic = tmp2;
- }
-}
-
-static void RebuildCondExpressions(void) {
- IRONode *fnode;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (fnode->numpred == 2) {
- if (fnode->first && fnode->first->type == IROLinearLabel)
- RebuildPossibleCondExpression(fnode);
- } else if (fnode->numsucc == 2) {
- if (fnode->last && (fnode->last->type == IROLinearIf || fnode->last->type == IROLinearIfNot))
- RebuildPossibleReturnCondExpression(fnode);
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean IsLogicalExpressionAssign(IROLinear *nd) {
- IROLinear *right;
- IROLinear *left;
-
- return (
- nd->type == IROLinearOp2Arg &&
- nd->nodetype == EASS &&
- (left = nd->u.diadic.left) &&
- (right = nd->u.diadic.right) &&
- right->type == IROLinearOperand &&
- right->u.node &&
- right->u.node->type == EINTCONST &&
- (CInt64_Equal(right->u.node->data.intval, cint64_one) || CInt64_Equal(right->u.node->data.intval, cint64_zero)) &&
- left->type == IROLinearOp1Arg &&
- left->nodetype == EINDIRECT &&
- left->u.monadic &&
- IS_TYPE_POINTER_ONLY(left->u.monadic->rtype) &&
- left->u.monadic->type == IROLinearOperand &&
- left->u.monadic->u.node &&
- left->u.monadic->u.node->type == EOBJREF &&
- left->u.monadic->u.node->data.objref &&
- left->u.monadic->u.node->data.objref->datatype == DLOCAL);
-}
-
-static Boolean IsPossibleLogicalExpressionStart(IRONode *fnode, IROLinear *nd) {
- return
- fnode->numsucc == 2 &&
- fnode->last &&
- (fnode->last->type == IROLinearIf || fnode->last->type == IROLinearIfNot) &&
- IsLogicalExpressionAssign(nd);
-}
-
-static Boolean CheckForTopLevelExpressions(IRONode *fnode1, IRONode *fnode2, IRONode *fnode3, IROLinear *nd1, IROLinear *nd2, Boolean flag) {
- IRONode *fnode;
- IROLinear *nd;
- UInt16 i;
-
- if (fnode1 != fnode3) {
- if (!Bv_IsBitSet(fnode2->index, fnode1->dom))
- return 0;
-
- if (flag) {
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode)
- fnode->x3C = 0;
- } else if (fnode1->x3C) {
- return 1;
- }
- fnode1->x3C = 1;
-
- for (i = 0; i < fnode1->numsucc; i++) {
- fnode = IRO_NodeTable[fnode1->succ[i]];
- if (!CheckForTopLevelExpressions(fnode, fnode2, fnode3, fnode->first, nd2, 0))
- return 0;
- }
- }
-
- for (nd = nd1; nd && nd != fnode1->last->next; nd = nd->next) {
- if (nd == nd2)
- return 1;
-
- if (nd->type != IROLinearNop && nd->type != IROLinearLabel && !(nd->flags & IROLF_Reffed))
- return 0;
- }
-
- return 1;
-}
-
-static void AddNodeAndSuccessorsRecursively(IRONodes *nodes, IRONode *fnode1, IRONode *fnode2) {
- UInt16 i;
-
- if (fnode1 && !fnode1->x3C) {
- fnode1->x3C = 1;
- IROFlowgraph_sub_4C3880(nodes, fnode1->index);
- if (fnode1 != fnode2) {
- for (i = 0; i < fnode1->numsucc; i++)
- AddNodeAndSuccessorsRecursively(nodes, IRO_NodeTable[fnode1->succ[i]], fnode2);
- }
- }
-}
-
-static Boolean RebuildPossibleLogicalExpression(IRONode *fnode, IROLinear *nd) {
- IROUse *use;
- IROLinear *nd2;
- IROLinear *left;
- IROLinear *right;
- IRONode *r25;
- IRONode *r24;
- ENode *objnode;
- IRODef *def1;
- IRODef *def2;
- UInt32 useCount;
- UInt32 rewrittenUseCount;
- Boolean sideEffectFlag;
- IROLinearType compareType;
- CLabel *somelab;
- IRONode *var_68;
- IRONode *var_6C;
- CInt64 compareVal;
- Boolean killedFlag;
- BitVector *bv1;
- BitVector *bv2;
-
- IROLinear *father;
- IROLinear *iter;
- IRODef *def;
- UInt32 i;
- IROLinear *newlin;
-
- objnode = nd->u.diadic.left->u.monadic->u.node;
- if (!objnode->data.objref->varptr)
- return 0;
-
- if (CInt64_Equal(nd->u.diadic.right->u.node->data.intval, cint64_zero)) {
- compareType = IROLinearIfNot;
- compareVal = cint64_one;
- } else {
- compareType = IROLinearIf;
- compareVal = cint64_zero;
- }
-
- var_68 = NULL;
- def1 = NULL;
- for (def = objnode->data.objref->varptr->defs; def && !def1; def = def->varnext) {
- if (def->x18 && def->linear == nd)
- def1 = def;
- }
-
- if (def1) {
- for (use = objnode->data.objref->varptr->uses; use; use = use->varnext) {
- if (use->x1C == 2 && Bv_IsBitSet(def1->index, use->x18)) {
- if (!var_68) {
- var_68 = use->node;
- } else if (Bv_IsBitSet(use->node->index, var_68->dom)) {
- var_68 = use->node;
- }
- }
- }
-
- if (var_68) {
- for (use = objnode->data.objref->varptr->uses; use; use = use->varnext) {
- if (use->node != var_68 && use->x1C == 2 && Bv_IsBitSet(def1->index, use->x18) && !Bv_IsBitSet(var_68->index, use->node->dom)) {
- var_68 = NULL;
- break;
- }
- }
- }
- }
-
- if (
- !var_68 ||
- !var_68->first ||
- var_68->first->type != IROLinearLabel ||
- !(somelab = var_68->first->u.label.label) ||
- var_68->numpred != 3
- )
- return 0;
-
- r25 = IRO_NodeTable[var_68->pred[0]];
- if (Bv_IsBitSet(IRO_NodeTable[var_68->pred[1]]->index, r25->dom)) {
- r25 = IRO_NodeTable[var_68->pred[1]];
- } else if (!Bv_IsBitSet(r25->index, IRO_NodeTable[var_68->pred[1]]->dom)) {
- return 0;
- }
-
- if (Bv_IsBitSet(IRO_NodeTable[var_68->pred[2]]->index, r25->dom)) {
- r25 = IRO_NodeTable[var_68->pred[2]];
- } else if (!Bv_IsBitSet(r25->index, IRO_NodeTable[var_68->pred[2]]->dom)) {
- return 0;
- }
-
- if (
- !r25 ||
- !(left = r25->last) ||
- left->type != compareType ||
- left->u.label.label != somelab
- )
- return 0;
-
- if (
- !FindFlowgraphNodeThatStartsWithLabel(left->u.label.label, &var_68, &var_6C) ||
- !var_6C ||
- var_6C->numpred != 1 ||
- !(r24 = IRO_NodeTable[var_6C->pred[0]]) ||
- !(right = r24->last) ||
- right->type != compareType ||
- right->u.label.label != left->u.label.label ||
- !(nd2 = FindLastDiadicTopLevelAssignmentInFlowgraphNode(var_6C)) ||
- !IsLogicalExpressionAssign(nd2) ||
- nd2->u.diadic.left->u.monadic->u.node->data.objref != objnode->data.objref ||
- !CInt64_Equal(compareVal, nd2->u.diadic.right->u.node->data.intval) ||
- nd2->rtype != nd->rtype
- )
- return 0;
-
- if (
- !CheckForTopLevelExpressions(fnode, fnode, r25, nd->next, left, 1) ||
- !CheckForTopLevelExpressions(r25->nextnode, r25->nextnode, r24, r25->nextnode->first, right, 1) ||
- !CheckForTopLevelExpressions(r24->nextnode, r24->nextnode, var_6C, right->next, nd2, 1) ||
- !CheckForTopLevelExpressions(var_6C, var_6C, var_6C, nd2->next, var_68->first, 1)
- )
- return 0;
-
- rewrittenUseCount = 0;
- useCount = 0;
- killedFlag = 0;
- sideEffectFlag = 0;
- if (!objnode->data.objref->varptr || !(objnode->data.objref->varptr->uses) || !(objnode->data.objref->varptr->defs)) {
- objnode = NULL;
- } else {
- def1 = def2 = NULL;
- for (def = objnode->data.objref->varptr->defs; def && (!def1 || !def2); def = def->varnext) {
- if (def->x18 && def->linear == nd)
- def1 = def;
- else if (def->x18 && def->linear == nd2)
- def2 = def;
- }
-
- if (!def1 || !def2) {
- objnode = NULL;
- } else {
- for (use = objnode->data.objref->varptr->uses; objnode && use; use = use->varnext) {
- if (use->x1C) {
- useCount++;
- if (Bv_IsBitSet(def1->index, use->x18) && Bv_IsBitSet(def2->index, use->x18)) {
- for (i = 0; objnode && i < use->x18->size; i++) {
- if (i != def1->index && i != def2->index && Bv_IsBitSet(i, use->x18))
- objnode = NULL;
- }
-
- if (objnode && !Bv_IsBitSet(var_68->index, use->node->dom))
- objnode = NULL;
-
- if (objnode) {
- if (RewriteUse(use, objnode, nd2, 0))
- rewrittenUseCount++;
- else
- objnode = NULL;
- }
-
- if (objnode) {
- if (!sideEffectFlag)
- sideEffectFlag = HasSideEffectsBeforeUse(var_68, var_68, use->node, use->linear, 1);
-
- if (!killedFlag && (IRO_HasSideEffect(left->u.label.x4) || IRO_HasSideEffect(right->u.label.x4))) {
- iter = use->linear;
- if ((father = IRO_LocateFather(use->linear))) {
- Bv_AllocVector(&bv1, IRO_NumVars + 1);
- Bv_AllocVector(&bv2, IRO_NumVars + 1);
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- IRO_WalkTree(left->u.label.x4, GetExprKills);
- IRO_WalkTree(right->u.label.x4, GetExprKills);
- Bv_Or(IRO_VarKills, bv1);
- while (father && !killedFlag) {
- CheckUnorderedRegionsForSideEffectsAndUses(father, iter, bv1, bv2, &killedFlag);
- iter = father;
- father = IRO_LocateFather(father);
- }
- }
-
- if (!killedFlag)
- killedFlag = UsesAKilledVarBeforeUse(var_68, var_68, use->node, use->linear, bv1, 1);
- }
- }
- } else if (Bv_IsBitSet(def1->index, use->x18) || Bv_IsBitSet(def2->index, use->x18))
- objnode = NULL;
- }
- }
- }
- }
-
- if (!objnode)
- return 0;
-
- left->type = right->type = IROLinearNop;
- left->expr = right->expr = NULL;
-
- IRO_NopOut(nd);
-
- newlin = IRO_NewLinear(IROLinearOp2Arg);
- memcpy(newlin, nd2, sizeof(IROLinear));
- newlin->nodetype = (compareType == IROLinearIf) ? ELOR : ELAND;
- newlin->index = IRO_NumLinear++;
- newlin->u.diadic.left = left->u.label.x4;
- newlin->u.diadic.right = right->u.label.x4;
- newlin->flags |= IROLF_Reffed;
- IRO_Paste(newlin, newlin, nd2);
-
- if (rewrittenUseCount == 1 && !sideEffectFlag && !killedFlag && !objnode->data.objref->varptr->xB) {
- for (use = objnode->data.objref->varptr->uses; use; use = use->varnext) {
- if (use->x1C && Bv_IsBitSet(def1->index, use->x18) && Bv_IsBitSet(def2->index, use->x18))
- RewriteUse(use, objnode, newlin, 1);
- }
-
- if (useCount == 1 && objnode->data.objref->u.var.info) {
- objnode->data.objref->u.var.info->usage = 0;
- objnode->data.objref->u.var.info->used = 0;
- }
- IRO_NopOut(nd2);
- def1->x18 = 0;
- def2->x18 = 0;
- } else {
- IRO_NopOut(nd2->u.label.x4);
- nd2->u.label.x4 = newlin;
- def1->x18 = 0;
- }
-
- if (r24->numpred == 1 && IRO_NodeTable[r24->pred[0]] == r25 && IRO_MergeFlowGraphNodes(r25, r24))
- r24 = r25;
- if (var_6C->numpred == 1 && IRO_NodeTable[var_6C->pred[0]] == r24 && IRO_MergeFlowGraphNodes(r24, var_6C))
- var_6C = r24;
- if (var_68->numpred == 1 && r24 == r25 && var_6C == r24)
- IRO_MergeFlowGraphNodes(var_6C, var_68);
- return 1;
-}
-
-static void RebuildLogicalExpressions(void) {
- IRONode *fnode;
- IROLinear *nd;
- Boolean flag;
-
- flag = 1;
- while (flag) {
- flag = 0;
- for (fnode = IRO_FirstNode; fnode && fnode->last; fnode = fnode->nextnode) {
- for (nd = fnode->first; nd && nd != fnode->last->next; nd = nd->next) {
- if (IsPossibleLogicalExpressionStart(fnode, nd) && RebuildPossibleLogicalExpression(fnode, nd))
- flag = 1;
- }
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean IsPossibleCondAssStart(IRONode *fnode) {
- return (fnode->numsucc == 2) && fnode->last && (fnode->last->type == IROLinearIf || fnode->last->type == IROLinearIfNot);
-}
-
-static Type *logicalType(void) {
- if (copts.cplusplus && copts.booltruefalse)
- return TYPE(&stbool);
- else
- return TYPE(&stsignedint);
-}
-
-static Boolean GeneratePossibleCondAss(IRONode *fnode) {
- IROLinear *r31;
- IRONode *node2;
- IRONode *r29;
- Boolean r28;
- IRONode *node1;
- IROLinear *r24;
- Boolean r23;
- IROLinear *r19;
- Boolean r18;
- IROLinear *r20;
- Boolean r19flag;
- IROLinear *r18nd;
- IROLinear *ass;
- IROLinear *cond;
- IROLinear *r16;
- IROLinear *r15;
- BitVector *saveVarKills;
- IROList list;
- Object *obj;
- IROLinear *r14;
-
- if (!fnode || fnode->numsucc != 2 || !fnode->last || (fnode->last->type != IROLinearIf && fnode->last->type != IROLinearIfNot))
- return 0;
-
- if (IRO_NodeTable[fnode->succ[0]] &&
- IRO_NodeTable[fnode->succ[0]]->first &&
- IRO_NodeTable[fnode->succ[0]]->first->type == IROLinearLabel &&
- IRO_NodeTable[fnode->succ[0]]->first->u.label.label == fnode->last->u.label.label) {
- node1 = IRO_NodeTable[fnode->succ[0]];
- node2 = IRO_NodeTable[fnode->succ[1]];
- } else {
- node1 = IRO_NodeTable[fnode->succ[1]];
- if (node1 && node1->first && node1->first->type == IROLinearLabel && node1->first->u.label.label == fnode->last->u.label.label) {
- node2 = IRO_NodeTable[fnode->succ[0]];
- } else {
- return 0;
- }
- }
-
- if (!node2 || node2->numpred != 1 || node2->numsucc != 1 || node2->last->next != node1->first)
- return 0;
-
- if (IRO_NodeTable[node2->succ[0]] == node1 && Bv_IsBitSet(fnode->index, node1->dom)) {
- r28 = 0;
- } else if (
- node1->numpred == 1 && node1->numsucc == 1 &&
- node2->succ[0] == node1->succ[0] &&
- (r29 = IRO_NodeTable[node2->succ[0]]) &&
- Bv_IsBitSet(fnode->index, r29->dom) &&
- node1->last->next == r29->first
- ) {
- r28 = 1;
- } else {
- return 0;
- }
-
- r24 = NULL;
- if (node2->last) {
- for (r19 = node2->first; r19 && r19 != node2->last->next; r19 = r19->next) {
- if (IRO_IsAssignment(r19) && !(r19->flags & IROLF_Reffed) && !r24) {
- r24 = r19;
- } else if (r19->type != IROLinearNop && r19->type != IROLinearLabel && r19->type != IROLinearGoto && !(r19->flags & IROLF_Reffed)) {
- return 0;
- }
- }
- }
-
- if (
- !r24 ||
- (r24->nodetype != EASS && !IRO_TransformSelfAssignmentToAssignment(r24)) ||
- !r24->u.diadic.left ||
- r24->u.diadic.left->type != IROLinearOp1Arg ||
- r24->u.diadic.left->nodetype != EINDIRECT ||
- !r24->u.diadic.left->u.monadic ||
- r24->u.diadic.left->u.monadic->type != IROLinearOperand ||
- !r24->u.diadic.left->u.monadic->u.node ||
- !r24->u.diadic.left->u.monadic->u.node->rtype ||
- !IS_TYPE_POINTER_ONLY(r24->u.diadic.left->u.monadic->u.node->rtype) ||
- !r24->u.diadic.left->u.monadic->u.node->data.monadic
- )
- return 0;
-
- if (r28) {
- r31 = NULL;
- if (node1->last) {
- for (r19 = node1->first; r19 && r19 != node1->last->next; r19 = r19->next) {
- if (IRO_IsAssignment(r19) && !(r19->flags & IROLF_Reffed) && !r31) {
- r31 = r19;
- } else if (r19->type != IROLinearNop && r19->type != IROLinearLabel && r19->type != IROLinearGoto && !(r19->flags & IROLF_Reffed)) {
- return 0;
- }
- }
- }
-
- if (
- !r31 ||
- (r31->nodetype != EASS && !IRO_TransformSelfAssignmentToAssignment(r31)) ||
- !r31->u.diadic.left ||
- r31->u.diadic.left->type != IROLinearOp1Arg ||
- r31->u.diadic.left->nodetype != EINDIRECT ||
- !r31->u.diadic.left->u.monadic ||
- r31->u.diadic.left->u.monadic->type != IROLinearOperand ||
- !r31->u.diadic.left->u.monadic->u.node ||
- !r31->u.diadic.left->u.monadic->u.node->rtype ||
- !IS_TYPE_POINTER_ONLY(r31->u.diadic.left->u.monadic->u.node->rtype) ||
- !r31->u.diadic.left->u.monadic->u.node->data.monadic
- )
- return 0;
-
- r18 = IRO_ExprsSame(r24->u.diadic.left, r31->u.diadic.left);
- }
-
- r23 = fnode->last->type == IROLinearIf;
- r20 = fnode->last->u.diadic.right;
- r19flag = 0;
- if (r28 && copts.commonsubs && IRO_IsSubableExpression(r20))
- r19flag = 1;
-
- if (r19flag) {
- IRO_FindDepends(r20);
- r19flag = !IRO_NotSubable;
- }
-
- if (r28) {
- if (r18) {
- r19flag = 0;
- } else if (IRO_HasSideEffect(r20)) {
- r19flag = 1;
- } else {
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- IRO_WalkTree(r20, GetExprUses);
- saveVarKills = IRO_VarKills;
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- IRO_WalkTree(r20, GetExprKills);
- if (Bv_BitsInCommon(IRO_VarKills, saveVarKills))
- r19flag = 1;
- }
-
- if (r19flag && !copts.commonsubs)
- return 0;
- }
-
- if (r19flag) {
- IRO_InitList(&list);
- obj = create_temp_object(r20->rtype);
- IRO_FindVar(obj, 1, 1);
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->u.diadic.left = IRO_TempReference(obj, &list);
- ass->rtype = r20->rtype;
- ass->nodetype = EASS;
- ass->index = ++IRO_NumLinear;
- ass->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.right = r20;
- IRO_AddToList(ass, &list);
- IRO_PasteAfter(list.head, list.tail, r20);
- }
-
- r16 = r24->u.diadic.left;
- r15 = r24->u.diadic.right;
- fnode->last->type = IROLinearNop;
- fnode->last->expr = NULL;
- if (node2->last->type == IROLinearGoto) {
- node2->last->type = IROLinearNop;
- node2->last->expr = NULL;
- }
- if (r28 || node1->numpred == 2) {
- node1->first->type = IROLinearNop;
- node1->first->expr = NULL;
- }
-
- if (r28 && r18) {
- if (node1->last->type == IROLinearGoto) {
- node1->last->type = IROLinearNop;
- node1->last->expr = NULL;
- }
- if (r29->numpred == 2) {
- r29->first->type = IROLinearNop;
- r29->first->expr = NULL;
- }
-
- cond = IRO_NewLinear(IROLinearOp3Arg);
- memcpy(cond, r24, sizeof(IROLinear));
- cond->type = IROLinearOp3Arg;
- cond->nodetype = ECOND;
- cond->index = ++IRO_NumLinear;
- cond->rtype = r16->rtype;
- cond->flags |= IROLF_Reffed;
- if (r19flag) {
- IRO_InitList(&list);
- r14 = IRO_TempReference(obj, &list);
- IRO_Paste(list.head, list.tail, r31);
- } else {
- r14 = r20;
- }
- cond->u.args3.a = r14;
-
- if (r23) {
- cond->u.args3.b = r31->u.diadic.right;
- cond->u.args3.c = r15;
- } else {
- cond->u.args3.b = r15;
- cond->u.args3.c = r31->u.diadic.right;
- }
-
- r24->type = IROLinearNop;
- r24->expr = NULL;
- IRO_NopOut(r24->u.diadic.left);
- IRO_Paste(cond, cond, r31);
- r31->u.diadic.right = cond;
- } else {
- r24->type = IROLinearOp3Arg;
- r24->nodetype = ECONDASS;
- if (r19flag) {
- IRO_InitList(&list);
- r20 = IRO_TempReference(obj, &list);
- IRO_Paste(list.head, list.tail, r24);
- }
- cond = r20;
- if (r23) {
- r18nd = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(r18nd, r20, sizeof(IROLinear));
- r18nd->type = IROLinearOp1Arg;
- r18nd->nodetype = ELOGNOT;
- r18nd->index = ++IRO_NumLinear;
- r18nd->rtype = logicalType();
- r18nd->u.monadic = r20;
- r18nd->flags |= IROLF_Reffed;
- IRO_Paste(r18nd, r18nd, r24);
- r20 = r18nd;
- }
- r24->u.args3.a = r20;
- r24->u.args3.b = r16;
- r24->u.args3.c = r15;
- if (r28) {
- r15 = r31->u.diadic.left;
- r16 = r31->u.diadic.right;
- if (node1->last->type == IROLinearGoto) {
- node1->last->type = IROLinearNop;
- node1->last->expr = NULL;
- }
- if (r29->numpred == 2) {
- r29->first->type = IROLinearNop;
- r29->first->expr = NULL;
- }
- r31->type = IROLinearOp3Arg;
- r31->nodetype = ECONDASS;
- if (r19flag) {
- IRO_InitList(&list);
- cond = IRO_TempReference(obj, &list);
- IRO_Paste(list.head, list.tail, r31);
- } else {
- IRO_InitList(&list);
- cond = IRO_DuplicateExpr(cond, &list);
- IRO_Paste(list.head, list.tail, r31);
- }
- if (!r23) {
- r14 = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(r14, cond, sizeof(IROLinear));
- r14->type = IROLinearOp1Arg;
- r14->nodetype = ELOGNOT;
- r14->index = ++IRO_NumLinear;
- r14->rtype = logicalType();
- r14->u.monadic = cond;
- r14->flags |= IROLF_Reffed;
- IRO_Paste(r14, r14, r31);
- cond = r14;
- }
- r31->u.args3.a = cond;
- r31->u.args3.b = r15;
- r31->u.args3.c = r16;
- }
- }
-
- if (IRO_MergeFlowGraphNodes(fnode, node2))
- node2 = fnode;
- if ((r28 || node1->numpred == 1) && IRO_MergeFlowGraphNodes(node2, node1))
- node1 = node2;
- if (r28 && r29->numpred == 1)
- IRO_MergeFlowGraphNodes(node1, r29);
- return 1;
-}
-
-static void GenerateCondAssignments(void) {
- IRONode *fnode;
-
- fnode = IRO_FirstNode;
- while (fnode && fnode->last) {
- if (IsPossibleCondAssStart(fnode)) {
- if (!GeneratePossibleCondAss(fnode))
- fnode = fnode->nextnode;
- } else {
- fnode = fnode->nextnode;
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-void IRO_RegenerateExpressions(void) {
- IRO_UpdateFlagsOnInts();
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- IRO_UseDef(0, 0);
-
- if (copts.optimizationlevel > 0) {
- IRO_Dump("Rebuilding ELORs and ELANDs\n");
- RebuildLogicalExpressions();
- IRO_DumpAfterPhase("RebuildLogicalExpressions", 0);
- }
-
- if (copts.optimizationlevel > 0) {
- IRO_Dump("Rebuilding ECONDs\n");
- RebuildCondExpressions();
- IRO_DumpAfterPhase("RebuildCondExpressions", 0);
- }
-
- if (copts.optimizationlevel > 0) {
- IRO_Dump("Generating ECONDASSes\n");
- GenerateCondAssignments();
- IRO_DumpAfterPhase("GenerateCondAssignments", 0);
- }
-}
diff --git a/compiler_and_linker/unsorted/IroFlowgraph.c b/compiler_and_linker/unsorted/IroFlowgraph.c
deleted file mode 100644
index 5c9c840..0000000
--- a/compiler_and_linker/unsorted/IroFlowgraph.c
+++ /dev/null
@@ -1,439 +0,0 @@
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroPropagate.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/InlineAsmPPC.h"
-
-UInt16 IRO_NumNodes;
-IRONode *IRO_FirstNode;
-IRONode *IRO_LastNode;
-IRONode *IRO_EndNode;
-IRONode **IRO_NodeTable;
-BitVector *IRO_VarKills;
-BitVector *IRO_Avail;
-BitVector *IRO_FuncKills;
-BitVector *IRO_ExprKills;
-
-static IRONode *StartNode(IROLinear *linear) {
- IRONode *node = oalloc(sizeof(IRONode));
-
- node->index = IRO_NumNodes;
- node->numsucc = 0;
- node->succ = NULL;
- node->numpred = 0;
- node->pred = NULL;
- node->first = linear;
- node->last = linear;
- node->x16 = NULL;
- node->x1A = NULL;
- node->x1E = NULL;
- node->x22 = NULL;
- node->x26 = 0;
- node->x2A = NULL;
- node->dom = NULL;
- node->nextnode = NULL;
- node->x36 = 0;
- node->x37 = 0;
- node->mustreach = 0;
- node->x39 = 0;
- node->loopdepth = 0;
- node->x3C = 0;
- node->addressed = NULL;
-
- IRO_NumNodes++;
- if (!IRO_FirstNode)
- IRO_FirstNode = node;
- else
- IRO_LastNode->nextnode = node;
- IRO_LastNode = node;
- return node;
-}
-
-static void AddSucc(IRONode *a, IRONode *b) {
- a->succ[a->numsucc++] = b->index;
- b->numpred++;
-}
-
-static void AddLabelSucc(IRONode *node, CLabel *label) {
- IRONode *targetnode = (IRONode *) label->stmt;
- if (targetnode) {
- AddSucc(node, targetnode);
- targetnode->x39 = 1;
- } else {
- CError_FATAL(126);
- }
-}
-
-static void AddSwitchSucc(IRONode *node) {
- SwitchInfo *info = node->last->u.swtch.info;
- SwitchCase *curcase = info->cases;
- SInt32 i = 1;
-
- while (curcase) {
- curcase = curcase->next;
- i++;
- }
-
- node->succ = oalloc(sizeof(UInt16) * i);
- for (curcase = info->cases; curcase; curcase = curcase->next)
- AddLabelSucc(node, curcase->label);
- AddLabelSucc(node, info->defaultlabel);
-}
-
-static void AddPred(UInt32 a, UInt16 b) {
- IRONode *node = IRO_NodeTable[a];
- node->pred[node->numpred++] = b;
-}
-
-void IRO_ComputeSuccPred(void) {
- CLabel *label;
- IRONode *node;
- SInt32 count;
- IROLinear *linear;
- ExceptionAction *action;
- IAEffects effects;
- UInt16 i;
-
- for (label = Labels; label; label = label->next)
- label->stmt = NULL;
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- node->x39 = 0;
- node->numsucc = 0;
- node->numpred = 0;
- node->x36 = 0;
- node->x37 = 0;
- if (node->first && node->first->type == IROLinearLabel)
- node->first->u.label.label->stmt = (Statement *) node;
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (!node->first) {
- if (node->nextnode) {
- node->succ = oalloc(sizeof(UInt16));
- AddSucc(node, node->nextnode);
- }
- } else {
- linear = node->last;
- next_linear:
- switch (linear->type) {
- case IROLinearReturn:
- case IROLinearEnd:
- break;
- case IROLinearGoto:
- node->succ = oalloc(sizeof(UInt16));
- AddLabelSucc(node, linear->u.label.label);
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- node->succ = oalloc(sizeof(UInt16) * 2);
- AddSucc(node, node->nextnode);
- AddLabelSucc(node, linear->u.label.label);
- break;
- case IROLinearSwitch:
- AddSwitchSucc(node);
- break;
- case IROLinearFunccall:
- count = 1;
- if (IRO_FunctionCallMightThrowException(linear)) {
- for (action = linear->stmt->dobjstack; action; action = action->prev) {
- if (action->type == EAT_CATCHBLOCK || action->type == EAT_SPECIFICATION)
- count++;
- }
- }
- node->succ = oalloc(sizeof(UInt16) * count);
- AddSucc(node, node->nextnode);
- if (IRO_FunctionCallMightThrowException(linear)) {
- for (action = linear->stmt->dobjstack; action; action = action->prev) {
- if (action->type == EAT_CATCHBLOCK)
- AddLabelSucc(node, action->data.catch_block.catch_label);
- else if (action->type == EAT_SPECIFICATION)
- AddLabelSucc(node, action->data.specification.unexp_label);
- }
- }
- break;
- case IROLinearAsm:
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
- node->succ = oalloc(sizeof(UInt16) * (!effects.x5 + effects.numlabels));
- if (!effects.x5)
- AddSucc(node, node->nextnode);
- for (i = 0; i < effects.numlabels; i++)
- AddLabelSucc(node, effects.labels[i]);
- break;
- case IROLinearOp2Arg:
- if (linear->nodetype == ECOMMA) {
- linear = linear->u.diadic.right;
- goto next_linear;
- }
- default:
- if (node->nextnode) {
- node->succ = oalloc(sizeof(UInt16));
- AddSucc(node, node->nextnode);
- }
- }
- }
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->numpred)
- node->pred = oalloc(sizeof(UInt16) * node->numpred);
- else
- node->pred = NULL;
- node->numpred = 0;
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- for (i = 0; i < node->numsucc; i++)
- AddPred(node->succ[i], node->index);
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first && node->first->type == IROLinearLabel) {
- IROLinear *linear = node->first;
- do {
- if (linear->type == IROLinearBeginCatch || linear->type == IROLinearEndCatch || linear->type == IROLinearEndCatchDtor) {
- node->x39 = 1;
- break;
- }
- } while (linear != node->last && (linear = linear->next));
- }
- }
-}
-
-void IRO_ComputeDom(void) {
- IRONode *node;
- BitVector *bv;
- SInt32 i;
- int repeat;
-
- Bv_AllocVector(&IRO_FirstNode->dom, IRO_NumNodes);
- Bv_SetBit(IRO_FirstNode->index, IRO_FirstNode->dom);
- for (node = IRO_FirstNode->nextnode; node; node = node->nextnode) {
- Bv_AllocVector(&node->dom, IRO_NumNodes);
- Bv_Set(node->dom);
- }
-
- Bv_AllocVector(&bv, IRO_NumNodes);
-
- do {
- repeat = 0;
- for (node = IRO_FirstNode->nextnode; node; node = node->nextnode) {
- if (node->numpred) {
- Bv_Set(bv);
- for (i = 0; i < node->numpred; i++) {
- Bv_And(IRO_NodeTable[node->pred[i]]->dom, bv);
- }
- Bv_SetBit(node->index, bv);
- } else {
- Bv_Clear(bv);
- Bv_SetBit(node->index, bv);
- }
-
- if (!Bv_Compare(bv, node->dom)) {
- Bv_Copy(bv, node->dom);
- repeat = 1;
- }
- }
- } while (repeat);
-}
-
-void IRO_BuildFlowgraph(IROLinear *linear) {
- IROLinear *scan;
- CLabel *label;
- ExceptionAction *action;
- IAEffects effects;
- IRONode *node;
- SInt32 i;
- int flag;
-
- for (label = Labels; label; label = label->next)
- label->stmt = NULL;
-
- scan = linear;
- IRO_NumNodes = 0;
- IRO_FirstNode = IRO_LastNode = IRO_EndNode = NULL;
- while (scan) {
- StartNode(scan);
- if (scan->type == IROLinearLabel)
- scan->u.label.label->stmt = (Statement *) IRO_LastNode;
-
- flag = 0;
- while (!flag && scan->next && !(scan->next->flags & IROLF_1)) {
- switch (scan->type) {
- case IROLinearGoto:
- case IROLinearReturn:
- case IROLinearEntry:
- case IROLinearExit:
- case IROLinearEnd:
- flag = 1;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- case IROLinearSwitch:
- flag = 1;
- skip:
- if (scan->next->type == IROLinearLabel) {
- IROLinear *nw = IRO_NewLinear(IROLinearNop);
- nw->index = ++IRO_NumLinear;
- nw->next = scan->next;
- scan->next = nw;
- }
- break;
- case IROLinearFunccall:
- if (IRO_FunctionCallMightThrowException(scan)) {
- for (action = scan->stmt->dobjstack; action; action = action->prev) {
- if (action->type == EAT_CATCHBLOCK || action->type == EAT_SPECIFICATION) {
- flag = 1;
- goto skip;
- }
- }
- }
- break;
- case IROLinearAsm:
- CodeGen_GetAsmEffects(scan->u.asm_stmt, &effects);
- if (effects.numlabels)
- flag = 1;
- break;
- }
- if (!flag)
- scan = scan->next;
- }
-
- if (scan->type == IROLinearEnd)
- IRO_EndNode = IRO_LastNode;
- IRO_LastNode->last = scan;
- scan = scan->next;
- }
-
- IRO_NodeTable = oalloc(IRO_NumNodes * sizeof(IRONode *));
- memset(IRO_NodeTable, 0, IRO_NumNodes * sizeof(IRONode *));
- for (node = IRO_FirstNode, i = 0; node; node = node->nextnode)
- IRO_NodeTable[i++] = node;
-
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- IRO_CheckForUserBreak();
-}
-
-IRONode *IRO_NewFlowGraphNode(void) {
- IRONode *node = oalloc(sizeof(IRONode));
- memset(node, 0, sizeof(IRONode));
- node->index = IRO_NumNodes;
- IRO_NumNodes++;
- node->nextnode = NULL;
- return node;
-}
-
-IRONode *IRO_MergeFlowGraphNodes(IRONode *a, IRONode *b) {
- IRONode *succ;
- Boolean found;
- UInt32 i;
- UInt32 j;
- UInt32 k;
-
- if (a->nextnode == b && a->last && b->first && a->last->next == b->first) {
- if (b->first->type == IROLinearLabel)
- IRO_NopOut(b->first);
-
- a->nextnode = b->nextnode;
- a->last = b->last;
-
- for (i = 0; i < a->numsucc; i++) {
- if (b->index == a->succ[i]) {
- for (j = i; j < a->numsucc; j++) {
- if ((j + 1) < a->numsucc)
- a->succ[j] = a->succ[j + 1];
- else
- a->succ[j] = 0;
- }
- a->numsucc--;
- break;
- }
- }
-
- for (i = 0; i < b->numsucc; i++) {
- succ = IRO_NodeTable[b->succ[i]];
- for (j = 0; j < a->numsucc; j++) {
- if (b->succ[i] == a->succ[j])
- break;
- }
-
- if (j == a->numsucc) {
- AddSucc(a, IRO_NodeTable[b->succ[i]]);
- succ->numpred--;
- }
-
- found = 0;
- for (j = 0; j < succ->numpred; j++) {
- if (a->index == succ->pred[j]) {
- found = 1;
- break;
- }
- }
-
- for (j = 0; j < succ->numpred; j++) {
- if (b->index == succ->pred[j]) {
- if (!found) {
- succ->pred[j] = a->index;
- } else {
- for (k = j; k < succ->numpred; k++) {
- if ((k + 1) < succ->numpred)
- succ->pred[k] = succ->pred[k + 1];
- else
- succ->pred[k] = 0;
- }
- succ->numpred--;
- }
- break;
- }
- }
- }
-
- b->numsucc = b->numpred = 0;
- b->first = b->last = NULL;
- b->nextnode = NULL;
- b->x36 = 0;
- b->x37 = 0;
- b->mustreach = 0;
- b->x39 = 0;
- b->loopdepth = 0;
-
- if (IRO_LastNode == b)
- IRO_LastNode = a;
-
- if (IRO_FirstExpr && IRO_LastExpr) {
- IROExpr *expr;
- for (expr = IRO_FirstExpr; expr && expr != IRO_LastExpr->next; expr = expr->next) {
- if (expr->node == b)
- expr->node = a;
- }
- }
-
- if (IRO_FirstAssign && IRO_LastAssign) {
- IROAssign *assign;
- for (assign = IRO_FirstAssign; assign && assign != IRO_LastAssign->next; assign = assign->next) {
- if (assign->node == b)
- assign->node = a;
- }
- }
-
- if (IRO_FirstVarUse && IRO_LastVarUse) {
- IROUse *use;
- for (use = IRO_FirstVarUse; use && use != IRO_LastVarUse->globalnext; use = use->globalnext) {
- if (use->node == b)
- use->node = a;
- }
- }
-
- IRO_NodeTable[b->index] = NULL;
- return a;
- }
-
- return NULL;
-}
diff --git a/compiler_and_linker/unsorted/IroJump.c b/compiler_and_linker/unsorted/IroJump.c
deleted file mode 100644
index e39e3f0..0000000
--- a/compiler_and_linker/unsorted/IroJump.c
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "compiler/IroJump.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroUtil.h"
-#include "compiler/CFunc.h"
-#include "compiler/Exceptions.h"
-
-static Boolean CheckChain(CLabel **labelptr) {
- IRONode *node;
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first && node->first->type == IROLinearLabel && node->first->u.label.label == *labelptr) {
- IROLinear *linear;
- CLabel *lab;
- for (linear = node->first->next, lab = NULL; linear && (linear->type == IROLinearLabel || linear->type == IROLinearNop); linear = linear->next) {
- if (linear->type == IROLinearLabel)
- lab = linear->u.label.label;
- }
-
- if (linear->type == IROLinearGoto && *labelptr != linear->u.label.label) {
- *labelptr = linear->u.label.label;
- IRO_Dump("Chaining goto at %d\n", linear->index);
- return 1;
- }
-
- if (lab && *labelptr != lab)
- *labelptr = lab;
- return 0;
- }
- }
-
- return 0;
-}
-
-Boolean IRO_DoJumpChaining(void) {
- IRONode *node;
- IROLinear *linear;
- Boolean flag;
- SwitchInfo *info;
- SwitchCase *curcase;
- Boolean result;
-
- result = 0;
- do {
- flag = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first) {
- linear = node->last;
- switch (linear->type) {
- case IROLinearGoto:
- if (CheckChain(&linear->u.label.label))
- flag = 1;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- if (CheckChain(&linear->u.label.label))
- flag = 1;
- break;
- case IROLinearSwitch:
- info = linear->u.swtch.info;
- for (curcase = info->cases; curcase; curcase = curcase->next) {
- if (CheckChain(&curcase->label))
- flag = 1;
- }
- if (CheckChain(&info->defaultlabel))
- flag = 1;
- break;
- }
- }
- }
- result |= flag;
- IRO_CheckForUserBreak();
- } while (flag);
-
- return result;
-}
-
-void IRO_MakeReachable(IRONode *node) {
- UInt16 i;
- Boolean flag;
-
- node->x36 = 1;
- do {
- flag = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->x36 && !node->x37) {
- for (i = 0; i < node->numsucc; i++) {
- if (!IRO_NodeTable[node->succ[i]]->x36) {
- flag = 1;
- IRO_NodeTable[node->succ[i]]->x36 = 1;
- }
- }
- node->x37 = 1;
- }
- }
- } while (flag);
-}
-
-Boolean IRO_RemoveUnreachable(void) {
- IRONode *node2;
- IRONode *node1;
- IROLinear *scan;
- IROLinear *linear;
- Boolean result;
- ExceptionAction **actptr;
- ExceptionAction *act;
-
- result = 0;
- IRO_ComputeSuccPred();
- IRO_MakeReachable(IRO_FirstNode);
- node1 = IRO_FirstNode;
- for (node2 = IRO_FirstNode->nextnode; node2; node2 = node2->nextnode) {
- if (node2->first && !node2->x36) {
- IRO_Dump("Removing unreachable code at: %d\n", node2->index);
- node1->nextnode = node2->nextnode;
- node1->last->next = node2->last->next;
- result = 1;
- for (linear = node2->first; linear && linear->type == IROLinearLabel && linear != node2->last->next; linear = linear->next) {
- for (scan = IRO_FirstLinear; scan; scan = scan->next) {
- if (scan->stmt)
- scan->stmt->marked = 0;
- }
-
- for (scan = IRO_FirstLinear; scan; scan = scan->next) {
- if (scan->stmt && !scan->stmt->marked) {
- scan->stmt->marked = 1;
- for (actptr = &scan->stmt->dobjstack; (act = *actptr); actptr = &act->prev) {
- if (
- (act->type == EAT_CATCHBLOCK && act->data.catch_block.catch_label == linear->u.label.label) ||
- (act->type == EAT_SPECIFICATION && act->data.specification.unexp_label == linear->u.label.label)) {
- *actptr = act->prev;
- }
- }
- }
- }
- }
- if (node2 == IRO_LastNode)
- IRO_LastNode = node1;
- } else {
- node1 = node2;
- }
- }
-
- if (result) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
-
- IRO_CheckForUserBreak();
- return result;
-}
-
-Boolean IRO_RemoveRedundantJumps(void) {
- IRONode *node;
- IROLinear *linear;
- IROLinear *scan;
- IROLinear *scan2;
- SwitchInfo *info;
- SwitchCase *curcase;
- Boolean result;
-
- result = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first) {
- linear = node->last;
- switch (linear->type) {
- case IROLinearGoto:
- scan = linear->next;
- while (scan && ((scan->type == IROLinearNop) || (scan->type == IROLinearLabel && scan->u.label.label != linear->u.label.label)))
- scan = scan->next;
- while (1) {
- if (!scan) break;
- if (scan->type != IROLinearLabel) break;
- if (scan->u.label.label == linear->u.label.label) {
- IRO_Dump("Removing goto next at %d\n", linear->index);
- linear->type = IROLinearNop;
- result = 1;
- break;
- }
- scan = scan->next;
- }
- break;
-
- case IROLinearIf:
- case IROLinearIfNot:
- scan = linear->next;
- while (scan && scan->type == IROLinearNop)
- scan = scan->next;
- if (scan && scan->type == IROLinearGoto) {
- scan2 = scan->next;
- while (scan2 && ((scan2->type == IROLinearNop) || (scan2->type == IROLinearLabel && scan2->u.label.label != linear->u.label.label)))
- scan2 = scan2->next;
-
- if (scan2 && scan2->type == IROLinearLabel && scan2->u.label.label == linear->u.label.label) {
- if (linear->type == IROLinearIf)
- linear->type = IROLinearIfNot;
- else
- linear->type = IROLinearIf;
-
- linear->u.label.label = scan->u.label.label;
- scan->type = IROLinearNop;
- IRO_Dump("Removing branch around goto at %d\n", linear->index);
- result = 1;
- }
- }
-
- scan2 = linear->next;
- while (scan2 && ((scan2->type == IROLinearNop) || (scan2->type == IROLinearLabel && scan2->u.label.label != linear->u.label.label)))
- scan2 = scan2->next;
- while (1) {
- if (!scan2) break;
- if (scan2->type != IROLinearLabel) break;
- if (scan2->u.label.label == linear->u.label.label) {
- IRO_Dump("Removing If/IfNot_Goto next at %d\n", linear->index);
- linear->type = IROLinearNop;
- IRO_CheckSideEffect(linear->u.label.x4);
- result = 1;
- break;
- }
- scan2 = scan2->next;
- }
- break;
-
- case IROLinearSwitch:
- info = linear->u.swtch.info;
- curcase = info->cases;
- while (curcase && curcase->label == info->defaultlabel)
- curcase = curcase->next;
- if (!curcase) {
- IRO_Dump("Removing Switch next at %d\n", linear->index);
- IRO_CheckSideEffect(linear->u.swtch.x4);
- linear->type = IROLinearGoto;
- linear->u.label.label = info->defaultlabel;
- result = 1;
- }
- break;
- }
- }
- }
-
- if (result) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
-
- IRO_CheckForUserBreak();
- return result;
-}
-
-Boolean IRO_RemoveLabels(void) {
- Boolean result;
- IRONode *node;
-
- result = 0;
- IRO_ComputeSuccPred();
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first && node->first->type == IROLinearLabel && !node->x39) {
- node->first->type = IROLinearNop;
- node->first->flags &= ~IROLF_1;
- result = 1;
- }
- }
-
- IRO_CheckForUserBreak();
- return result;
-}
diff --git a/compiler_and_linker/unsorted/IroLinearForm.c b/compiler_and_linker/unsorted/IroLinearForm.c
deleted file mode 100644
index 4941587..0000000
--- a/compiler_and_linker/unsorted/IroLinearForm.c
+++ /dev/null
@@ -1,1797 +0,0 @@
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/types.h"
-
-typedef struct NullCheckListNode {
- SInt32 precompid;
- Object *tempobj;
- struct NullCheckListNode *next;
-} NullCheckListNode;
-
-IROLinear *IRO_FirstLinear;
-IROLinear *IRO_LastLinear;
-UInt32 IRO_NumLinear;
-Statement *CurStat;
-static NullCheckListNode *NullCheckList;
-static Statement *CurrStmt;
-static Statement *PrevStmt;
-
-static void LinkLinear(IROLinear *linear) {
- linear->index = IRO_NumLinear++;
- if (IRO_FirstLinear)
- IRO_LastLinear->next = linear;
- else
- IRO_FirstLinear = linear;
- IRO_LastLinear = linear;
-}
-
-IROLinear *IRO_NewLinear(IROLinearType type) {
- IROLinear *linear = oalloc(sizeof(IROLinear));
- memset(linear, 0, sizeof(IROLinear));
- linear->stmt = CurStat;
- linear->nodetype = EPOSTINC;
- linear->next = NULL;
- linear->type = type;
- linear->rtype = NULL;
- linear->flags = 0;
- linear->nodeflags = 0;
- linear->expr = NULL;
- linear->x16 = 0;
- return linear;
-}
-
-static void MarkAssigned(IROLinear *linear, Boolean flag) {
- IROLinear *inner;
- IROAddrRecord *rec;
-
- if (IS_LINEAR_MONADIC(linear, EINDIRECT) && IS_LINEAR_MONADIC(linear->u.monadic, EBITFIELD)) {
- linear->flags |= IROLF_Assigned;
- inner = linear->u.monadic->u.monadic;
- if (inner->type == IROLinearOperand) {
- inner->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- inner->flags |= IROLF_Used;
- }
- }
-
- if (IS_LINEAR_DIADIC(inner, EADD)) {
- if (IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) {
- if (IS_LINEAR_ENODE(inner->u.diadic.right, EINTCONST))
- inner->u.diadic.left->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- inner->u.diadic.left->flags |= IROLF_Used;
- }
- }
-
- rec = IRO_InitAddrRecordPointer(inner);
- IRO_DecomposeAddressExpression(inner, rec);
- if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) {
- ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Used;
- }
- }
- }
- }
-
- if (IS_LINEAR_MONADIC(linear, EINDIRECT)) {
- linear->flags |= IROLF_Assigned;
- if (linear->u.monadic->type == IROLinearOperand) {
- linear->u.monadic->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- linear->u.monadic->flags |= IROLF_Used;
- }
- }
- }
-
- if (IS_LINEAR_MONADIC(linear, EINDIRECT)) {
- linear->flags |= IROLF_Assigned;
- inner = linear->u.monadic;
-
- if (IS_LINEAR_DIADIC(inner, EADD)) {
- if (IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) {
- if (IS_LINEAR_ENODE(inner->u.diadic.right, EINTCONST))
- inner->u.diadic.left->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- inner->u.diadic.left->flags |= IROLF_Used;
- }
- }
-
- rec = IRO_InitAddrRecordPointer(inner);
- IRO_DecomposeAddressExpression(inner, rec);
- if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) {
- ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Assigned;
- if (flag) {
- linear->flags |= IROLF_Used;
- ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Used;
- }
- }
- }
- }
-}
-
-static void MarkSubscript(IROLinear *linear) {
- linear->flags |= IROLF_Subs;
- if (IS_LINEAR_DIADIC(linear, EADD)) {
- if (IRO_IsAddressMultiply(linear->u.diadic.left) || IS_LINEAR_MONADIC(linear->u.diadic.left, EINDIRECT))
- linear->u.diadic.left->flags |= IROLF_Subs;
- if (IRO_IsAddressMultiply(linear->u.diadic.right) || IS_LINEAR_MONADIC(linear->u.diadic.right, EINDIRECT))
- linear->u.diadic.right->flags |= IROLF_Subs;
-
- if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD))
- MarkSubscript(linear->u.diadic.left);
- if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD))
- MarkSubscript(linear->u.diadic.right);
- }
-}
-
-static void MarkArgs(IROLinear *linear) {
- int i;
- linear->flags |= IROLF_4000;
-
- switch (linear->type) {
- case IROLinearEnd:
- break;
- case IROLinearOp1Arg:
- case IROLinearBeginCatch:
- case IROLinearEndCatch:
- case IROLinearEndCatchDtor:
- MarkArgs(linear->u.monadic);
- break;
- case IROLinearOp2Arg:
- MarkArgs(linear->u.diadic.left);
- MarkArgs(linear->u.diadic.right);
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- MarkArgs(linear->u.label.x4);
- break;
- case IROLinearReturn:
- if (linear->u.monadic)
- MarkArgs(linear->u.monadic);
- break;
- case IROLinearSwitch:
- MarkArgs(linear->u.swtch.x4);
- break;
- case IROLinearOp3Arg:
- MarkArgs(linear->u.args3.a);
- MarkArgs(linear->u.args3.b);
- MarkArgs(linear->u.args3.c);
- break;
- case IROLinearFunccall:
- MarkArgs(linear->u.funccall.linear8);
- for (i = 0; i < linear->u.funccall.argCount; i++)
- MarkArgs(linear->u.funccall.args[i]);
- break;
- }
-}
-
-// assumed name, position
-CW_INLINE void MarkSubExpr(IROLinear *linear) {
- int i;
-
- switch (linear->type) {
- case IROLinearNop:
- case IROLinearOperand:
- case IROLinearGoto:
- case IROLinearLabel:
- case IROLinearEntry:
- case IROLinearExit:
- case IROLinearAsm:
- case IROLinearEnd:
- break;
- case IROLinearOp1Arg:
- case IROLinearBeginCatch:
- case IROLinearEndCatch:
- case IROLinearEndCatchDtor:
- linear->u.monadic->flags |= IROLF_Reffed;
- break;
- case IROLinearOp2Arg:
- linear->u.diadic.left->flags |= IROLF_Reffed;
- linear->u.diadic.right->flags |= IROLF_Reffed;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- linear->u.label.x4->flags |= IROLF_Reffed;
- break;
- case IROLinearReturn:
- if (linear->u.monadic)
- linear->u.monadic->flags |= IROLF_Reffed;
- break;
- case IROLinearSwitch:
- linear->u.swtch.x4->flags |= IROLF_Reffed;
- break;
- case IROLinearOp3Arg:
- linear->u.args3.a->flags |= IROLF_Reffed;
- linear->u.args3.b->flags |= IROLF_Reffed;
- linear->u.args3.c->flags |= IROLF_Reffed;
- break;
- case IROLinearFunccall:
- linear->u.funccall.linear8->flags |= IROLF_Reffed;
- for (i = 0; i < linear->u.funccall.argCount; i++)
- linear->u.funccall.args[i]->flags |= IROLF_Reffed;
- break;
- default:
- CError_FATAL(368);
- }
-}
-
-static void MarkSubs1(IROLinear *linear) {
- IROAddrRecord *rec;
-
- if (IS_LINEAR_MONADIC(linear, EBITFIELD)) {
- linear = linear->u.monadic;
- if (IS_LINEAR_ENODE(linear, EOBJREF))
- linear->flags |= IROLF_Ind;
- }
-
- if (IS_LINEAR_DIADIC(linear, EADD)) {
- if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF) && IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST))
- linear->u.diadic.left->flags |= IROLF_Ind;
-
- rec = IRO_InitAddrRecordPointer(linear);
- IRO_DecomposeAddressExpression(linear, rec);
- if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF))
- ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Ind;
- }
-}
-
-static void MakeLeftChildAsAssignment(ENode *enode) {
- Statement *stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = enode->data.diadic.left;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void AssignCommaRToTemp(ENode *enode, Boolean flag) {
- Statement *stmt;
-
- if (!IS_TYPE_VOID(enode->rtype) && !flag) {
- Object *obj = create_temp_object(enode->rtype);
- ENode *indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(obj);
-
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(548);
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.diadic.right;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- enode->type = EINDIRECT;
- enode->data.monadic = create_objectrefnode(obj);
- CError_ASSERT(580, !IS_TYPE_VOID(enode->rtype));
- } else {
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = enode->data.diadic.right;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- enode->type = EINTCONST;
- enode->data.intval = cint64_zero;
- }
-}
-
-static void AssignDangerousArgumentToTemp(ENode *enode) {
- Statement *stmt;
- Object *obj;
- ENode *indnode;
- ENode *rightnode;
-
- obj = create_temp_object(enode->rtype);
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(obj);
-
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(627);
-
- rightnode = IRO_NewENode(enode->type);
- memcpy(rightnode, enode, sizeof(ENode));
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = rightnode;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- enode->type = EINDIRECT;
- enode->data.monadic = create_objectrefnode(obj);
-}
-
-static void CreateTempAssignmentToZero(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
- ENode *rightnode;
-
- *objptr = create_temp_object(enode->rtype);
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(678);
-
- rightnode = IRO_NewENode(EINTCONST);
- rightnode->data.intval = cint64_zero;
- rightnode->rtype = enode->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = rightnode;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void CreateTempAssignmentToOne(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
- ENode *rightnode;
-
- *objptr = create_temp_object(enode->rtype);
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(720);
-
- rightnode = IRO_NewENode(EINTCONST);
- rightnode->data.intval = cint64_one;
- rightnode->rtype = enode->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = rightnode;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateCondExpression(ENode *enode, CLabel **label) {
- Statement *stmt;
-
- *label = IRO_NewLabel();
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFNGOTO;
- stmt->expr = enode->data.cond.cond;
- stmt->label = *label;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateGoToStmt(ENode *enode, CLabel **label) {
- Statement *stmt;
-
- *label = IRO_NewLabel();
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_GOTO;
- stmt->label = *label;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void PutTempOnNullCheckList(ENode *expr, Object *obj) {
- NullCheckListNode *n = lalloc(sizeof(NullCheckListNode));
- n->precompid = expr->data.nullcheck.precompid;
- n->tempobj = obj;
- n->next = NULL;
- if (NullCheckList) {
- n->next = NullCheckList;
- NullCheckList = n;
- } else {
- NullCheckList = n;
- }
-}
-
-static Object *GetTempFromtheList(ENode *expr) {
- NullCheckListNode *n;
-
- for (n = NullCheckList; n; n = n->next) {
- if (n->precompid == expr->data.precompid)
- break;
- }
-
- CError_ASSERT(839, n);
- return n->tempobj;
-}
-
-static void GenerateNullcheckExprTempAssignment(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
-
- if (!IS_TYPE_VOID(enode->rtype))
- *objptr = create_temp_object(enode->rtype);
- else
- *objptr = create_temp_object(enode->data.nullcheck.nullcheckexpr->rtype);
-
- PutTempOnNullCheckList(enode, *objptr);
-
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- indnode->rtype = enode->data.nullcheck.nullcheckexpr->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.nullcheck.nullcheckexpr;
- if (!IS_TYPE_VOID(enode->rtype))
- stmt->expr->rtype = enode->rtype;
- else
- stmt->expr->rtype = enode->data.nullcheck.nullcheckexpr->rtype;
-
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateExpr1TempAssignment(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
-
- if (!IS_TYPE_VOID(enode->rtype)) {
- *objptr = create_temp_object(enode->rtype);
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- indnode->rtype = enode->rtype;
- CError_ASSERT(905, !IS_TYPE_VOID(enode->rtype));
- }
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- if (!IS_TYPE_VOID(enode->rtype)) {
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.cond.expr1;
- stmt->expr->rtype = enode->rtype;
- } else {
- stmt->expr = enode->data.cond.expr1;
- }
-
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateExpr2TempAssignment(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
-
- if (!IS_TYPE_VOID(enode->rtype)) {
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- indnode->rtype = enode->rtype;
- CError_ASSERT(953, !IS_TYPE_VOID(enode->rtype));
- }
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- if (!IS_TYPE_VOID(enode->rtype)) {
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.cond.expr2;
- stmt->expr->rtype = enode->rtype;
- } else {
- stmt->expr = enode->data.cond.expr2;
- }
-
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateForceLoadTempAssignment(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
-
- if (!IS_TYPE_VOID(enode->rtype)) {
- *objptr = create_temp_object(enode->rtype);
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- indnode->rtype = enode->rtype;
- CError_ASSERT(1003, !IS_TYPE_VOID(enode->rtype));
- }
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- if (!IS_TYPE_VOID(enode->rtype)) {
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.monadic;
- stmt->expr->rtype = enode->rtype;
- } else {
- stmt->expr = enode->data.monadic;
- }
-
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateLabel(CLabel **labelptr) {
- Statement *stmt;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_LABEL;
- stmt->label = *labelptr;
- stmt->label->stmt = stmt;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateIfNotTemp(ENode *enode, Object **objptr, CLabel **labelptr) {
- Statement *stmt;
- ENode *indnode;
-
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- indnode->rtype = enode->data.monadic->rtype;
-
- *labelptr = IRO_NewLabel();
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFNGOTO;
- stmt->expr = indnode;
- stmt->label = *labelptr;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void GenerateNullcheckCondExpr(ENode *enode, Object **objptr) {
- Statement *stmt;
- ENode *indnode;
-
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- indnode->rtype = enode->data.nullcheck.nullcheckexpr->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = enode->data.nullcheck.condexpr;
- if (!IS_TYPE_VOID(enode->rtype))
- stmt->expr->rtype = enode->rtype;
- else
- stmt->expr->rtype = enode->data.nullcheck.nullcheckexpr->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void TransformLogicalAndLHS(ENode *enode, Object **objptr, CLabel **labelptr) {
- Statement *stmt;
-
- *labelptr = IRO_NewLabel();
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFNGOTO;
- stmt->expr = enode->data.diadic.left;
- stmt->label = *labelptr;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void TransformLogicalAndRHS(ENode *enode, Object **objptr, CLabel **labelptr) {
- Statement *stmt;
- ENode *indnode;
- ENode *rightnode;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFNGOTO;
- stmt->expr = enode->data.diadic.right;
- stmt->label = *labelptr;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(1225);
-
- rightnode = IRO_NewENode(EINTCONST);
- rightnode->data.intval = cint64_one;
- rightnode->rtype = enode->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = rightnode;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_LABEL;
- stmt->label = *labelptr;
- stmt->label->stmt = stmt;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- enode->type = EINDIRECT;
- enode->data.monadic = create_objectrefnode(*objptr);
- CError_ASSERT(1276, !IS_TYPE_VOID(enode->rtype));
-}
-
-static void TransformLogicalOrLHS(ENode *enode, Object **objptr, CLabel **labelptr) {
- Statement *stmt;
-
- *labelptr = IRO_NewLabel();
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFGOTO;
- stmt->expr = enode->data.diadic.left;
- stmt->label = *labelptr;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-}
-
-static void TransformLogicalOrRHS(ENode *enode, Object **objptr, CLabel **labelptr) {
- Statement *stmt;
- ENode *indnode;
- ENode *rightnode;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_IFGOTO;
- stmt->expr = enode->data.diadic.right;
- stmt->label = *labelptr;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- indnode = IRO_NewENode(EINDIRECT);
- indnode->data.monadic = create_objectrefnode(*objptr);
- if (!IS_TYPE_VOID(enode->rtype))
- indnode->rtype = enode->rtype;
- else
- CError_FATAL(1354);
-
- rightnode = IRO_NewENode(EINTCONST);
- rightnode->data.intval = cint64_zero;
- rightnode->rtype = enode->rtype;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_EXPRESSION;
- stmt->expr = IRO_NewENode(EASS);
- stmt->expr->data.diadic.left = indnode;
- stmt->expr->data.diadic.right = rightnode;
- stmt->expr->rtype = enode->rtype;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = ST_LABEL;
- stmt->label = *labelptr;
- stmt->label->stmt = stmt;
- stmt->dobjstack = CurrStmt->dobjstack;
- stmt->sourceoffset = CurrStmt->sourceoffset;
- stmt->sourcefilepath = CurrStmt->sourcefilepath;
- stmt->value = CurrStmt->value;
- stmt->flags = CurrStmt->flags;
-
- if (PrevStmt) {
- stmt->next = PrevStmt->next;
- PrevStmt->next = stmt;
- } else {
- stmt->next = NULL;
- }
- PrevStmt = stmt;
-
- enode->type = EINDIRECT;
- enode->data.monadic = create_objectrefnode(*objptr);
- CError_ASSERT(1405, !IS_TYPE_VOID(enode->rtype));
-}
-
-static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
- switch (a->type) {
- ENODE_CASE_MONADIC:
- LinearizeExpr1(a->data.monadic, a, 0, 0);
- if (a->type == EFORCELOAD) {
- Object *obj;
- GenerateForceLoadTempAssignment(a, &obj);
- a->type = EINDIRECT;
- a->data.monadic = create_objectrefnode(obj);
- CError_ASSERT(1428, !IS_TYPE_VOID(a->rtype));
- }
- break;
- ENODE_CASE_DIADIC_1:
- case ECOMMA:
- case EPMODULO:
- case EROTL:
- case EROTR:
- case EBTST:
- if (a->type == ECOMMA) {
- LinearizeExpr1(a->data.diadic.left, a, 1, 0);
- MakeLeftChildAsAssignment(a);
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- AssignCommaRToTemp(a, flag);
- } else if (a->data.diadic.right->cost >= a->data.diadic.left->cost) {
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- LinearizeExpr1(a->data.diadic.left, a, 0, 0);
- } else {
- LinearizeExpr1(a->data.diadic.left, a, 0, 0);
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- }
- break;
- ENODE_CASE_ASSIGN:
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- LinearizeExpr1(a->data.diadic.left, a, 0, 0);
- break;
- case ELAND:
- case ELOR:
- if (a->type == ELAND) {
- CLabel *label;
- Object *obj;
- CreateTempAssignmentToZero(a, &obj);
- LinearizeExpr1(a->data.diadic.left, a, 0, 0);
- TransformLogicalAndLHS(a, &obj, &label);
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- TransformLogicalAndRHS(a, &obj, &label);
- } else if (a->type == ELOR) {
- CLabel *label;
- Object *obj;
- CreateTempAssignmentToOne(a, &obj);
- LinearizeExpr1(a->data.diadic.left, a, 0, 0);
- TransformLogicalOrLHS(a, &obj, &label);
- LinearizeExpr1(a->data.diadic.right, a, 0, 0);
- TransformLogicalOrRHS(a, &obj, &label);
- }
- break;
- case ECOND: {
- CLabel *label1, *label2;
- Object *obj;
- LinearizeExpr1(a->data.cond.cond, a, 0, 0);
- GenerateCondExpression(a, &label1);
- LinearizeExpr1(a->data.cond.expr1, a, 0, 0);
- GenerateExpr1TempAssignment(a, &obj);
- GenerateGoToStmt(a, &label2);
- GenerateLabel(&label1);
- LinearizeExpr1(a->data.cond.expr2, a, 0, 0);
- GenerateExpr2TempAssignment(a, &obj);
- GenerateLabel(&label2);
- if (!IS_TYPE_VOID(a->rtype)) {
- a->type = EINDIRECT;
- a->data.monadic = create_objectrefnode(obj);
- CError_ASSERT(1596, !IS_TYPE_VOID(a->rtype));
- } else {
- a->type = EINTCONST;
- a->data.intval = cint64_zero;
- }
- break;
- }
- case EPRECOMP: {
- Object *temp = GetTempFromtheList(a);
- a->type = EINDIRECT;
- a->data.monadic = create_objectrefnode(temp);
- CError_ASSERT(1614, !IS_TYPE_VOID(a->rtype));
- break;
- }
- case ENULLCHECK: {
- CLabel *label;
- Object *obj;
- LinearizeExpr1(a->data.nullcheck.nullcheckexpr, a, 0, 0);
- GenerateNullcheckExprTempAssignment(a, &obj);
- GenerateIfNotTemp(a, &obj, &label);
- LinearizeExpr1(a->data.nullcheck.condexpr, a, 0, 0);
- GenerateNullcheckCondExpr(a, &obj);
- GenerateLabel(&label);
- if (!IS_TYPE_VOID(a->rtype)) {
- a->type = EINDIRECT;
- a->data.monadic = create_objectrefnode(obj);
- CError_ASSERT(1639, !IS_TYPE_VOID(a->rtype));
- } else {
- a->type = EINTCONST;
- a->data.intval = cint64_zero;
- }
- break;
- }
- case EFUNCCALL:
- case EFUNCCALLP: {
- SInt32 count;
- SInt32 i;
- ENodeList *list;
- ENode **arr;
- SInt16 *arr2;
-
- IRO_IsLeafFunction = 0;
-
- list = a->data.funccall.args;
- count = 0;
- while (list) {
- list = list->next;
- count++;
- }
-
- if (count) {
- arr = oalloc(sizeof(ENode *) * count);
- list = a->data.funccall.args;
- count = 0;
- while (list) {
- arr[count] = list->node;
- list = list->next;
- count++;
- }
-
- arr2 = oalloc(sizeof(SInt16) * count);
- for (i = 0; i < count; i++)
- arr2[i] = count - i - 1;
-
- for (i = 0; i < count; i++)
- LinearizeExpr1(arr[arr2[i]], a, 0, 0);
- }
-
- LinearizeExpr1(a->data.funccall.funcref, a, 0, 0);
- break;
- }
-
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case ESETCONST:
- case EVECTOR128CONST:
- break;
-
- default:
- CError_FATAL(1723);
- }
-}
-
-static IROLinear *LinearizeExpr(ENode *enode) {
- IROLinear *linear = NULL;
-
- switch (enode->type) {
- ENODE_CASE_MONADIC:
- linear = IRO_NewLinear(IROLinearOp1Arg);
- linear->u.monadic = LinearizeExpr(enode->data.monadic);
- linear->nodetype = enode->type;
- linear->rtype = enode->rtype;
- linear->nodeflags = enode->flags;
- if (IRO_IsAssignOp[linear->nodetype])
- MarkAssigned(linear->u.monadic, 1);
- if (linear->nodetype == EINDIRECT) {
- MarkSubs1(linear->u.monadic);
- linear->u.monadic->flags |= IROLF_Immind | IROLF_Ind;
- if (IS_LINEAR_DIADIC(linear->u.monadic, EADD))
- MarkSubscript(linear->u.monadic);
- }
- break;
- ENODE_CASE_DIADIC_1:
- case ECOMMA:
- case EPMODULO:
- case EROTL:
- case EROTR:
- case EBTST:
- linear = IRO_NewLinear(IROLinearOp2Arg);
- linear->nodeflags = enode->flags;
- if (!ENODE_IS(enode, ECOMMA) && enode->data.diadic.right->cost >= enode->data.diadic.left->cost) {
- linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right);
- linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left);
- linear->flags |= IROLF_8000;
- } else {
- linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left);
- linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right);
- }
- linear->nodetype = enode->type;
- linear->rtype = enode->rtype;
- if (IRO_IsAssignOp[linear->nodetype])
- MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]);
- break;
- ENODE_CASE_ASSIGN:
- linear = IRO_NewLinear(IROLinearOp2Arg);
- linear->nodeflags = enode->flags;
- linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right);
- linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left);
- linear->flags |= IROLF_8000;
- linear->nodetype = enode->type;
- linear->rtype = enode->rtype;
- MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]);
- break;
- case EINTCONST:
- case EFLOATCONST:
- case ESTRINGCONST:
- case EOBJREF:
- case EVECTOR128CONST:
- linear = IRO_NewLinear(IROLinearOperand);
- linear->nodeflags = enode->flags;
- linear->u.node = enode;
- linear->rtype = enode->rtype;
- break;
- case EFUNCCALL:
- case EFUNCCALLP: {
- SInt32 count;
- SInt32 i;
- ENodeList *list;
- ENode **arr;
- SInt16 *arr2;
-
- linear = IRO_NewLinear(IROLinearFunccall);
- linear->nodeflags = enode->flags;
- linear->u.funccall.ispascal = enode->type == EFUNCCALLP;
-
- list = enode->data.funccall.args;
- count = 0;
- while (list) {
- list = list->next;
- count++;
- }
-
- arr = NULL;
- if (count) {
- arr = oalloc(sizeof(ENode *) * count);
- list = enode->data.funccall.args;
- count = 0;
- while (list) {
- arr[count] = list->node;
- list = list->next;
- count++;
- }
-
- arr2 = oalloc(sizeof(SInt16) * count);
- for (i = 0; i < count; i++)
- arr2[i] = count - i - 1;
-
- for (i = 0; i < count; i++) {
- arr[arr2[i]] = (ENode *) LinearizeExpr(arr[arr2[i]]);
- MarkArgs((IROLinear *) arr[arr2[i]]);
- }
- }
-
- linear->u.funccall.argCount = count;
- linear->u.funccall.args = (IROLinear **) arr;
- linear->u.funccall.linear8 = LinearizeExpr(enode->data.funccall.funcref);
- linear->u.funccall.functype = enode->data.funccall.functype;
- linear->rtype = enode->rtype;
- break;
- }
- default:
- CError_FATAL(1943);
- }
-
- if (linear)
- LinkLinear(linear);
- return linear;
-}
-
-void IRO_PreLinearize(Statement *stmt) {
- IRO_FirstLinear = IRO_LastLinear = NULL;
- IRO_NumLinear = 0;
- CurrStmt = PrevStmt = NULL;
-
- while (stmt) {
- CurStat = stmt;
- CurrStmt = stmt;
- NullCheckList = NULL;
-
- switch (stmt->type) {
- case ST_NOP:
- case ST_LABEL:
- case ST_GOTO:
- break;
- case ST_OVF:
- CError_FATAL(1989);
- case ST_EXPRESSION:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_SWITCH:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_IFGOTO:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_IFNGOTO:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_RETURN:
- if (stmt->expr)
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_BEGINCATCH:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_ENDCATCH:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
- case ST_ENDCATCHDTOR:
- LinearizeExpr1(stmt->expr, NULL, 0, 0);
- break;
-
- case ST_EXIT:
- case ST_ENTRY:
- case ST_ASM:
- break;
-
- default:
- CError_FATAL(2038);
- }
-
- PrevStmt = stmt;
- stmt = stmt->next;
- }
-
- IRO_CheckForUserBreak();
-}
-
-static void MarkAllSubExprs(IROLinear *linear) {
- IROLinear *scan;
- int i;
-
- for (scan = linear; scan; scan = scan->next)
- scan->flags &= ~IROLF_Reffed;
-
- for (scan = linear; scan; scan = scan->next)
- MarkSubExpr(scan);
-}
-
-void IRO_Linearize(Statement *stmt) {
- IROLinear *linear;
-
- IRO_FirstLinear = IRO_LastLinear = NULL;
- IRO_NumLinear = 0;
-
- while (stmt) {
- CurStat = stmt;
- linear = NULL;
-
- switch (stmt->type) {
- case ST_NOP:
- linear = IRO_NewLinear(IROLinearNop);
- break;
- case ST_LABEL:
- linear = IRO_NewLinear(IROLinearLabel);
- linear->u.label.label = stmt->label;
- linear->flags |= IROLF_1;
- break;
- case ST_GOTO:
- linear = IRO_NewLinear(IROLinearGoto);
- linear->u.label.label = stmt->label;
- break;
- case ST_EXPRESSION:
- LinearizeExpr(stmt->expr);
- break;
- case ST_SWITCH:
- linear = IRO_NewLinear(IROLinearSwitch);
- linear->u.swtch.x4 = LinearizeExpr(stmt->expr);
- linear->u.swtch.info = (SwitchInfo *) stmt->label;
- break;
- case ST_IFGOTO:
- linear = IRO_NewLinear(IROLinearIf);
- linear->u.label.x4 = LinearizeExpr(stmt->expr);
- linear->u.label.label = stmt->label;
- break;
- case ST_IFNGOTO:
- linear = IRO_NewLinear(IROLinearIfNot);
- linear->u.label.x4 = LinearizeExpr(stmt->expr);
- linear->u.label.label = stmt->label;
- break;
- case ST_RETURN:
- IRO_FunctionHasReturn = 1;
- linear = IRO_NewLinear(IROLinearReturn);
- if (stmt->expr)
- linear->u.monadic = LinearizeExpr(stmt->expr);
- else
- linear->u.monadic = NULL;
- break;
- case ST_OVF:
- CError_FATAL(2143);
- break;
- case ST_EXIT:
- linear = IRO_NewLinear(IROLinearExit);
- linear->u.label.label = stmt->label;
- break;
- case ST_ENTRY:
- linear = IRO_NewLinear(IROLinearEntry);
- linear->u.label.label = stmt->label;
- linear->flags |= IROLF_1;
- break;
- case ST_BEGINCATCH:
- linear = IRO_NewLinear(IROLinearBeginCatch);
- linear->u.ctch.linear = LinearizeExpr(stmt->expr);
- linear->u.ctch.x4 = 0;
- linear->u.ctch.x8 = 0;
- break;
- case ST_ENDCATCH:
- linear = IRO_NewLinear(IROLinearEndCatch);
- linear->u.monadic = LinearizeExpr(stmt->expr);
- break;
- case ST_ENDCATCHDTOR:
- linear = IRO_NewLinear(IROLinearEndCatchDtor);
- linear->u.monadic = LinearizeExpr(stmt->expr);
- break;
- case ST_ASM:
- linear = IRO_NewLinear(IROLinearAsm);
- linear->u.asm_stmt = stmt;
- if (copts.optimizewithasm) {
- IAEffects effects;
- CodeGen_GetAsmEffects(stmt, &effects);
- if (effects.x0 || effects.x3)
- DisableDueToAsm = 1;
- } else {
- DisableDueToAsm = 1;
- }
- break;
- default:
- CError_FATAL(2194);
- }
-
- if (linear)
- LinkLinear(linear);
- stmt = stmt->next;
- }
-
- linear = IRO_NewLinear(IROLinearEnd);
- linear->flags |= IROLF_1;
- LinkLinear(linear);
-
- MarkAllSubExprs(IRO_FirstLinear);
- IRO_CheckForUserBreak();
-}
-
-static Statement *NewStatement(IROLinear *linear, StatementType sttype) {
- Statement *stmt = lalloc(sizeof(Statement));
- memset(stmt, 0, sizeof(Statement));
- stmt->type = sttype;
- stmt->value = 1;
- if (linear->stmt) {
- stmt->dobjstack = linear->stmt->dobjstack;
- stmt->sourceoffset = linear->stmt->sourceoffset;
- stmt->sourcefilepath = linear->stmt->sourcefilepath;
- stmt->value = linear->stmt->value;
- stmt->flags = linear->stmt->flags;
- } else {
- stmt->sourceoffset = -1;
- stmt->sourcefilepath = NULL;
- }
- return stmt;
-}
-
-ENode *IRO_NewENode(ENodeType nodetype) {
- ENode *enode = lalloc(sizeof(ENode));
- memset(enode, 0, sizeof(ENode));
- enode->type = nodetype;
- return enode;
-}
-
-static ENode *BuildExpr(IROLinear *linear) {
- ENode *enode;
-
- switch (linear->type) {
- case IROLinearOperand:
- enode = IRO_NewENode(linear->u.node->type);
- enode->flags = linear->nodeflags;
- *enode = *linear->u.node;
- break;
- case IROLinearOp1Arg:
- enode = IRO_NewENode(linear->nodetype);
- enode->flags = linear->nodeflags;
- enode->data.monadic = BuildExpr(linear->u.monadic);
- enode->rtype = linear->rtype;
- enode->cost = enode->data.monadic->cost;
- if (!enode->cost)
- enode->cost = 1;
- break;
- case IROLinearOp2Arg:
- enode = IRO_NewENode(linear->nodetype);
- enode->flags = linear->nodeflags;
- enode->data.diadic.left = BuildExpr(linear->u.diadic.left);
- enode->data.diadic.right = BuildExpr(linear->u.diadic.right);
-
- enode->cost = enode->data.diadic.left->cost;
- if (enode->data.diadic.right->cost > enode->cost)
- enode->cost = enode->data.diadic.right->cost;
- else if (enode->data.diadic.right->cost == enode->cost)
- enode->cost += 1;
-
- if (ENODE_IS4(enode, ESHL, ESHR, EDIV, EMODULO))
- enode->cost += 2;
- if (enode->cost > 200)
- enode->cost = 200;
-
- enode->rtype = linear->rtype;
- break;
- case IROLinearOp3Arg:
- enode = IRO_NewENode(linear->nodetype);
- enode->flags = linear->nodeflags;
- enode->data.cond.cond = BuildExpr(linear->u.args3.a);
- enode->data.cond.expr1 = BuildExpr(linear->u.args3.b);
- enode->data.cond.expr2 = BuildExpr(linear->u.args3.c);
- enode->rtype = linear->rtype;
-
- enode->cost = enode->data.cond.cond->cost;
- if (enode->data.cond.expr1->cost > enode->cost)
- enode->cost = enode->data.cond.expr1->cost;
- if (enode->data.cond.expr2->cost > enode->cost)
- enode->cost = enode->data.cond.expr2->cost;
- enode->cost += 1;
-
- if (enode->cost > 200)
- enode->cost = 200;
-
- break;
-
- case IROLinearFunccall: {
- int i;
- enode = IRO_NewENode(linear->u.funccall.ispascal ? EFUNCCALLP : EFUNCCALL);
- enode->flags = linear->nodeflags;
- enode->data.funccall.funcref = BuildExpr(linear->u.funccall.linear8);
- enode->data.funccall.functype = linear->u.funccall.functype;
- enode->data.funccall.args = NULL;
- enode->cost = 200;
- for (i = linear->u.funccall.argCount - 1; i >= 0; i--) {
- ENodeList *list = lalloc(sizeof(ENodeList));
- list->node = BuildExpr(linear->u.funccall.args[i]);
- list->next = enode->data.funccall.args;
- enode->data.funccall.args = list;
- }
- enode->rtype = linear->rtype;
- break;
- }
-
- default:
- IRO_Dump("Oh, oh, bad expression type in BuildExpr at: %d\n", linear->index);
- CError_FATAL(2390);
- }
-
- enode->pointsTo = linear->pointsToFunction;
- return enode;
-}
-
-Statement *IRO_Delinearize(IRONode *node, IROLinear *linear) {
- IROLinear *scanlin;
- Statement *firstStmt;
- Statement *lastStmt;
- IRONode *scan;
- Statement *stmt;
- IRONode mynode;
-
- firstStmt = lastStmt = NULL;
-
- if (node) {
- scan = node;
- MarkAllSubExprs(IRO_FirstLinear);
- } else {
- memset(&mynode, 0, sizeof(IRONode));
- mynode.first = linear;
- scan = &mynode;
- MarkAllSubExprs(linear);
- }
-
- while (scan) {
- for (scanlin = scan->first; scanlin; scanlin = scanlin->next) {
- stmt = NULL;
- if (!(scanlin->flags & IROLF_Reffed)) {
- switch (scanlin->type) {
- case IROLinearNop:
- if (scan == node)
- stmt = NewStatement(scanlin, ST_NOP);
- else
- stmt = NULL;
- break;
- case IROLinearOperand:
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- case IROLinearOp3Arg:
- case IROLinearFunccall:
- stmt = NewStatement(scanlin, ST_EXPRESSION);
- stmt->expr = BuildExpr(scanlin);
- break;
- case IROLinearGoto:
- stmt = NewStatement(scanlin, ST_GOTO);
- stmt->label = scanlin->u.label.label;
- break;
- case IROLinearExit:
- stmt = NewStatement(scanlin, ST_EXIT);
- stmt->label = scanlin->u.label.label;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- stmt = NewStatement(scanlin, (scanlin->type == IROLinearIf) ? ST_IFGOTO : ST_IFNGOTO);
- stmt->label = scanlin->u.label.label;
- stmt->expr = BuildExpr(scanlin->u.label.x4);
- break;
- case IROLinearReturn:
- stmt = NewStatement(scanlin, ST_RETURN);
- if (scanlin->u.monadic)
- stmt->expr = BuildExpr(scanlin->u.monadic);
- break;
- case IROLinearLabel:
- stmt = NewStatement(scanlin, ST_LABEL);
- stmt->label = scanlin->u.label.label;
- stmt->label->stmt = stmt;
- break;
- case IROLinearEntry:
- stmt = NewStatement(scanlin, ST_ENTRY);
- stmt->label = scanlin->u.label.label;
- stmt->label->stmt = stmt;
- break;
- case IROLinearSwitch:
- stmt = NewStatement(scanlin, ST_SWITCH);
- stmt->expr = BuildExpr(scanlin->u.swtch.x4);
- stmt->label = (CLabel *) scanlin->u.swtch.info;
- break;
- case IROLinearBeginCatch:
- stmt = NewStatement(scanlin, ST_BEGINCATCH);
- stmt->expr = BuildExpr(scanlin->u.ctch.linear);
- break;
- case IROLinearEndCatch:
- stmt = NewStatement(scanlin, ST_ENDCATCH);
- stmt->expr = BuildExpr(scanlin->u.monadic);
- break;
- case IROLinearEndCatchDtor:
- stmt = NewStatement(scanlin, ST_ENDCATCHDTOR);
- stmt->expr = BuildExpr(scanlin->u.monadic);
- break;
- case IROLinearAsm:
- stmt = scanlin->u.asm_stmt;
- break;
- case IROLinearEnd:
- stmt = NULL;
- break;
- default:
- CError_FATAL(2685);
- }
-
- if (stmt) {
- if (LoopOptimizerRun) {
- SInt32 i;
- SInt32 value = 1;
- for (i = 0; i < scan->loopdepth; i++) {
- value = (value < 4096) ? (value * 8) : (value + 1);
- }
- stmt->value = value;
- }
- if (firstStmt)
- lastStmt->next = stmt;
- else
- firstStmt = stmt;
- lastStmt = stmt;
- }
- }
- if (scanlin == scan->last)
- break;
- }
- scan = scan->nextnode;
- }
-
- return firstStmt;
-}
-
-void IRO_RenumberInts(void) {
- IROLinear *linear = IRO_FirstLinear;
- IRO_NumLinear = 0;
- while (linear) {
- linear->index = IRO_NumLinear++;
- linear = linear->next;
- }
-}
-
-static void TravExprToUpdateFlags(IROLinear *linear) {
- int i;
-
- linear->flags &= ~(IROLF_Assigned | IROLF_8 | IROLF_Used | IROLF_Ind | IROLF_Subs | IROLF_LoopInvariant | IROLF_Ris | IROLF_Immind | IROLF_CouldError);
- switch (linear->type) {
- case IROLinearNop:
- case IROLinearOperand:
- break;
- case IROLinearOp1Arg:
- TravExprToUpdateFlags(linear->u.monadic);
- if (IRO_IsAssignOp[linear->nodetype])
- MarkAssigned(linear->u.monadic, 1);
- if (linear->nodetype == EINDIRECT) {
- MarkSubs1(linear->u.monadic);
- linear->u.monadic->flags |= IROLF_Immind | IROLF_Ind;
- if (IS_LINEAR_DIADIC(linear->u.monadic, EADD))
- MarkSubscript(linear->u.monadic);
- }
- break;
- case IROLinearOp2Arg:
- TravExprToUpdateFlags(linear->u.diadic.left);
- TravExprToUpdateFlags(linear->u.diadic.right);
- if (IRO_IsAssignOp[linear->nodetype])
- MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]);
- break;
- case IROLinearOp3Arg:
- TravExprToUpdateFlags(linear->u.args3.a);
- TravExprToUpdateFlags(linear->u.args3.b);
- TravExprToUpdateFlags(linear->u.args3.c);
- break;
- case IROLinearFunccall:
- TravExprToUpdateFlags(linear->u.funccall.linear8);
- for (i = linear->u.funccall.argCount - 1; i >= 0; i--)
- TravExprToUpdateFlags(linear->u.funccall.args[i]);
- break;
- default:
- IRO_Dump("Oh, oh, bad expression type in TravExprToUpdateFlags at: %d\n", linear->index);
- CError_FATAL(2853);
- }
-}
-
-void IRO_UpdateFlagsOnInts(void) {
- IROLinear *linear;
- IRONode *node;
-
- MarkAllSubExprs(IRO_FirstLinear);
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- for (linear = node->first; linear; linear = linear->next) {
- if (!(linear->flags & IROLF_Reffed)) {
- switch (linear->type) {
- case IROLinearOperand:
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- case IROLinearOp3Arg:
- case IROLinearFunccall:
- TravExprToUpdateFlags(linear);
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- TravExprToUpdateFlags(linear->u.label.x4);
- break;
- case IROLinearReturn:
- if (linear->u.monadic)
- TravExprToUpdateFlags(linear->u.monadic);
- break;
- case IROLinearSwitch:
- TravExprToUpdateFlags(linear->u.swtch.x4);
- break;
- case IROLinearBeginCatch:
- TravExprToUpdateFlags(linear->u.ctch.linear);
- break;
- case IROLinearEndCatch:
- TravExprToUpdateFlags(linear->u.monadic);
- break;
- case IROLinearEndCatchDtor:
- TravExprToUpdateFlags(linear->u.monadic);
- break;
- case IROLinearNop:
- case IROLinearGoto:
- case IROLinearLabel:
- case IROLinearEntry:
- case IROLinearExit:
- case IROLinearAsm:
- case IROLinearEnd:
- break;
- default:
- CError_FATAL(2931);
- }
- }
- if (linear == node->last)
- break;
- }
- }
-}
-
-void IRO_SaveLinearIR(IROLinearIRSave *save) {
- save->firstLinear = IRO_FirstLinear;
- save->lastLinear = IRO_LastLinear;
- save->numLinear = IRO_NumLinear;
- save->curStat = CurStat;
- save->disableDueToAsm = DisableDueToAsm;
- save->isLeafFunction = IRO_IsLeafFunction;
- save->functionHasReturn = IRO_FunctionHasReturn;
- save->nullCheckList = NullCheckList;
- save->currStmt = CurrStmt;
- save->prevStmt = PrevStmt;
-}
-
-void IRO_RestoreLinearIR(IROLinearIRSave *save) {
- IRO_FirstLinear = save->firstLinear;
- IRO_LastLinear = save->lastLinear;
- IRO_NumLinear = save->numLinear;
- CurStat = save->curStat;
- DisableDueToAsm = save->disableDueToAsm;
- IRO_IsLeafFunction = save->isLeafFunction;
- IRO_FunctionHasReturn = save->functionHasReturn;
- NullCheckList = save->nullCheckList;
- CurrStmt = save->currStmt;
- PrevStmt = save->prevStmt;
-}
-
diff --git a/compiler_and_linker/unsorted/IroLoop.c b/compiler_and_linker/unsorted/IroLoop.c
deleted file mode 100644
index d6ec5f0..0000000
--- a/compiler_and_linker/unsorted/IroLoop.c
+++ /dev/null
@@ -1,2324 +0,0 @@
-#include "compiler/IroLoop.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroPropagate.h"
-#include "compiler/IroSubable.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-IRONode *LoopNode;
-Boolean ConditionalHeaderAtBottom;
-IROLoopInd *FirstInd;
-BitVector *InLoop;
-IROList IRO_InitLList;
-BitVector *InLoop_Exits;
-BitVector *InLoop_Tails;
-UInt32 LoopExitNumber;
-UInt32 LoopTailNum;
-IRONode *LoopExitSuccessor;
-IRONode *LoopTail;
-IROLoopMemRef *IRO_LoopMemRefFirst;
-IROLoopMemRef *IRO_LoopMemRefCurrent;
-static IROExpr *RisList;
-static BitVector *AllKills;
-static Boolean KnownBounds;
-static SInt32 Times;
-static IROLinear *PredInt;
-static IROElmList *FirstAddendLinear;
-static IROElmList *LastAddendLinear;
-static int NoSubableSubs;
-
-// forward decls
-static void MyHandleLoop_Vector(IRONode *fnode);
-static void MyHandleLoop_Motion(IRONode *fnode);
-static void CheckAllLoopAddresses(IRONode *fnode, BitVector *bv, Boolean *resultFlag);
-static void MakeLoopEntry(IROLinear *nd, IROAddrRecord *rec, Boolean mustreach1, Boolean flag2);
-static void MoveInvarianceInAddressExpr(void);
-static IROLinear *RearrangeInvarianceInAddressExpr(IROLinear *nd, IROList *list);
-static UInt32 IsAssignmentReductionCandidate(IROLinear *nd);
-
-void FindMustReach(void) {
- IRONode *fnode;
- IRONode *fnode2;
- IRONode *pred;
- int i;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- fnode->mustreach = 0;
- if (Bv_IsBitSet(fnode->index, InLoop)) {
- fnode->mustreach = 1;
-
- for (i = 0; i < LoopNode->numpred; i++) {
- pred = IRO_NodeTable[LoopNode->pred[i]];
- if (Bv_IsBitSet(pred->index, InLoop) && !Bv_IsBitSet(fnode->index, pred->dom)) {
- fnode->mustreach = 0;
- break;
- }
- }
-
- for (fnode2 = IRO_FirstNode; fnode2; fnode2 = fnode2->nextnode) {
- if (Bv_IsBitSet(fnode2->index, InLoop)) {
- for (i = 0; i < fnode2->numsucc; i++) {
- if (!Bv_IsBitSet(fnode2->succ[i], InLoop) && !Bv_IsBitSet(fnode->index, fnode2->dom)) {
- fnode->mustreach = 0;
- break;
- }
- }
-
- if (!fnode->mustreach)
- break;
- }
- }
- }
- }
-}
-
-void FindMustReach1(IRONode *checkfnode) {
- IRONode *fnode;
- IRONode *fnode2;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop)) {
- fnode->mustreach1 = 1;
- for (fnode2 = IRO_FirstNode; fnode2; fnode2 = fnode2->nextnode) {
- if (Bv_IsBitSet(fnode2->index, InLoop)) {
- if (Bv_IsBitSet(fnode2->index, InLoop_Tails) && !Bv_IsBitSet(fnode->index, fnode2->dom))
- fnode->mustreach1 = 0;
-
- if (Bv_IsBitSet(fnode2->index, InLoop_Exits) && fnode2 != checkfnode && !Bv_IsBitSet(fnode->index, fnode2->dom))
- fnode->mustreach1 = 0;
-
- if (!fnode->mustreach1)
- break;
- }
- }
- }
- }
-}
-
-static void IRO_FindLoopTailsAndExits(IRONode *fnode) {
- IRONode *scan;
- IRONode *succ;
- int i;
-
- for (scan = IRO_FirstNode; scan; scan = scan->nextnode) {
- if (Bv_IsBitSet(scan->index, InLoop)) {
- for (i = 0; i < scan->numsucc; i++) {
- succ = IRO_NodeTable[scan->succ[i]];
- if (succ == fnode) {
- Bv_SetBit(scan->index, InLoop_Tails);
- LoopTail = scan;
- LoopTailNum++;
- }
- if (!Bv_IsBitSet(succ->index, InLoop)) {
- LoopExitNumber++;
- LoopExitSuccessor = succ;
- Bv_SetBit(scan->index, InLoop_Exits);
- }
- }
- }
- }
-
- IRO_Dump("IRO_FindLoopTailsAndExits:For header %d, Loop exits and loop tails are \n", fnode->index);
- IRO_DumpBits("Loop Exits: ", InLoop_Exits);
- IRO_DumpBits("Loop Tails: ", InLoop_Tails);
- IRO_Dump("LoopExitNum=%d: \n", LoopExitNumber);
- if (LoopExitSuccessor)
- IRO_Dump("LoopExitSuccessor node =%d: \n", LoopExitSuccessor->index);
-}
-
-static int IsSafeTypcon(IROLinear *nd) {
- Type *srcType;
- Type *destType;
- SInt32 srcSize;
- SInt32 destSize;
- Boolean srcUnsigned;
- Boolean destUnsigned;
-
- srcType = nd->u.monadic->rtype;
- destType = nd->rtype;
- if (!IS_TYPE_INT(srcType) || !IS_TYPE_INT(destType))
- return 0;
-
- srcSize = srcType->size;
- destSize = destType->size;
- srcUnsigned = IRO_IsUnsignedType(srcType);
- destUnsigned = IRO_IsUnsignedType(destType);
-
- if (srcUnsigned == destUnsigned && destSize >= srcSize)
- return 1;
- if (srcUnsigned == 1 && destUnsigned == 0 && destSize > srcSize)
- return 1;
- return 0;
-}
-
-static int Reducable(IROLinear *nd, IROLinear **resultNd1, IROLinear **resultNd2, VarRecord **resultVar) {
- IROLinear *indirect;
- IROLinear *left;
- IROLinear *right;
- Boolean leftInvariant;
- Boolean rightInvariant;
- Boolean leftTypcon;
- Boolean rightTypcon;
- Object *obj;
- ENode *enode;
- IROLoopInd *ind;
- CInt64 val64;
- SInt32 val;
- SInt32 div;
-
- leftInvariant = 0;
- rightInvariant = 0;
- leftTypcon = 0;
- rightTypcon = 0;
-
- if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD && (IS_TYPE_INT(nd->rtype) || IS_TYPE_POINTER_ONLY(nd->rtype))) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON) {
- leftTypcon = 1;
- leftInvariant = (left->flags & IROLF_LoopInvariant) != 0;
- left = left->u.monadic;
- }
- if (right->type == IROLinearOp1Arg && right->nodetype == ETYPCON) {
- rightTypcon = 1;
- rightInvariant = (right->flags & IROLF_LoopInvariant) != 0;
- right = right->u.monadic;
- }
-
- if (((left->flags & IROLF_LoopInvariant) || leftInvariant) && IRO_IsVariable(right)) {
- if (leftInvariant || ((!(obj = IRO_IsVariable(left)) || !IRO_IsRegable(obj)) && !IRO_IsConstant(left))) {
- if (
- left->type == IROLinearOp2Arg &&
- left->nodetype == EADD &&
- (obj = IRO_IsVariable(left->u.diadic.left)) &&
- IRO_IsRegable(obj) &&
- IRO_IsConstant(left->u.diadic.right)
- )
- return 0;
-
- if (rightTypcon) {
- if (!IsSafeTypcon(nd->u.diadic.right))
- return 0;
- *resultNd2 = nd->u.diadic.right;
- } else {
- *resultNd2 = right;
- }
-
- indirect = right;
- *resultNd1 = IRO_NewLinear(IROLinearOperand);
-
- enode = IRO_NewENode(EINTCONST);
- enode->data.intval = cint64_one;
- enode->rtype = nd->u.diadic.right->rtype;
- (*resultNd1)->rtype = nd->u.diadic.right->rtype;
- (*resultNd1)->u.node = enode;
- } else {
- return 0;
- }
- } else if (
- ((left->flags & IROLF_LoopInvariant) || leftInvariant) &&
- right->type == IROLinearOp2Arg &&
- !rightTypcon &&
- (right->nodetype == EMUL || right->nodetype == ESHL)
- ) {
- if (IRO_IsConstant(right->u.diadic.right)) {
- if (right->nodetype == ESHL) {
- right->nodetype = EMUL;
- right->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_one, right->u.diadic.right->u.node->data.intval);
- }
- if (right->u.diadic.left->type == IROLinearOp1Arg) {
- if (IRO_IsVariable(right->u.diadic.left)) {
- *resultNd2 = right->u.diadic.left;
- indirect = right->u.diadic.left;
- *resultNd1 = right->u.diadic.right;
- } else if (right->u.diadic.left->nodetype == ETYPCON && IRO_IsVariable(right->u.diadic.left->u.monadic)) {
- if (!IsSafeTypcon(right->u.diadic.left))
- return 0;
- *resultNd2 = right->u.diadic.left;
- indirect = right->u.diadic.left->u.monadic;
- *resultNd1 = right->u.diadic.right;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else if (
- ((right->flags & IROLF_LoopInvariant) || rightInvariant) &&
- left->type == IROLinearOp2Arg &&
- !leftTypcon &&
- (left->nodetype == EMUL || left->nodetype == ESHL)
- ) {
- if (IRO_IsConstant(left->u.diadic.right)) {
- if (left->nodetype == ESHL) {
- left->nodetype = EMUL;
- left->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_one, left->u.diadic.right->u.node->data.intval);
- }
- if (left->u.diadic.left->type == IROLinearOp1Arg) {
- if (IRO_IsVariable(left->u.diadic.left)) {
- *resultNd2 = left->u.diadic.left;
- indirect = left->u.diadic.left;
- *resultNd1 = left->u.diadic.right;
- } else if (left->u.diadic.left->nodetype == ETYPCON && IRO_IsVariable(left->u.diadic.left->u.monadic)) {
- if (!IsSafeTypcon(left->u.diadic.left))
- return 0;
- *resultNd2 = left->u.diadic.left;
- indirect = left->u.diadic.left->u.monadic;
- *resultNd1 = left->u.diadic.right;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else if (
- ((right->flags & IROLF_LoopInvariant) || rightInvariant) &&
- IRO_IsVariable(left)
- ) {
- if (rightInvariant || ((!(obj = IRO_IsVariable(right)) || !IRO_IsRegable(obj)) && !IRO_IsConstant(right))) {
- if (
- right->type == IROLinearOp2Arg &&
- right->nodetype == EADD &&
- (obj = IRO_IsVariable(right->u.diadic.left)) &&
- IRO_IsRegable(obj) &&
- IRO_IsConstant(right->u.diadic.right)
- )
- return 0;
-
- if (leftTypcon) {
- if (!IsSafeTypcon(nd->u.diadic.left))
- return 0;
- *resultNd2 = nd->u.diadic.left;
- } else {
- *resultNd2 = left;
- }
-
- indirect = left;
- *resultNd1 = IRO_NewLinear(IROLinearOperand);
-
- enode = IRO_NewENode(EINTCONST);
- enode->data.intval = cint64_one;
- enode->rtype = nd->u.diadic.left->rtype;
- (*resultNd1)->rtype = nd->u.diadic.left->rtype;
- (*resultNd1)->u.node = enode;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else if (nd->type == IROLinearOp2Arg && (nd->nodetype == EMUL || nd->nodetype == ESHL) && nd->rtype->size <= 4 && (IS_TYPE_INT(nd->rtype) || IS_TYPE_POINTER_ONLY(nd->rtype))) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
-
- if (IRO_IsConstant(right) && IRO_IsVariable(left)) {
- *resultNd2 = left;
- indirect = left;
- *resultNd1 = right;
- } else if (IRO_IsConstant(nd->u.diadic.right) && left->type == IROLinearOp1Arg && left->nodetype == ETYPCON &&
- IRO_IsVariable(left->u.monadic)) {
- if (!IsSafeTypcon(left))
- return 0;
- *resultNd2 = left;
- indirect = left->u.monadic;
- *resultNd1 = right;
- } else {
- if (nd->type == IROLinearOp2Arg && nd->nodetype == ESHL)
- return 0;
-
- if (nd->u.diadic.right->flags & IROLF_LoopInvariant) {
- if (IRO_IsVariable(left)) {
- *resultNd2 = left;
- indirect = left;
- *resultNd1 = right;
- } else if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON && IRO_IsVariable(left->u.monadic)) {
- if (!IsSafeTypcon(left))
- return 0;
- *resultNd2 = left;
- indirect = left->u.monadic;
- *resultNd1 = right;
- } else {
- return 0;
- }
- } else if (nd->u.diadic.left->flags & IROLF_LoopInvariant) {
- if (IRO_IsVariable(right)) {
- *resultNd2 = right;
- indirect = right;
- *resultNd1 = left;
- } else if (right->type == IROLinearOp1Arg && right->nodetype == ETYPCON && IRO_IsVariable(right->u.monadic) && nd->type == IROLinearOp2Arg && nd->nodetype == EMUL) {
- if (!IsSafeTypcon(right))
- return 0;
- *resultNd2 = right;
- indirect = right->u.monadic;
- *resultNd1 = left;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
- } else if (nd->type == IROLinearOp2Arg && (nd->nodetype == EDIV || nd->nodetype == ESHR) && nd->rtype->size <= 4 && IS_TYPE_INT(nd->rtype)) {
- if (IRO_IsVariable(nd->u.diadic.left) && IRO_IsConstant(nd->u.diadic.right)) {
- val64 = nd->u.diadic.right->u.node->data.intval;
- if (nd->type == IROLinearOp2Arg && nd->nodetype == ESHR) {
- CInt64_GetULong(&val64);
- if (CInt64_GetULong(&val64) > 32 || CTool_EndianReadWord32(&val64.hi))
- return 0;
- val64 = CInt64_Shl(cint64_one, val64);
- }
- *resultNd2 = nd->u.diadic.left;
- indirect = nd->u.diadic.left;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
-
- if (
- nd->type == IROLinearOp2Arg &&
- nd->nodetype == ESHL &&
- (
- !IRO_IsConstant(*resultNd1) ||
- (SInt32) CInt64_GetULong(&(*resultNd1)->u.node->data.intval) < 0 ||
- (SInt32) CInt64_GetULong(&(*resultNd1)->u.node->data.intval) > 32 ||
- CTool_EndianReadWord32(&(*resultNd1)->u.node->data.intval.hi)
- )
- )
- return 0;
-
- CError_ASSERT(802, indirect->u.monadic->u.node != NULL);
- *resultVar = IRO_FindVar(indirect->u.monadic->u.node->data.objref, 0, 1);
- if (!*resultVar || (*resultVar)->xA != 2)
- return 0;
-
- if (copts.ANSIstrict || copts.strengthreductionstrict) {
- Type *type = (*resultVar)->object->type;
- if (IRO_IsUnsignedType(type) && type->size < stunsignedlong.size)
- return 0;
- }
-
- if (nd->type == IROLinearOp2Arg && (nd->nodetype == ESHR || nd->nodetype == EDIV)) {
- ind = FirstInd;
- while (ind && ind->var != *resultVar)
- ind = ind->next;
-
- CError_ASSERT(845, ind != NULL);
-
- if (ind->addNode == NULL) {
- if (ind->addConst < (val = CInt64_GetULong(&val64)))
- return 0;
- if ((div = ind->addConst / val) <= 0)
- return 0;
-
- *resultNd1 = IRO_NewLinear(IROLinearOperand);
- enode = IRO_NewENode(EINTCONST);
- CInt64_SetULong(&enode->data.intval, div);
- enode->rtype = nd->u.diadic.left->rtype;
- (*resultNd1)->rtype = nd->u.diadic.left->rtype;
- (*resultNd1)->u.node = enode;
- } else {
- return 0;
- }
- }
-
- return 1;
-}
-
-static void IRO_RemoveExpr_Action(IROLinear *linear, Boolean isFirst) {
- if (isFirst && linear->expr)
- IRO_RemoveExpr(linear->expr);
-}
-
-static void IRO_ActUnmarkRISCandidate(IROLinear *linear, Boolean isFirst) {
- if (isFirst && linear->expr)
- linear->flags &= ~IROLF_Ris;
-}
-
-static IROExpr *CreateRIS(IROExpr *expr, IROLinear *nd1, IROLinear *nd2, IROLoopInd *induction, int unk) {
- Object *tempObj;
- Type *type;
- Boolean flag23;
- Object *tempObj2;
- IROLinear *firstnode;
- IROLinear *fourthnode;
- IROLinear *fifthnode;
- IROLinear *secondnode;
- IROLinear *thirdnode;
- IROLinear *tmp;
- ENode *enode;
- IROList list1;
- IROList list2;
-
- flag23 = 0;
- type = expr->linear->rtype;
- tempObj = create_temp_object(type);
- IRO_FindVar(tempObj, 1, 1);
- IRO_InitList(&list1);
-
- if (IS_LINEAR_DIADIC(expr->linear, EADD)) {
- firstnode = IRO_DuplicateExpr(expr->linear, &list1);
- } else if (IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR)) {
- firstnode = IRO_DuplicateExpr(expr->linear, &list1);
- } else {
- firstnode = IRO_NewLinear(IROLinearOp2Arg);
- firstnode->index = ++IRO_NumLinear;
- firstnode->rtype = type;
- firstnode->nodetype = EMUL;
- firstnode->u.diadic.left = IRO_DuplicateExpr(nd1, &list1);
- if (unk)
- firstnode->u.diadic.right = IRO_DuplicateExpr(nd1, &list1);
- else
- firstnode->u.diadic.right = IRO_DuplicateExpr(nd2, &list1);
- IRO_AddToList(firstnode, &list1);
- }
-
- secondnode = IRO_NewLinear(IROLinearOp2Arg);
- secondnode->index = ++IRO_NumLinear;
- secondnode->rtype = type;
- secondnode->nodetype = EASS;
- secondnode->u.diadic.left = IRO_TempReference(tempObj, &list1);
- secondnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned;
- secondnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned;
- secondnode->u.diadic.right = firstnode;
- IRO_AddToList(secondnode, &list1);
- IRO_Paste(list1.head, list1.tail, PredInt);
- if (
- !IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR) &&
- induction->addConst != 1 &&
- (induction->addNode || !IRO_IsConstant(nd2))
- ) {
- flag23 = 1;
- IRO_InitList(&list1);
- thirdnode = IRO_NewLinear(IROLinearOp2Arg);
- thirdnode->index = ++IRO_NumLinear;
- thirdnode->rtype = nd2->rtype;
- thirdnode->nodetype = EMUL;
-
- if (!induction->addNode) {
- thirdnode->u.diadic.left = IRO_DuplicateExpr(nd2, &list1);
- thirdnode->u.diadic.right = IRO_NewLinear(IROLinearOperand);
- thirdnode->u.diadic.right->index = ++IRO_NumLinear;
- enode = IRO_NewENode(EINTCONST);
- enode->rtype = nd2->rtype;
- thirdnode->u.diadic.right->rtype = nd2->rtype;
- CInt64_SetLong(&enode->data.intval, induction->addConst);
- thirdnode->u.diadic.right->u.node = enode;
- IRO_AddToList(thirdnode->u.diadic.right, &list1);
- } else {
- thirdnode->u.diadic.left = IRO_DuplicateExpr(nd2, &list1);
- thirdnode->u.diadic.right = IRO_DuplicateExpr(induction->addNode, &list1);
- if (nd2->rtype != induction->addNode->rtype) {
- tmp = IRO_NewLinear(IROLinearOp1Arg);
- tmp->nodetype = ETYPCON;
- tmp->index = ++IRO_NumLinear;
- tmp->rtype = nd2->rtype;
- tmp->u.monadic = thirdnode->u.diadic.right;
- IRO_AddToList(tmp, &list1);
- thirdnode->u.diadic.right = tmp;
- }
- }
- IRO_AddToList(thirdnode, &list1);
-
- tempObj2 = create_temp_object(nd2->rtype);
-
- fourthnode = IRO_NewLinear(IROLinearOp2Arg);
- fourthnode->index = ++IRO_NumLinear;
- fourthnode->rtype = nd2->rtype;
- fourthnode->nodetype = EASS;
- fourthnode->u.diadic.left = IRO_TempReference(tempObj2, &list1);
- fourthnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned;
- fourthnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned;
- fourthnode->u.diadic.right = thirdnode;
- IRO_AddToList(fourthnode, &list1);
- IRO_Paste(list1.head, list1.tail, PredInt);
- }
-
- IRO_InitList(&list2);
- fifthnode = IRO_NewLinear(IROLinearOp2Arg);
- fifthnode->index = ++IRO_NumLinear;
- fifthnode->rtype = type;
- if (induction->nd->type == IROLinearOp2Arg) {
- if (induction->nd->nodetype == EASS && IS_LINEAR_DIADIC(induction->nd->u.diadic.right, EADD))
- fifthnode->nodetype = EADDASS;
- else if (induction->nd->nodetype == EASS && IS_LINEAR_DIADIC(induction->nd->u.diadic.right, ESUB))
- fifthnode->nodetype = ESUBASS;
- else
- fifthnode->nodetype = induction->nd->nodetype;
- } else {
- if (induction->nd->nodetype == EPREINC || induction->nd->nodetype == EPOSTINC)
- fifthnode->nodetype = EADDASS;
- else
- fifthnode->nodetype = ESUBASS;
- }
-
- fifthnode->u.diadic.left = IRO_TempReference(tempObj, &list2);
- fifthnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Used | IROLF_Assigned;
- fifthnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Used | IROLF_Assigned;
- if (!unk) {
- if (!flag23) {
- if (induction->addConst == 1 || IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR)) {
- fifthnode->u.diadic.right = IRO_DuplicateExpr(nd2, &list2);
- } else {
- fifthnode->u.diadic.right = IRO_NewLinear(IROLinearOperand);
- fifthnode->u.diadic.right->index = ++IRO_NumLinear;
- enode = IRO_NewENode(EINTCONST);
- enode->rtype = nd2->rtype;
- fifthnode->u.diadic.right->rtype = nd2->rtype;
- CInt64_SetLong(&enode->data.intval, induction->addConst * CInt64_GetULong(&nd2->u.node->data.intval));
- fifthnode->u.diadic.right->u.node = enode;
- IRO_AddToList(fifthnode->u.diadic.right, &list2);
- }
- } else {
- fifthnode->u.diadic.right = IRO_TempReference(tempObj2, &list2);
- fifthnode->u.diadic.right->flags |= IROLF_Used;
- }
- }
-
- fifthnode->index = ++IRO_NumLinear;
- IRO_AddToList(fifthnode, &list2);
- IRO_Paste(list2.head, list2.tail, IRO_FindStart(induction->nd));
- IRO_WalkTree(expr->linear, IRO_RemoveExpr_Action);
- expr->x8 = tempObj;
- expr->next = RisList;
- RisList = expr;
- return expr;
-}
-
-static IRONode *CreatePreHeader(IRONode *fnode1, IRONode *fnode2) {
- IROLinear *labelnode;
- IRONode *newfnode;
- IRONode *iter;
- CLabel *oldlabel;
- CLabel *newlabel;
- SwitchInfo *swinfo;
- SwitchCase *swcase;
-
- newfnode = oalloc(sizeof(IRONode));
- memset(newfnode, 0, sizeof(IRONode));
- newfnode->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- labelnode = IRO_NewLinear(IROLinearLabel);
- labelnode->index = IRO_NumLinear++;
- labelnode->next = NULL;
- labelnode->u.label.label = IRO_NewLabel();
- labelnode->flags |= IROLF_1;
- labelnode->u.label.label->stmt = (Statement *) newfnode;
- newfnode->first = labelnode;
- newfnode->last = labelnode;
-
- if (fnode2) {
- fnode2->last->next = labelnode;
- labelnode->next = IRO_NewLinear(IROLinearNop);
- labelnode->next->next = fnode1->first;
- fnode2->nextnode = newfnode;
- newfnode->nextnode = fnode1;
- } else {
- CError_ASSERT(1254, fnode1->first->type == IROLinearLabel);
- labelnode->next = IRO_NewLinear(IROLinearGoto);
- labelnode->next->u.label.label = fnode1->first->u.label.label;
- IRO_LastNode->last->next = labelnode;
- IRO_LastNode->nextnode = newfnode;
- IRO_LastNode = newfnode;
- IRO_LastLinear = labelnode->next;
- }
-
- newfnode->last = labelnode->next;
-
- IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes);
- memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes);
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode)
- IRO_NodeTable[iter->index] = iter;
-
- if (fnode1->first->type == IROLinearLabel) {
- oldlabel = fnode1->first->u.label.label;
- newlabel = newfnode->first->u.label.label;
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode) {
- if (!Bv_IsBitSet(iter->index, InLoop) && iter != newfnode) {
- switch (iter->last->type) {
- case IROLinearGoto:
- if (iter->last->u.label.label == oldlabel)
- iter->last->u.label.label = newlabel;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- if (iter->last->u.label.label == oldlabel)
- iter->last->u.label.label = newlabel;
- break;
- case IROLinearSwitch:
- swinfo = iter->last->u.swtch.info;
- for (swcase = swinfo->cases; swcase; swcase = swcase->next) {
- if (swcase->label == oldlabel)
- swcase->label = newlabel;
- }
- if (swinfo->defaultlabel == oldlabel)
- swinfo->defaultlabel = newlabel;
- break;
- }
- }
- }
- }
-
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- return newfnode;
-}
-
-static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) {
- IROLinear *labelnode;
- IRONode *fnode2;
- IRONode *newfnode;
- Boolean flag;
- IRONode *iter;
- CLabel *oldlabel;
- CLabel *newlabel;
- SwitchInfo *swinfo;
- SwitchCase *swcase;
- UInt16 i;
-
- CError_ASSERT(1355, fnode1 != NULL && LoopExitNumber == 1);
-
- fnode2 = NULL;
- flag = 0;
-
- for (i = 0; i < fnode1->numpred; i++) {
- iter = IRO_NodeTable[fnode1->pred[i]];
- if (Bv_IsBitSet(iter->index, InLoop_Exits)) {
- CError_ASSERT(1366, fnode2 == NULL);
- fnode2 = iter;
- if (!flag) {
- if (
- !iter->last ||
- !fnode1->first ||
- fnode1->first->type != IROLinearLabel ||
- (
- (iter->last->type == IROLinearIf || iter->last->type == IROLinearIfNot) &&
- iter->last->u.label.label != fnode1->first->u.label.label
- ))
- flag = 1;
- }
- }
- }
-
- CError_ASSERT(1382, fnode2 != NULL);
-
- newfnode = oalloc(sizeof(IRONode));
- memset(newfnode, 0, sizeof(IRONode));
- newfnode->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- labelnode = IRO_NewLinear(IROLinearLabel);
- labelnode->index = IRO_NumLinear++;
- labelnode->next = NULL;
- labelnode->u.label.label = IRO_NewLabel();
- labelnode->flags |= IROLF_1;
- labelnode->u.label.label->stmt = (Statement *) newfnode;
- newfnode->first = labelnode;
- newfnode->last = labelnode;
-
- if (flag) {
- fnode2->last->next = labelnode;
- labelnode->next = IRO_NewLinear(IROLinearNop);
- labelnode->next->next = fnode1->first;
- fnode2->nextnode = newfnode;
- newfnode->nextnode = fnode1;
- } else {
- CError_ASSERT(1422, fnode1->first->type == IROLinearLabel);
- labelnode->next = IRO_NewLinear(IROLinearGoto);
- labelnode->next->u.label.label = fnode1->first->u.label.label;
- IRO_LastNode->last->next = labelnode;
- IRO_LastNode->nextnode = newfnode;
- IRO_LastNode = newfnode;
- IRO_LastLinear = labelnode->next;
- }
-
- newfnode->last = labelnode->next;
-
- IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes);
- memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes);
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode)
- IRO_NodeTable[iter->index] = iter;
-
- if (fnode1->first->type == IROLinearLabel) {
- oldlabel = fnode1->first->u.label.label;
- newlabel = newfnode->first->u.label.label;
- switch (fnode2->last->type) {
- case IROLinearGoto:
- if (fnode2->last->u.label.label == oldlabel)
- fnode2->last->u.label.label = newlabel;
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- if (fnode2->last->u.label.label == oldlabel)
- fnode2->last->u.label.label = newlabel;
- break;
- case IROLinearSwitch:
- swinfo = fnode2->last->u.swtch.info;
- for (swcase = swinfo->cases; swcase; swcase = swcase->next) {
- if (swcase->label == oldlabel)
- swcase->label = newlabel;
- }
- if (swinfo->defaultlabel == oldlabel)
- swinfo->defaultlabel = newlabel;
- break;
- }
- }
-
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- return newfnode;
-}
-
-void AddPreds(IRONode *fnode) {
- IRONode *pred;
- int i;
-
- for (i = 0; i < fnode->numpred; i++) {
- pred = IRO_NodeTable[fnode->pred[i]];
- if (!Bv_IsBitSet(pred->index, InLoop)) {
- Bv_SetBit(pred->index, InLoop);
- AddPreds(pred);
- }
- }
-}
-
-static void RemoveNoopsFromExprList(void) {
- IROExpr *expr;
- IROExpr *prev;
-
- expr = IRO_FirstExpr;
- prev = NULL;
- while (expr) {
- if (expr->linear->type == IROLinearNop) {
- if (prev)
- prev->next = expr->next;
- else
- IRO_FirstExpr = expr->next;
- expr = expr->next;
- } else {
- prev = expr;
- expr = expr->next;
- }
- }
-}
-
-void IncLoopDepth(void) {
- IRONode *fnode;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop))
- fnode->loopdepth++;
- }
-}
-
-void IRO_SetLoopDepth(void) {
- IRONode *fnode;
- IRONode *pred;
- UInt16 i;
- UInt16 flag;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode)
- fnode->loopdepth = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- flag = 0;
-
- for (i = 0; i < fnode->numpred; i++) {
- pred = IRO_NodeTable[fnode->pred[i]];
- if (Bv_IsBitSet(fnode->index, pred->dom)) {
- if (!flag) {
- Bv_AllocVector(&InLoop, IRO_NumNodes + 1);
- Bv_Clear(InLoop);
- Bv_SetBit(fnode->index, InLoop);
- }
- flag = 1;
- Bv_SetBit(pred->index, InLoop);
- if (pred != fnode)
- AddPreds(pred);
- }
- }
-
- if (flag)
- IncLoopDepth();
- }
-
- IRO_CheckForUserBreak();
-}
-
-static void InsertBranchAroundLoopPreheaders(void) {
- IRONode *fnode;
- CLabel *label;
- IRONode *iter;
- IROLinear *endnode;
- IROLinear *labelnode;
-
- if (IRO_EndNode && IRO_EndNode->last && IRO_EndNode->last->type == IROLinearEnd) {
- label = IRO_NewLabel();
- fnode = IRO_NewFlowGraphNode();
- IRO_LastNode->nextnode = fnode;
- label->stmt = (Statement *) fnode;
-
- IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes);
- memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes);
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode)
- IRO_NodeTable[iter->index] = iter;
-
- labelnode = IRO_NewLinear(IROLinearLabel);
- labelnode->index = ++IRO_NumLinear;
- labelnode->u.label.label = label;
- labelnode->flags |= IROLF_1;
- fnode->first = labelnode;
- IRO_LastLinear->next = labelnode;
-
- endnode = IRO_NewLinear(IROLinearEnd);
- memcpy(endnode, IRO_EndNode->last, sizeof(IROLinear));
- endnode->index = ++IRO_NumLinear;
- endnode->next = NULL;
- fnode->last = endnode;
- labelnode->next = endnode;
- IRO_LastLinear = endnode;
-
- IRO_EndNode->last->type = IROLinearGoto;
- IRO_EndNode->last->u.label.label = label;
- IRO_LastNode = fnode;
- IRO_EndNode = fnode;
-
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
-}
-
-void IRO_FindLoops(void) {
- IRONode *fnode;
- IRONode *pred;
- UInt16 i;
- UInt16 flag;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- flag = 0;
-
- for (i = 0; i < fnode->numpred; i++) {
- pred = IRO_NodeTable[fnode->pred[i]];
- if (Bv_IsBitSet(fnode->index, pred->dom)) {
- if (!flag) {
- Bv_AllocVector(&InLoop, IRO_NumNodes + 1);
- Bv_Clear(InLoop);
- Bv_SetBit(fnode->index, InLoop);
- }
- flag = 1;
- Bv_SetBit(pred->index, InLoop);
- if (pred != fnode)
- AddPreds(pred);
- }
- }
-
- if (flag) {
- IncLoopDepth();
- IRO_Dump("IRO_FindLoops:Found loop with header %d\n", fnode->index);
- IRO_DumpBits("Loop includes: ", InLoop);
- MyHandleLoop_Motion(fnode);
- IRO_UpdateFlagsOnInts();
- MyHandleLoop_Vector(fnode);
- RemoveNoopsFromExprList();
- IRO_UpdateFlagsOnInts();
- IRO_UpdateVars();
- }
- }
-
- if (!IRO_FunctionHasReturn && IRO_EndNode != IRO_LastNode)
- InsertBranchAroundLoopPreheaders();
-}
-
-static void CheckSubableSub(IROLinear *linear, Boolean isFirst) {
- if (isFirst && IRO_IsSubableExpression(linear)) {
- IRO_Dump("Subable Expression is %d\n", linear->index);
- NoSubableSubs = 0;
- }
-}
-
-static int NoSubableSubExprs(IROLinear *nd) {
- NoSubableSubs = 1;
- IRO_WalkTree(nd, CheckSubableSub);
- return NoSubableSubs;
-}
-
-void ComputeLoopKills(void) {
- IRONode *fnode;
- IROLinear *nd;
-
- Bv_AllocVector(&AllKills, IRO_NumVars + 1);
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) {
- Bv_AllocVector(&fnode->x16, IRO_NumVars + 1);
- Bv_AllocVector(&fnode->x1E, IRO_NumVars + 1);
- while (1) {
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(nd);
- Bv_Or(IRO_VarKills, AllKills);
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
- }
- }
-}
-
-void ComputeLoopInvariance(void) {
- IRONode *fnode;
- IROLinear *nd;
-
- IRO_Depends = IRO_VarKills;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) {
- nd->flags &= ~IROLF_LoopInvariant;
- while (1) {
- if ((nd->flags & IROLF_Reffed) && nd->type != IROLinearNop) {
- IRO_FindDepends_NoAlloc(nd);
- if (!IRO_IsVolatile && !Bv_BitsInCommon(IRO_Depends, AllKills))
- nd->flags |= IROLF_LoopInvariant;
-
- if (IRO_CouldError)
- nd->flags |= IROLF_CouldError;
- else
- nd->flags &= ~IROLF_CouldError;
- }
-
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
- }
- }
-}
-
-void ComputeLoopInduction(void) {
- IRONode *fnode;
- IROLinear *nd;
- Boolean flag;
- Object *obj;
- Object *obj2;
- Object *obj3;
- VarRecord *var;
- IROLinear *tmpnd;
- IROLoopInd *ind;
- Boolean isUnsigned;
-
- Bv_AllocVector(&AllKills, IRO_NumVars + 1);
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) {
- while (1) {
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(nd);
- Bv_Or(IRO_VarKills, AllKills);
- flag = 0;
- if (
- (
- nd->type == IROLinearOp2Arg &&
- nd->rtype->size <= 4 &&
- (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) &&
- (obj = IRO_IsVariable(nd->u.diadic.left)) &&
- obj->type->size == nd->rtype->size &&
- IS_TYPE_INT(obj->type) &&
- (
- (IRO_IsIntConstant(nd->u.diadic.right) && CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval))
- ||
- (nd->u.diadic.right->flags & IROLF_LoopInvariant)
- )
- )
- ||
- (
- nd->type == IROLinearOp1Arg &&
- nd->rtype->size <= 4 &&
- (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC || nd->nodetype == EPREINC || nd->nodetype == EPREDEC) &&
- (obj = IRO_IsVariable(nd->u.monadic)) &&
- obj->type->size == nd->rtype->size &&
- IS_TYPE_INT(obj->type)
- )
- )
- {
- flag = 1;
- }
- else if (
- nd->type == IROLinearOp2Arg &&
- nd->rtype->size <= 4 &&
- nd->nodetype == EASS &&
- (obj = IRO_IsVariable(nd->u.diadic.left)) &&
- obj->type->size == nd->rtype->size &&
- IS_TYPE_INT(obj->type) &&
- nd->u.diadic.right->type == IROLinearOp2Arg &&
- (nd->u.diadic.right->nodetype == EADD || nd->u.diadic.right->nodetype == ESUB)
- )
- {
- if (nd->u.diadic.right->nodetype == EADD) {
- obj2 = IRO_IsVariable(nd->u.diadic.right->u.diadic.left);
- obj3 = IRO_IsVariable(nd->u.diadic.right->u.diadic.right);
- if (obj2 == obj && obj3 != obj && (nd->u.diadic.right->u.diadic.right->flags & IROLF_LoopInvariant))
- flag = 1;
-
- if (obj3 == obj && obj2 != obj && (nd->u.diadic.right->u.diadic.left->flags & IROLF_LoopInvariant)) {
- flag = 1;
- tmpnd = nd->u.diadic.right->u.diadic.left;
- nd->u.diadic.right->u.diadic.left = nd->u.diadic.right->u.diadic.right;
- nd->u.diadic.right->u.diadic.right = tmpnd;
- }
- } else {
- obj2 = IRO_IsVariable(nd->u.diadic.right->u.diadic.left);
- obj3 = IRO_IsVariable(nd->u.diadic.right->u.diadic.right);
- if (obj2 == obj && obj3 != obj && (nd->u.diadic.right->u.diadic.right->flags & IROLF_LoopInvariant))
- flag = 1;
- }
- }
-
- if (flag) {
- if ((var = IRO_FindAssigned(nd))) {
- if (var->xA == 2)
- var->xA = 0;
- else if (var->xA == 1)
- var->xA = 2;
- }
- } else {
- for (var = IRO_FirstVar; var; var = var->next) {
- if (Bv_IsBitSet(var->index, IRO_VarKills))
- var->xA = 0;
- }
- }
-
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
- }
- }
-
- IRO_DumpBits("Killed in loop: ", AllKills);
-
- for (fnode = IRO_FirstNode, FirstInd = NULL; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) {
- while (1) {
- if (
- (
- nd->type == IROLinearOp2Arg &&
- (nd->nodetype == EADDASS || nd->nodetype == ESUBASS || nd->nodetype == EASS)
- )
- ||
- (
- nd->type == IROLinearOp1Arg &&
- (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC || nd->nodetype == EPREINC || nd->nodetype == EPREDEC)
- )
- ) {
- if ((var = IRO_FindAssigned(nd)) && var->xA == 2 && var->object->type->size <= 4) {
- ind = oalloc(sizeof(IROLoopInd));
- ind->fnode = fnode;
- ind->var = var;
- ind->nd = nd;
- ind->next = FirstInd;
- ind->addNode = NULL;
- ind->addConst = 0;
- ind->flags = 0;
-
- if (nd->type == IROLinearOp2Arg) {
- isUnsigned = IRO_IsUnsignedType(nd->rtype);
- if (IRO_IsIntConstant(nd->u.diadic.right)) {
- CInt64 val = nd->u.diadic.right->u.node->data.intval;
- if (IS_LINEAR_DIADIC(nd, EADDASS) && CInt64_Less(val, cint64_zero)) {
- nd->nodetype = ESUBASS;
- nd->u.diadic.right->u.node->data.intval = CInt64_Neg(val);
- }
- if (isUnsigned) {
- CInt64_ConvertUInt32(&nd->u.diadic.right->u.node->data.intval);
- ind->addConst = CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval);
- } else {
- CInt64_ConvertInt32(&nd->u.diadic.right->u.node->data.intval);
- ind->addConst = CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval);
- }
- ind->addNode = NULL;
- } else if (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) {
- ind->addNode = nd->u.diadic.right;
- } else if (nd->nodetype == EASS) {
- ind->addNode = nd->u.diadic.right->u.diadic.right;
- }
- } else {
- if (IS_TYPE_POINTER_ONLY(nd->rtype))
- ind->addConst = TPTR_TARGET(nd->rtype)->size;
- else
- ind->addConst = 1;
- ind->addNode = NULL;
- }
-
- FirstInd = ind;
-
- if (IS_LINEAR_DIADIC_2(nd, EADDASS, ESUBASS)) {
- if (nd->u.diadic.right->flags & IROLF_LoopInvariant)
- IRO_Dump("Found induction variable the new way: %s\n", var->object->name->name);
- else
- IRO_Dump("Found induction variable the old way: %s\n", var->object->name->name);
- } else if (nd->type == IROLinearOp2Arg && (nd->u.diadic.right->nodetype == EADD || nd->u.diadic.right->nodetype == ESUB)) {
- IRO_Dump("Found induction variable the new way: %s\n", var->object->name->name);
- } else {
- IRO_Dump("Found induction variable the old way: %s\n", var->object->name->name);
- }
- }
- }
-
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
- }
- }
-}
-
-static void IRO_ActUnmarkLoopInvariance(IROLinear *linear, Boolean isFirst) {
- if (isFirst)
- linear->flags &= ~IROLF_LoopInvariant;
-}
-
-static void UnmarkSubexpressionsOfInvariantExpressions(void) {
- IROExpr *expr;
-
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (
- Bv_IsBitSet(expr->node->index, InLoop) &&
- !expr->notSubable &&
- (!expr->couldError || expr->node->mustreach) &&
- (expr->linear->flags & IROLF_LoopInvariant)
- ) {
- IRO_WalkTree(expr->linear, IRO_ActUnmarkLoopInvariance);
- expr->linear->flags |= IROLF_LoopInvariant;
- }
- }
-}
-
-static void MyHandleLoop_Vector(IRONode *fnode) {
- IRONode *pred;
- UInt16 i;
- IROExpr *expr;
- IROExpr *removedExprs;
- IROExpr *exprnext;
- IROLoopInd *induction;
- IROExpr *exprinner;
- Boolean flag24;
- IRONode *v2;
- IRONode *node22;
- int flag21;
- IRONode *iter;
- IROExpr *searchris;
- IROLinear *reduceNd1;
- VarRecord *var;
- IROLinear *reduceNd2;
-
- IRO_FirstExpr = NULL;
- LoopNode = fnode;
- FindMustReach();
-
- for (var = IRO_FirstVar; var; var = var->next)
- var->xA = 1;
-
- ComputeLoopKills();
- ComputeLoopInvariance();
- ComputeLoopInduction();
- LoopNode = fnode;
- ConditionalHeaderAtBottom = 0;
-
- v2 = NULL;
- flag21 = 0;
- node22 = NULL;
- for (i = 0; i < LoopNode->numpred; i++) {
- pred = IRO_NodeTable[LoopNode->pred[i]];
- if (!Bv_IsBitSet(pred->index, InLoop)) {
- if (flag21)
- node22 = NULL;
- else
- node22 = pred;
- flag21 = 1;
- if (pred->nextnode == fnode) {
- CError_ASSERT(2880, v2 == NULL || pred == v2);
- v2 = pred;
- }
- }
- }
-
- if (!flag21) {
- IRO_Dump("No predecessor outside the loop\n");
- return;
- }
-
- if (!node22 || node22->last->type != IROLinearGoto)
- node22 = CreatePreHeader(fnode, v2);
- PredInt = node22->last;
-
- if (PredInt->type == IROLinearGoto && PredInt->u.label.label != LoopNode->first->u.label.label) {
- if (!KnownBounds || !Times) {
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode)
- iter->mustreach = 0;
- } else {
- PredInt->u.label.label = LoopNode->first->u.label.label;
- IRO_ComputeSuccPred();
- }
- }
-
- if (copts.loopinvariants || copts.strengthreduction) {
- MoveInvarianceInAddressExpr();
- IRO_DumpAfterPhase("MoveInvarianceInAddressExpr", 0);
- IRO_FindExpressions(InLoop, 1);
- IRO_DumpExprs();
- }
-
- if (copts.loopinvariants)
- UnmarkSubexpressionsOfInvariantExpressions();
-
- if (!copts.optimizesize && copts.strengthreduction) {
- for (expr = IRO_FirstExpr; expr; expr = expr->next) {
- if (
- !(expr->x0 & 4) &&
- Bv_IsBitSet(expr->node->index, InLoop) &&
- !expr->notSubable &&
- (!expr->couldError || expr->node->mustreach) &&
- Reducable(expr->linear, &reduceNd1, &reduceNd2, &var)
- ) {
- IRO_WalkTree(expr->linear, IRO_ActUnmarkRISCandidate);
- expr->linear->flags |= IROLF_Ris;
- expr->x1A = reduceNd1;
- expr->x1E = var;
- expr->x22 = reduceNd2;
- }
- }
- }
-
- if (!copts.optimizesize && copts.strengthreduction) {
- RisList = NULL;
- for (expr = IRO_FirstExpr; expr; expr = exprnext) {
- exprnext = expr->next;
- if (!(expr->x0 & 4) && (expr->linear->flags & IROLF_Ris)) {
- reduceNd1 = expr->x1A;
- var = expr->x1E;
- reduceNd2 = expr->x22;
-
- induction = FirstInd;
- while (induction && induction->var != var)
- induction = induction->next;
- CError_ASSERT(3529, induction != NULL);
-
- IRO_FindDepends(reduceNd1);
- if (!Bv_BitsInCommon(IRO_Depends, AllKills)) {
- IRO_Dump("Found reduction in strength: %d\n", expr->linear->index);
- if (IS_LINEAR_DIADIC(expr->linear, ESHL)) {
- expr->linear->nodetype = EMUL;
- CInt64_SetULong(&reduceNd1->u.node->data.intval, 1 << CInt64_GetULong(&reduceNd1->u.node->data.intval));
- reduceNd1->u.node->rtype = expr->linear->rtype;
- }
-
- searchris = RisList;
- while (1) {
- if (!searchris)
- break;
- if (IRO_ExprsSame(expr->linear, searchris->linear))
- break;
- searchris = searchris->next;
- }
-
- if (searchris) {
- IRO_Dump("Using existing RIS: %d\n", searchris->linear->index);
- IRO_WalkTree(expr->linear, IRO_RemoveExpr_Action);
- } else {
- searchris = CreateRIS(expr, reduceNd2, reduceNd1, induction, 0);
- }
- IRO_ReplaceReference(expr->linear, searchris->x8, expr->linear);
- IRO_ClipExpr(expr);
- }
- }
- }
- }
-
- RisList = NULL;
-
- expr = IRO_FirstExpr;
- removedExprs = NULL;
- if (copts.loopinvariants) {
- while (expr) {
- exprnext = expr->next;
- flag24 = 0;
-
- if (
- Bv_IsBitSet(expr->node->index, InLoop) &&
- !expr->notSubable &&
- (!expr->couldError || expr->node->mustreach) &&
- (expr->linear->flags & IROLF_LoopInvariant) &&
- !(expr->x0 & 4)
- ) {
- IRO_Dump("Found loop invariant: %d\n", expr->linear->index);
-
- for (exprinner = removedExprs; exprinner; exprinner = exprinner->next) {
- if (IRO_ExprsSame(exprinner->linear, expr->linear)) {
- IRO_ReplaceReference(expr->linear, exprinner->x8, expr->linear);
- IRO_NopOut(expr->linear);
- IRO_Dump("Using already removed expr: %d\n", exprinner->linear->index);
- IRO_RemoveExpr(expr);
- flag24 = 1;
- }
- }
-
- if (!flag24 && !expr->x8) {
- IRO_GetTemp(expr);
- IRO_ReplaceReference(expr->linear, expr->x8, expr->linear);
- IRO_MoveExpression(expr, PredInt);
- IRO_AssignToTemp(expr);
- IRO_RemoveExpr(expr);
- expr->next = removedExprs;
- removedExprs = expr;
- }
- }
-
- expr = exprnext;
- }
- }
-}
-
-static void MyHandleLoop_Motion(IRONode *fnode) {
- IROLoopMemRef *memref;
- IRONode *pred;
- UInt16 i;
- IRONode *v2;
- IRONode *node21;
- Object *tempobj;
- int flag20;
- IRONode *iter;
- IROLinear *ass;
- VarRecord *var;
- Boolean checkflag;
- IROLoop *loop;
- IROList list;
- IROElmList *refiter;
-
- IRO_FirstExpr = NULL;
- LoopNode = fnode;
- FindMustReach();
-
- for (var = IRO_FirstVar; var; var = var->next)
- var->xA = 1;
-
- ComputeLoopKills();
- ComputeLoopInvariance();
- ComputeLoopInduction();
- LoopNode = fnode;
- ConditionalHeaderAtBottom = 0;
-
- v2 = NULL;
- flag20 = 0;
- node21 = NULL;
- for (i = 0; i < LoopNode->numpred; i++) {
- pred = IRO_NodeTable[LoopNode->pred[i]];
- if (!Bv_IsBitSet(pred->index, InLoop)) {
- if (flag20)
- node21 = NULL;
- else
- node21 = pred;
- flag20 = 1;
- if (pred->nextnode == fnode) {
- CError_ASSERT(3880, v2 == NULL || pred == v2);
- v2 = pred;
- }
- }
- }
-
- if (!flag20) {
- IRO_Dump("No predecessor outside the loop\n");
- return;
- }
-
- if (!node21 || node21->last->type != IROLinearGoto)
- node21 = CreatePreHeader(fnode, v2);
- PredInt = node21->last;
-
- if (PredInt->type == IROLinearGoto && PredInt->u.label.label != LoopNode->first->u.label.label) {
- if (!KnownBounds || !Times) {
- for (iter = IRO_FirstNode; iter; iter = iter->nextnode)
- iter->mustreach = 0;
- } else {
- PredInt->u.label.label = LoopNode->first->u.label.label;
- IRO_ComputeSuccPred();
- }
- }
-
- if (copts.loopinvariants || copts.strengthreduction) {
- MoveInvarianceInAddressExpr();
- IRO_DumpAfterPhase("MoveInvarianceInAddressExpr", 0);
- IRO_FindExpressions(InLoop, 0);
- IRO_DumpExprs();
- }
-
- if (copts.loopinvariants)
- UnmarkSubexpressionsOfInvariantExpressions();
-
- checkflag = 1;
- Bv_AllocVector(&InLoop_Exits, IRO_NumNodes + 1);
- Bv_AllocVector(&InLoop_Tails, IRO_NumNodes + 1);
- LoopExitNumber = 0;
- LoopExitSuccessor = NULL;
- LoopTailNum = 0;
- LoopTail = NULL;
- IRO_FindLoopTailsAndExits(fnode);
- FindMustReach1(fnode);
-
- loop = NULL;
- if (LoopTailNum == 1) {
- if (fnode->last->type == IROLinearIf || fnode->last->type == IROLinearIfNot)
- loop = ExtractLoopInfo(fnode);
- else if (LoopTail->last->type == IROLinearIf || LoopTail->last->type == IROLinearIfNot)
- loop = ExtractLoopInfo(LoopTail);
- }
-
- if (loop && !(loop->flags & LP_IFEXPR_NON_CANONICAL) && LoopExitNumber == 1) {
- IRO_LoopMemRefFirst = NULL;
- IRO_LoopMemRefCurrent = NULL;
- CheckAllLoopAddresses(IRO_FirstNode, InLoop, &checkflag);
- CheckAllLoopAddresses(IRO_FirstNode, InLoop, &checkflag);
- if (checkflag) {
- for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) {
- if (memref->flags & LoopMemRef_10)
- memref->flags |= LoopMemRef_8;
- }
-
- for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) {
- IRO_Dump("Loop Motion Candidate:: Int= %d", memref->nd->index);
- if (memref->flags & LoopMemRef_8)
- IRO_Dump("<invalid>");
- if (memref->flags & LoopMemRef_1)
- IRO_Dump("<load>");
- if (memref->flags & LoopMemRef_2)
- IRO_Dump("<store>");
- IRO_Dump("\n");
-
- if (!(memref->flags & LoopMemRef_8)) {
- tempobj = create_temp_object(memref->nd->rtype);
- IRO_FindVar(tempobj, 1, 1);
- if (IRO_FindVar(((IROLinear *) memref->rec->objRefs->element)->u.node->data.objref, 0, 1)) {
- IRO_InitList(&list);
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->rtype = memref->nd->rtype;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, &list);
- ass->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.right = IRO_DuplicateExpr(memref->nd, &list);
- IRO_AddToList(ass, &list);
- IRO_Paste(list.head, list.tail, PredInt);
- } else {
- CError_FATAL(4123);
- }
-
- if (LoopExitSuccessor->numpred != 1)
- LoopExitSuccessor = CreateNewLoopExitSuccessor(LoopExitSuccessor);
-
- IRO_InitList(&list);
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->rtype = memref->nd->rtype;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_DuplicateExpr(memref->nd, &list);
- ass->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned;
- ass->u.diadic.right = IRO_TempReference(tempobj, &list);
- IRO_AddToList(ass, &list);
-
- if (LoopExitSuccessor->first->type == IROLinearLabel)
- IRO_PasteAfter(list.head, list.tail, LoopExitSuccessor->first);
- else
- IRO_Paste(list.head, list.tail, LoopExitSuccessor->first);
-
- for (refiter = memref->list; refiter; refiter = refiter->next) {
- IRO_Dump("Loop Motion Candidate Reference at Int= %d\n", ((IROLinear *) refiter->element)->index);
- IRO_InitList(&list);
- IRO_TempReference(tempobj, &list);
- IRO_Paste(list.head, list.tail, refiter->element);
- IRO_LocateFather_Cut_And_Paste(refiter->element, list.tail);
- }
- }
- }
- }
- }
-
- IRO_DumpAfterPhase("After Motion", 0);
-}
-
-static Boolean CheckLoopAddress(IROLinear *nd, Boolean mustreach1) {
- IROLoopMemRef *memref;
- IROAddrRecord *rec;
- IROAddrRecord *otherrec;
- IROLinear *inner;
- IROElmList *list;
- Boolean flag;
-
- inner = nd->u.monadic;
- rec = IRO_InitAddrRecordPointer(inner);
- if (IS_LINEAR_ENODE(inner, EOBJREF)) {
- rec->numObjRefs++;
- IRO_AddElmToList(inner, &rec->objRefs);
- } else if (IS_LINEAR_DIADIC(inner, EADD)) {
- IRO_DecomposeAddressExpression(inner, rec);
- } else {
- return 0;
- }
-
- if (rec->numObjRefs != 1)
- return 0;
-
- flag = (nd->flags & IROLF_CouldError) || !(nd->flags & IROLF_Reffed);
- if (!IRO_LoopMemRefFirst) {
- MakeLoopEntry(nd, rec, mustreach1, flag);
- } else {
- for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) {
- otherrec = memref->rec;
- if (((IROLinear *) rec->objRefs->element)->u.node->data.objref == ((IROLinear *) otherrec->objRefs->element)->u.node->data.objref) {
- if (IRO_ExprsSame(inner, otherrec->linear)) {
- list = oalloc(sizeof(IROElmList));
- list->element = nd;
- list->next = NULL;
- if (!memref->list) {
- memref->list = list;
- } else {
- list->next = memref->list;
- memref->list = list;
- }
- } else {
- memref->flags |= LoopMemRef_8;
- }
-
- if (!mustreach1 && flag)
- memref->flags |= LoopMemRef_8;
- if (mustreach1 || flag)
- memref->flags &= ~LoopMemRef_10;
- break;
- }
- }
-
- if (!memref)
- MakeLoopEntry(nd, rec, mustreach1, flag);
- }
-
- return 1;
-}
-
-static void CheckAllLoopAddresses(IRONode *fnode, BitVector *bv, Boolean *resultFlag) {
- IROLinear *nd;
- Boolean flag;
-
- flag = *resultFlag;
- while (fnode) {
- if (Bv_IsBitSet(fnode->index, bv) && (nd = fnode->first)) {
- while (flag) {
- if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT)
- flag = CheckLoopAddress(nd, fnode->mustreach1);
- else if (nd->type == IROLinearFunccall)
- flag = 0;
-
- if (nd == fnode->last)
- break;
- nd = nd->next;
- }
-
- if (!flag)
- break;
- }
- fnode = fnode->nextnode;
- }
- *resultFlag = flag;
-}
-
-static void MakeLoopEntry(IROLinear *nd, IROAddrRecord *rec, Boolean mustreach1, Boolean flag2) {
- IROElmList *list;
-
- if (!IRO_IsRegable(((IROLinear *) rec->objRefs->element)->u.node->data.objref) &&
- (nd->u.monadic->flags & IROLF_LoopInvariant) &&
- !IRO_HasSideEffect(nd)) {
- if (!IRO_LoopMemRefFirst) {
- IRO_LoopMemRefCurrent = IRO_LoopMemRefFirst = oalloc(sizeof(IROLoopMemRef));
- } else {
- IRO_LoopMemRefCurrent->next = oalloc(sizeof(IROLoopMemRef));
- IRO_LoopMemRefCurrent = IRO_LoopMemRefCurrent->next;
- }
- IRO_LoopMemRefCurrent->flags = LoopMemRef_10;
- IRO_LoopMemRefCurrent->nd = nd;
- IRO_LoopMemRefCurrent->rec = rec;
- IRO_LoopMemRefCurrent->next = NULL;
- IRO_LoopMemRefCurrent->list = NULL;
-
- list = oalloc(sizeof(IROElmList));
- list->element = nd;
- list->next = NULL;
- if (!IRO_LoopMemRefCurrent->list) {
- IRO_LoopMemRefCurrent->list = list;
- } else {
- list->next = IRO_LoopMemRefCurrent->list;
- IRO_LoopMemRefCurrent->list = list;
- }
-
- if (((IROLinear *) rec->objRefs->element)->flags & IROLF_Assigned) {
- IRO_LoopMemRefCurrent->flags |= LoopMemRef_2;
- if (((IROLinear *) rec->objRefs->element)->flags & IROLF_Used)
- IRO_LoopMemRefCurrent->flags |= LoopMemRef_1;
- } else {
- IRO_LoopMemRefCurrent->flags |= LoopMemRef_1;
- }
-
- if (!mustreach1 && flag2)
- IRO_LoopMemRefCurrent->flags |= LoopMemRef_8;
-
- if (mustreach1 || flag2)
- IRO_LoopMemRefCurrent->flags &= ~LoopMemRef_10;
- }
-}
-
-void FindAssignmenttoInductionVar(IROLoop *loop, IRONode *fnode) {
- IROLinear *nd;
- UInt32 index;
-
- if (!loop->induction) {
- loop->nd14 = NULL;
- } else {
- index = loop->induction->var->index;
- for (nd = fnode->first; nd; nd = nd->next) {
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(nd);
- if (Bv_IsBitSet(index, IRO_VarKills))
- loop->nd14 = nd;
-
- if (nd == fnode->last)
- break;
- }
-
- if (loop->nd14 && loop->nd14->type != IROLinearOp2Arg)
- loop->nd14 = NULL;
- }
-}
-
-static void ComputeIntWeight(IROLoop *loop, IROLinear *Int) {
- loop->sizeBySomeMeasurement++;
-}
-
-static IROLinear *IsTypconVar(IROLinear *nd) {
- if (IS_LINEAR_MONADIC(nd, ETYPCON) && IRO_IsVariable(nd->u.monadic))
- return nd->u.monadic;
- else
- return NULL;
-}
-
-IROLoop *ExtractLoopInfo(IRONode *fnode) {
- Boolean flag30;
- Boolean flag29;
- Boolean flag28;
- UInt32 counter27;
- IROLoopInd *ind23;
- Object *obj;
- IROLinear *nd21;
- IRONode *scanfnode;
- IROLinear *left19;
- IROLinear *right18;
- IROLinear *tmp18;
- IROLinear *scannd;
- IROLinear *tmp;
- VarRecord *var;
- IROLoopInd *scanind;
- IROLinear *left;
- IROLinear *right;
- UInt32 counter2;
- UInt32 i;
- IROLoop *loop;
-
- flag30 = 0;
- flag29 = 0;
- flag28 = 0;
- counter27 = 0;
- LoopNode = fnode;
-
- loop = oalloc(sizeof(IROLoop));
- loop->fnode = fnode;
- nd21 = LoopNode->last->u.label.x4;
- loop->nd18 = nd21;
- loop->flags = 0;
- loop->x8 = 0;
- loop->nd14 = NULL;
- loop->induction = NULL;
- loop->index20 = -1;
- loop->index24 = -1;
- loop->sizeBySomeMeasurement = 0;
-
- if (nd21->type == IROLinearOp2Arg && IS_TYPE_INT(nd21->rtype)) {
- ind23 = NULL;
- left19 = nd21->u.diadic.left;
- right18 = nd21->u.diadic.right;
- if (IRO_IsVariable(left19) || (left19 = IsTypconVar(left19))) {
- if ((var = IRO_FindVar(left19->u.monadic->u.node->data.objref, 0, 1))) {
- scanind = FirstInd;
- while (scanind && scanind->var != var)
- scanind = scanind->next;
- if (scanind) {
- ind23 = scanind;
- loop->flags |= LoopFlags_1;
- loop->induction = scanind;
- }
- }
- }
-
- if (IRO_IsVariable(right18) || (right18 = IsTypconVar(right18))) {
- if ((var = IRO_FindVar(right18->u.monadic->u.node->data.objref, 0, 1))) {
- scanind = FirstInd;
- while (scanind && scanind->var != var)
- scanind = scanind->next;
- if (scanind) {
- ind23 = scanind;
- loop->flags &= ~LoopFlags_1;
- loop->induction = scanind;
- }
- }
- }
-
- if (ind23 && ind23->addConst > 0) {
- if (loop->flags & LoopFlags_1) {
- if (
- loop->nd18->type != IROLinearOp2Arg ||
- !(loop->nd18->nodetype == ELESS || loop->nd18->nodetype == EGREATER || loop->nd18->nodetype == ELESSEQU || loop->nd18->nodetype == EGREATEREQU) ||
- !loop->nd18->u.diadic.left ||
- !loop->nd18->u.diadic.left->rtype ||
- !IS_TYPE_INT(loop->nd18->u.diadic.left->rtype) ||
- !loop->nd18->u.diadic.right ||
- !loop->nd18->u.diadic.right->rtype ||
- !IS_TYPE_INT(loop->nd18->u.diadic.right->rtype)
- ) {
- loop->flags |= LP_IFEXPR_NON_CANONICAL;
- return loop;
- }
- } else {
- if (
- loop->nd18->type == IROLinearOp2Arg &&
- (loop->nd18->nodetype == EGREATER || loop->nd18->nodetype == EGREATEREQU) &&
- (left = loop->nd18->u.diadic.left) &&
- left->rtype &&
- IS_TYPE_INT(left->rtype) &&
- (right = loop->nd18->u.diadic.right) &&
- right->rtype &&
- IS_TYPE_INT(right->rtype)
- ) {
- loop->nd18->u.diadic.left = right;
- loop->nd18->u.diadic.right = left;
- if (loop->nd18->nodetype == EGREATER)
- loop->nd18->nodetype = ELESS;
- else if (loop->nd18->nodetype == EGREATEREQU)
- loop->nd18->nodetype = ELESSEQU;
- loop->flags |= LoopFlags_1;
- } else if (
- loop->nd18->type == IROLinearOp2Arg &&
- (loop->nd18->nodetype == ELESS || loop->nd18->nodetype == ELESSEQU) &&
- (left = loop->nd18->u.diadic.left) &&
- left->rtype &&
- IS_TYPE_INT(left->rtype) &&
- (right = loop->nd18->u.diadic.right) &&
- right->rtype &&
- IS_TYPE_INT(right->rtype)
- ) {
- loop->nd18->u.diadic.left = right;
- loop->nd18->u.diadic.right = left;
- if (loop->nd18->nodetype == ELESS)
- loop->nd18->nodetype = EGREATER;
- else if (loop->nd18->nodetype == ELESSEQU)
- loop->nd18->nodetype = EGREATEREQU;
- loop->flags |= LoopFlags_1;
- } else {
- loop->flags |= LP_IFEXPR_NON_CANONICAL;
- return loop;
- }
- }
- } else {
- loop->flags |= LP_INDUCTION_NOT_FOUND;
- return loop;
- }
- } else if (nd21->type == IROLinearOp1Arg && IS_TYPE_INT(nd21->rtype)) {
- if (nd21->nodetype == EPREINC || nd21->nodetype == EPOSTINC || nd21->nodetype == EPREDEC || nd21->nodetype == EPOSTDEC) {
- if (IRO_IsVariable(nd21->u.monadic)) {
- if ((var = IRO_FindVar(nd21->u.monadic->u.monadic->u.node->data.objref, 0, 1))) {
- scanind = FirstInd;
- while (scanind && scanind->var != var)
- scanind = scanind->next;
- if (scanind) {
- ind23 = scanind;
- loop->flags |= LoopFlags_10000;
- loop->induction = scanind;
- } else {
- loop->flags |= LP_INDUCTION_NOT_FOUND;
- return loop;
- }
- } else {
- loop->flags |= LP_INDUCTION_NOT_FOUND;
- return loop;
- }
- } else {
- loop->flags |= LP_INDUCTION_NOT_FOUND;
- return loop;
- }
- } else {
- loop->flags |= LP_INDUCTION_NOT_FOUND;
- return loop;
- }
- } else {
- loop->flags |= LP_IFEXPR_NON_CANONICAL;
- return loop;
- }
-
- counter2 = 0;
- scanind = FirstInd;
- while (scanind) {
- scanind = scanind->next;
- counter2++;
- }
-
- if (counter2 > 1)
- loop->flags |= LP_HAS_MULTIPLE_INDUCTIONS;
-
- if ((scanind = loop->induction)) {
- nd21 = scanind->nd;
- if (nd21->type == IROLinearOp2Arg) {
- if (IS_LINEAR_DIADIC_2(loop->nd18, ELESS, ELESSEQU)) {
- if (nd21->nodetype == EADDASS) {
- if (scanind->addConst == 1)
- loop->flags |= LP_LOOP_STEP_ISADD;
- if (scanind->addConst > 0)
- loop->flags |= LP_LOOP_STEP_ISPOS;
- } else if (nd21->nodetype == EASS &&
- IS_LINEAR_DIADIC(nd21->u.diadic.right, EADD) &&
- IRO_IsIntConstant(tmp18 = nd21->u.diadic.right->u.diadic.right) &&
- CTool_EndianReadWord32(&tmp18->u.node->data.intval.hi) == 0) {
- if (CInt64_GetULong(&tmp18->u.node->data.intval) == 1)
- loop->flags |= LP_LOOP_STEP_ISADD;
- if (CInt64_GetULong(&tmp18->u.node->data.intval) > 0)
- loop->flags |= LP_LOOP_STEP_ISPOS;
- }
- }
- } else if (nd21->type == IROLinearOp1Arg) {
- if (nd21->nodetype == EPREINC || nd21->nodetype == EPOSTINC) {
- if (scanind->addConst == 1)
- loop->flags |= LP_LOOP_STEP_ISADD;
- if (scanind->addConst > 0)
- loop->flags |= LP_LOOP_STEP_ISPOS;
- }
- if (nd21->nodetype == EPREDEC || nd21->nodetype == EPOSTDEC) {
- if (scanind->addConst == 1)
- loop->flags |= LoopFlags_2000;
- if (scanind->addConst > 0)
- loop->flags |= LP_LOOP_STEP_ISNEG;
- }
- }
- loop->index24 = nd21->index;
- loop->index20 = IRO_FindStart(nd21)->index;
- }
-
- if (ind23) {
- tmp = IRO_FindStart(fnode->last->u.diadic.right);
- loop->flags |= LoopFlags_200;
- if (loop->flags & LoopFlags_10000) {
- for (scannd = loop->fnode->first; scannd && scannd != tmp; scannd = scannd->next) {
- if (scannd->type != IROLinearLabel && scannd->type != IROLinearNop)
- loop->flags &= ~LoopFlags_200;
- }
- } else {
- for (scannd = ind23->nd->next; scannd && scannd != tmp; scannd = scannd->next){
- if (scannd->type != IROLinearLabel && scannd->type != IROLinearNop)
- loop->flags &= ~LoopFlags_200;
- }
- for (scannd = loop->fnode->first; scannd && scannd != tmp; scannd = scannd->next){
- if ((scannd->index < loop->index20 || scannd->index > loop->index24) && scannd->type != IROLinearLabel && scannd->type != IROLinearNop)
- loop->flags &= ~LoopFlags_200;
- }
- }
- }
-
- for (scanfnode = IRO_FirstNode; scanfnode; scanfnode = scanfnode->nextnode) {
- if (Bv_IsBitSet(scanfnode->index, InLoop) && scanfnode != fnode && (scannd = scanfnode->first)) {
- while (1) {
- if (scannd->type == IROLinearFunccall)
- flag30 = 1;
- if (scannd->type == IROLinearGoto)
- flag28++;
- if (flag28 >= 1)
- flag29 = 1;
- if (scannd->type == IROLinearIf || scannd->type == IROLinearIfNot || scannd->type == IROLinearSwitch || scannd->type == IROLinearReturn)
- flag29 = 1;
-
- if (scannd->type == IROLinearAsm)
- loop->flags |= LP_LOOP_HAS_ASM;
-
- if (!(scannd->flags & IROLF_Reffed) && scannd->type != IROLinearNop && scannd->type != IROLinearLabel) {
- if (!IRO_IsAssignOp[scannd->nodetype]) {
- loop->flags |= LoopFlags_8;
- } else if (scannd->index < loop->index20 || scannd->index > loop->index24) {
- counter27++;
- if (IsAssignmentReductionCandidate(scannd) && counter27 == 1)
- loop->flags |= LoopFlags_40000;
- if (counter27 > 1)
- loop->flags &= ~LoopFlags_40000;
- }
- }
-
- if (scannd->index < loop->index20 || scannd->index > loop->index24) {
- if (IS_LINEAR_ENODE(scannd, EOBJREF)) {
- obj = scannd->u.node->data.objref;
- if ((scannd->flags & IROLF_Ind) && obj && obj == loop->induction->var->object) {
- if (!(scannd->flags & IROLF_Assigned) && (scannd->flags & IROLF_Used)) {
- IRO_Dump("Induction Used in loop\n");
- loop->flags |= LoopFlags_800;
- }
- }
- }
-
- if (IS_LINEAR_DIADIC(scannd, ESHR) &&
- (obj = IRO_IsVariable(scannd->u.diadic.left)) &&
- IRO_IsIntConstant(scannd->u.diadic.right)) {
- for (scanind = FirstInd; scanind; scanind = scanind->next) {
- if (scanind->var->object == obj) {
- IRO_Dump("Induction has DIV: %s\n", obj->name->name);
- scanind->flags |= LoopInd_HasDiv;
- }
- }
- }
-
- if (IS_LINEAR_DIADIC(scannd, EAND) &&
- (obj = IRO_IsVariable(scannd->u.diadic.left)) &&
- IRO_IsIntConstant(scannd->u.diadic.right)) {
- for (scanind = FirstInd; scanind && obj; scanind = scanind->next) {
- if (scanind->var->object == obj) {
- IRO_Dump("Induction has MOD: %s\n", obj->name->name);
- scanind->flags |= LoopInd_HasMod;
- }
- }
- }
- }
-
- ComputeIntWeight(loop, scannd);
- if (scannd == scanfnode->last)
- break;
- scannd = scannd->next;
- }
- }
-
- if (flag30)
- loop->flags |= LP_LOOP_HAS_CALLS;
- if (flag29)
- loop->flags |= LP_LOOP_HAS_CNTRLFLOW;
-
- for (i = 0; i < scanfnode->numsucc && scanfnode != fnode; i++) {
- if (Bv_IsBitSet(scanfnode->index, InLoop) && !Bv_IsBitSet(scanfnode->succ[i], InLoop)) {
- IRO_Dump("Node %d has an out of loop successor %d\n", scanfnode->index, scanfnode->succ[i]);
- IRO_DumpBits("Loop includes: ", InLoop);
- IRO_Dump("loop has multiple exits\n");
- loop->flags |= LoopFlags_1000;
- }
- }
- }
-
- return loop;
-}
-
-CLabel *BuildLabel(IROList *list) {
- IROLinear *nd;
-
- nd = IRO_NewLinear(IROLinearLabel);
- nd->index = IRO_NumLinear++;
- nd->u.label.label = IRO_NewLabel();
- nd->flags |= IROLF_1;
- IRO_AddToList(nd, list);
- return nd->u.label.label;
-}
-
-static void MoveInvarianceInAddressExpr(void) {
- IRONode *fnode;
- IROLinear *nd;
- IROLinear *start;
- IROList list;
-
- IRO_FirstExpr = IRO_LastExpr = NULL;
- IRO_NumExprs = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (Bv_IsBitSet(fnode->index, InLoop)) {
- for (nd = fnode->first; nd; nd = nd->next) {
- if (nd->type == IROLinearOp1Arg &&
- (nd->nodetype == EINDIRECT || nd->nodetype == EINDIRECT) &&
- IS_LINEAR_DIADIC(nd->u.monadic, EADD)) {
- RearrangeInvarianceInAddressExpr(nd->u.monadic, &list);
- start = IRO_FindStart(nd->u.monadic);
- IRO_LocateFather_Cut_And_Paste(nd->u.monadic, list.tail);
- IRO_Paste(list.head, list.tail, start);
- }
-
- if (nd == fnode->last)
- break;
- }
- }
- }
-
- IRO_UpdateFlagsOnInts();
-}
-
-static void AddAddendLinear(IROLinear *nd) {
- IROElmList *list;
-
- if (IS_LINEAR_DIADIC(nd, EADD)) {
- AddAddendLinear(nd->u.diadic.left);
- AddAddendLinear(nd->u.diadic.right);
- } else {
- list = oalloc(sizeof(IROElmList));
- list->element = nd;
- list->next = NULL;
- if (FirstAddendLinear)
- LastAddendLinear->next = list;
- else
- FirstAddendLinear = list;
- LastAddendLinear = list;
- }
-}
-
-static IROLinear *RearrangeInvarianceInAddressExpr(IROLinear *nd, IROList *list) {
- IROLinear *result;
- IROElmList *scanlist;
- IROElmList *elist;
- IROLinear *scannd;
-
- IRO_InitList(list);
- FirstAddendLinear = LastAddendLinear = NULL;
- AddAddendLinear(nd->u.diadic.left);
- AddAddendLinear(nd->u.diadic.right);
-
- elist = NULL;
- result = NULL;
- for (scanlist = FirstAddendLinear; scanlist; scanlist = scanlist->next) {
- scannd = scanlist->element;
- if (!IRO_IsIntConstant(scannd) && (scannd->flags & IROLF_LoopInvariant)) {
- if (result) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg);
- tmp->index = ++IRO_NumLinear;
- tmp->nodetype = EADD;
- tmp->u.diadic.left = result;
- tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list);
- IRO_AddToList(tmp, list);
- tmp->flags |= IROLF_LoopInvariant;
- tmp->flags |= IROLF_Reffed;
- tmp->rtype = result->rtype;
- result = tmp;
- } else {
- result = IRO_DuplicateExpr(scannd, list);
- }
-
- if (elist)
- elist->next = scanlist->next;
- else
- FirstAddendLinear = scanlist->next;
- } else {
- elist = scanlist;
- }
- }
-
- for (scanlist = FirstAddendLinear, elist = NULL; scanlist; scanlist = scanlist->next) {
- scannd = scanlist->element;
- if (!IRO_IsIntConstant(scannd)) {
- if (result) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg);
- tmp->index = ++IRO_NumLinear;
- tmp->nodetype = EADD;
- tmp->u.diadic.left = result;
- tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list);
- IRO_AddToList(tmp, list);
- tmp->flags |= IROLF_Reffed;
- tmp->rtype = result->rtype;
- result = tmp;
- } else {
- result = IRO_DuplicateExpr(scannd, list);
- }
-
- if (elist)
- elist->next = scanlist->next;
- else
- FirstAddendLinear = scanlist->next;
- } else {
- elist = scanlist;
- }
- }
-
- for (scanlist = FirstAddendLinear; scanlist; scanlist = scanlist->next) {
- scannd = scanlist->element;
- if (result) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg);
- tmp->index = ++IRO_NumLinear;
- tmp->nodetype = EADD;
- tmp->u.diadic.left = result;
- tmp->u.diadic.right = scannd;
- tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list);
- IRO_AddToList(tmp, list);
- tmp->flags |= IROLF_Reffed;
- tmp->rtype = result->rtype;
- result = tmp;
- } else {
- result = IRO_DuplicateExpr(scannd, list);
- }
- }
-
- return result;
-}
-
-static IROLinear *FindAddendForReductionPattern(IROLinear *a, IROLinear *b, Boolean *resultFlag) {
- IROLinear *left;
- IROLinear *right;
- IROLinear *node28;
- Boolean subflag;
-
- left = b->u.diadic.left;
- right = b->u.diadic.right;
- if (b->nodetype == EADD || b->nodetype == ESUB) {
- node28 = left;
- while (IS_LINEAR_MONADIC(node28, ETYPCON))
- node28 = node28->u.monadic;
-
- if (IS_LINEAR_MONADIC(node28, EINDIRECT) && (node28->u.monadic->flags & IROLF_LoopInvariant) && IRO_ExprsSame(a, node28)) {
- *resultFlag = 1;
- return left;
- }
-
- if (IS_LINEAR_DIADIC_2(node28, EADD, ESUB)) {
- if ((node28 = FindAddendForReductionPattern(a, node28, &subflag))) {
- *resultFlag = 1;
- return node28;
- }
- }
- }
-
- *resultFlag = 0;
- if (b->nodetype == EADD) {
- node28 = right;
- while (IS_LINEAR_MONADIC(node28, ETYPCON))
- node28 = node28->u.monadic;
-
- if (IS_LINEAR_MONADIC(node28, EINDIRECT) && (node28->u.monadic->flags & IROLF_LoopInvariant) && IRO_ExprsSame(a, node28)) {
- return right;
- }
-
- if (IS_LINEAR_DIADIC_2(node28, EADD, ESUB)) {
- if ((node28 = FindAddendForReductionPattern(a, node28, &subflag))) {
- return node28;
- }
- }
- }
-
- return NULL;
-}
-
-static void ReorderOperandsForReductionPattern(IROLinear *a, IROLinear *b) {
- IROLinear *left;
- IROLinear *right;
- IROLinear *addend;
- IROLinear *tmp;
- Boolean flag;
-
- left = b->u.diadic.left;
- right = b->u.diadic.right;
-
- if (b->nodetype == EADD && (addend = FindAddendForReductionPattern(a, b, &flag)) && addend != left) {
- if (flag && IS_LINEAR_DIADIC_2(left, EADD, ESUB) && addend->rtype == right->rtype) {
- tmp = left;
- b->u.diadic.left = right;
- left = right;
- b->u.diadic.right = tmp;
- right = tmp;
- flag = 0;
- }
-
- if (!flag && IS_LINEAR_DIADIC_2(right, EADD, ESUB) && addend->rtype == left->rtype) {
- if (IRO_LocateFather_Cut_And_Paste_Without_Nopping(addend, left))
- b->u.diadic.left = addend;
- }
- }
-}
-
-static UInt32 IsAssignmentReductionCandidate(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- IROLinear *tmp;
-
- if (nd->type == IROLinearOp2Arg) {
- if (nd->nodetype == EASS) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_LINEAR_MONADIC(left, EINDIRECT) && (left->u.monadic->flags & IROLF_LoopInvariant)) {
- if (IS_LINEAR_MONADIC(right, ETYPCON) &&
- right->rtype->type == right->u.monadic->rtype->type &&
- IS_TYPE_INT(right->rtype) &&
- right->rtype->size < right->u.monadic->rtype->size)
- right = right->u.monadic;
-
- if (IS_LINEAR_DIADIC_2(right, EADD, ESUB)) {
- ReorderOperandsForReductionPattern(left, right);
- tmp = right->u.diadic.left;
- if (IS_LINEAR_MONADIC(tmp, ETYPCON))
- tmp = tmp->u.monadic;
- if (IS_LINEAR_MONADIC(tmp, EINDIRECT) &&
- (tmp->u.monadic->flags & IROLF_LoopInvariant) &&
- IRO_ExprsSame(left, tmp) &&
- right->u.diadic.right->type == IROLinearOp2Arg) {
- if (right->u.diadic.right->nodetype == EADD)
- return 1;
- if (right->u.diadic.right->nodetype == ESUB)
- return 1;
- if (right->u.diadic.right->nodetype == EMUL)
- return 1;
- if (right->u.diadic.right->nodetype == EDIV)
- return 1;
- }
- }
- }
- } else if (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
-
- if (IS_LINEAR_MONADIC(right, ETYPCON) &&
- right->rtype->type == right->u.monadic->rtype->type &&
- IS_TYPE_INT(right->rtype) &&
- right->rtype->size < right->u.monadic->rtype->size)
- right = right->u.monadic;
-
- if (IS_LINEAR_MONADIC(left, EINDIRECT) &&
- (left->u.monadic->flags & IROLF_LoopInvariant) &&
- right->type == IROLinearOp2Arg) {
- if (right->nodetype == EADD)
- return 1;
- if (right->nodetype == ESUB)
- return 1;
- if (right->nodetype == EMUL)
- return 1;
- if (right->nodetype == EDIV)
- return 1;
- }
- }
- }
-
- return 0;
-}
-
diff --git a/compiler_and_linker/unsorted/IroMalloc.c b/compiler_and_linker/unsorted/IroMalloc.c
deleted file mode 100644
index 8928ba9..0000000
--- a/compiler_and_linker/unsorted/IroMalloc.c
+++ /dev/null
@@ -1,564 +0,0 @@
-#include "compiler/IroMalloc.h"
-#include "compiler/CompilerTools.h"
-
-#define FLAGMASK 0xF
-
-typedef struct Block {
- struct Block *prev;
- struct Block *next;
- void *x8;
- void *xC;
- size_t remain;
- size_t x14;
-} Block;
-
-typedef struct SubBlockBase {
- size_t x0;
- Block *block;
-} SubBlockBase;
-
-typedef struct SubBlock {
- size_t x0;
- Block *block;
- struct SubBlock *x8;
- struct SubBlock *xC;
-} SubBlock;
-
-typedef struct SubBlockTail {
- size_t x0copy;
-} SubBlockTail;
-
-typedef struct BlockTail {
- size_t x14copy;
- SubBlock *unk;
-} BlockTail;
-
-typedef struct FixStart {
- struct FixBlock *a;
- struct FixSubBlock *b;
- long count;
-} FixStart;
-
-typedef struct FixBlock {
- struct FixBlock *prev;
- struct FixBlock *next;
- size_t entrysize;
-} FixBlock;
-
-typedef struct FixSubBlockBase {
- FixBlock *fixblock;
-} FixSubBlockBase;
-
-typedef struct FixSubBlock {
- FixBlock *fixblock;
- struct FixSubBlock *next;
-} FixSubBlock;
-
-static const size_t fix_pool_sizes[] = {0xC, 0x1C, 0x2C, 0x4C};
-static Block *start_;
-static FixStart fix_start[4];
-static int initialized;
-
-// forward decls
-static void Block_link(Block *block, SubBlock *subblock);
-static void Block_unlink(Block *block, SubBlock *subblock);
-static void SubBlock_construct(SubBlock *subblock, size_t size, Block *block, int flag1, int flag2);
-static SubBlock *SubBlock_split(SubBlock *subblock, size_t pos);
-static SubBlock *SubBlock_merge_prev(SubBlock *subblock, SubBlock **sbptr);
-static void SubBlock_merge_next(SubBlock *subblock, SubBlock **sbptr);
-
-#define BLOCK_TAIL(block) ((BlockTail *) ((long) (block) + ((block)->x14 & ~FLAGMASK) - sizeof(BlockTail)))
-
-#define BUF_LOCATOR(buf) (*((size_t *) ((long) (buf) - sizeof(size_t))))
-#define SBB_BLOCK(sbb) ((Block *) ((long) ((sbb)->block) & ~1))
-
-#define BUF_IS_VAR(buf) (BUF_LOCATOR(buf) & 1)
-#define VARBUF_SBB(buf) ((SubBlockBase *) ((long) (buf) - sizeof(SubBlockBase)))
-#define VARBUF_SB(buf) ((SubBlock *) ((long) (buf) - sizeof(SubBlockBase)))
-#define VARBUF_BLOCKSIZE(buf) (VARBUF_SBB(buf)->x0 & ~FLAGMASK)
-#define VARBUF_SIZE(buf) (((VARBUF_SBB(buf)->x0 & ~FLAGMASK) - sizeof(SubBlockBase)))
-#define VARBUF_BLOCK(buf) SBB_BLOCK(VARBUF_SBB(buf))
-#define FIXBUF_SIZE(buf) (((FixBlock *) BUF_LOCATOR(buf))->entrysize)
-
-#define BUF_SIZE(buf) BUF_IS_VAR(buf) ? VARBUF_SIZE(buf) : FIXBUF_SIZE(buf)
-
-static void Block_construct(Block *block, size_t size) {
- SubBlock *subblock;
-
- block->x14 = size | 3;
- ((BlockTail *) ((long) block + size - sizeof(BlockTail)))->x14copy = block->x14;
-
- subblock = (SubBlock *) (block + 1);
- SubBlock_construct(subblock, size - sizeof(Block) - sizeof(BlockTail), block, 0, 0);
-
- block->remain = size - sizeof(Block) - sizeof(BlockTail);
- BLOCK_TAIL(block)->unk = NULL;
-
- Block_link(block, subblock);
-}
-
-static SubBlock *Block_subBlock(Block *block, size_t size) {
- SubBlock *subblock;
- size_t check;
- size_t best;
-
- if (!BLOCK_TAIL(block)->unk)
- return NULL;
-
- subblock = BLOCK_TAIL(block)->unk;
- best = subblock->x0 & ~FLAGMASK;
- check = subblock->x0 & ~FLAGMASK;
- while (check < size) {
- subblock = subblock->xC;
- check = subblock->x0 & ~FLAGMASK;
- if (best < check)
- best = check;
- if (subblock == BLOCK_TAIL(block)->unk) {
- block->remain = best;
- return NULL;
- }
- }
-
- if ((check - size) >= 0x60)
- SubBlock_split(subblock, size);
-
- BLOCK_TAIL(block)->unk = subblock->xC;
- Block_unlink(block, subblock);
- return subblock;
-}
-
-static void Block_link(Block *block, SubBlock *subblock) {
- size_t size;
- SubBlock **sbptr;
-
- size = subblock->x0 & ~FLAGMASK;
- subblock->x0 &= ~2;
- ((SubBlock *) ((long) subblock + size))->x0 &= ~4;
- ((SubBlockTail *) ((long) subblock + size - sizeof(SubBlockTail)))->x0copy = size;
-
- sbptr = &BLOCK_TAIL(block)->unk;
- if (*sbptr) {
- subblock->x8 = (*sbptr)->x8;
- subblock->x8->xC = subblock;
- subblock->xC = *sbptr;
- (*sbptr)->x8 = subblock;
- *sbptr = subblock;
- *sbptr = SubBlock_merge_prev(*sbptr, sbptr);
- SubBlock_merge_next(*sbptr, sbptr);
- } else {
- *sbptr = subblock;
- subblock->x8 = subblock;
- subblock->xC = subblock;
- }
-
- if (block->remain < ((*sbptr)->x0 & ~FLAGMASK))
- block->remain = (*sbptr)->x0 & ~FLAGMASK;
-}
-
-static void Block_unlink(Block *block, SubBlock *subblock) {
- size_t size;
- SubBlock **sbptr;
-
- size = subblock->x0 & ~FLAGMASK;
- subblock->x0 |= 2;
- ((SubBlock *) ((long) subblock + size))->x0 |= 4;
-
- sbptr = &BLOCK_TAIL(block)->unk;
- if (*sbptr == subblock)
- *sbptr = subblock->xC;
-
- if (*sbptr == subblock) {
- *sbptr = NULL;
- block->remain = 0;
- } else {
- subblock->xC->x8 = subblock->x8;
- subblock->x8->xC = subblock->xC;
- }
-}
-
-static void SubBlock_construct(SubBlock *subblock, size_t size, Block *block, int flag1, int flag2) {
- subblock->block = (Block *) ((long) block | 1);
- subblock->x0 = size;
- if (flag1)
- subblock->x0 |= 4;
- if (flag2) {
- subblock->x0 |= 2;
- ((SubBlock *) (((long) subblock) + size))->x0 |= 4;
- } else {
- ((SubBlockTail *) (((long) subblock) + size - sizeof(SubBlockTail)))->x0copy = size;
- }
-}
-
-static SubBlock *SubBlock_split(SubBlock *subblock, size_t pos) {
- size_t oldsize;
- int flag;
- SubBlock *splitright;
- Block *block;
-
- oldsize = subblock->x0 & ~FLAGMASK;
- flag = !(subblock->x0 & 2);
- splitright = (SubBlock *) ((long) subblock + pos);
- block = (Block *) ((long) subblock->block & ~1);
- SubBlock_construct(subblock, pos, block, subblock->x0 & 4, !flag);
- SubBlock_construct(splitright, oldsize - pos, block, !flag, !flag);
- if (flag) {
- splitright->xC = subblock->xC;
- splitright->xC->x8 = splitright;
- splitright->x8 = subblock;
- subblock->xC = splitright;
- }
-
- return splitright;
-}
-
-static SubBlock *SubBlock_merge_prev(SubBlock *subblock, SubBlock **sbptr) {
- size_t prevsize;
- SubBlock *prevblock;
-
- if (!(subblock->x0 & 4)) {
- prevsize = ((SubBlockTail *) ((long) subblock - sizeof(SubBlockTail)))->x0copy;
- if (prevsize & 2)
- return subblock;
-
- prevblock = (SubBlock *) ((long) subblock - prevsize);
- prevblock->x0 = prevblock->x0 & FLAGMASK;
- prevblock->x0 |= (prevsize + (subblock->x0 & ~FLAGMASK)) & ~FLAGMASK;
- if (!(prevblock->x0 & 2))
- ((SubBlockTail *) ((long) prevblock + prevsize + (subblock->x0 & ~FLAGMASK) - sizeof(SubBlockTail)))->x0copy = prevsize + (subblock->x0 & ~FLAGMASK);
-
- if (*sbptr == subblock)
- *sbptr = (*sbptr)->xC;
-
- subblock->xC->x8 = subblock->x8;
- subblock->xC->x8->xC = subblock->xC;
- return prevblock;
- }
-
- return subblock;
-}
-
-static void SubBlock_merge_next(SubBlock *subblock, SubBlock **sbptr) {
- SubBlock *nextblock;
- size_t nextsize;
-
- nextblock = (SubBlock *) ((long) subblock + (subblock->x0 & ~FLAGMASK));
- if (!(nextblock->x0 & 2)) {
- nextsize = (subblock->x0 & ~FLAGMASK) + (nextblock->x0 & ~FLAGMASK);
- subblock->x0 = subblock->x0 & FLAGMASK;
- subblock->x0 |= nextsize & ~FLAGMASK;
-
- if (!(subblock->x0 & 2))
- ((SubBlockTail *) ((long) subblock + nextsize - sizeof(SubBlockTail)))->x0copy = nextsize;
-
- if (!(subblock->x0 & 2))
- ((SubBlock *) ((long) subblock + nextsize))->x0 &= ~4;
- else
- ((SubBlock *) ((long) subblock + nextsize))->x0 |= 4;
-
- if (*sbptr == nextblock)
- *sbptr = (*sbptr)->xC;
- if (*sbptr == nextblock)
- *sbptr = NULL;
-
- nextblock->xC->x8 = nextblock->x8;
- nextblock->x8->xC = nextblock->xC;
- }
-}
-
-static void link_block(Block *block) {
- if (start_) {
- block->prev = start_->prev;
- block->prev->next = block;
- block->next = start_;
-
- start_->prev = block;
- start_ = block;
- } else {
- start_ = block;
- block->prev = block;
- block->next = block;
- }
-}
-
-static Block *unlink_block(Block *block) {
- Block *newblock;
-
- newblock = block->next;
- if (newblock == block)
- newblock = NULL;
-
- if (start_ == block)
- start_ = newblock;
-
- if (newblock) {
- newblock->prev = block->prev;
- newblock->prev->next = newblock;
- }
-
- block->prev = block->next = NULL;
- return newblock;
-}
-
-static Block *link_new_block(size_t size) {
- Block *block;
-
- size = (size + 0x1000 + sizeof(Block) + sizeof(BlockTail) - 1) & ~0xFFF;
- if (size < 0x10000)
- size = 0x10000;
-
- if (!(block = galloc(size)))
- return NULL;
-
- Block_construct(block, size);
- link_block(block);
- return block;
-}
-
-static void *allocate_from_var_pools(size_t size) {
- Block *block;
- SubBlock *subblock;
-
- size = (size + sizeof(Block) - 1) & ~0xF;
- if (size < 0x60)
- size = 0x60;
-
- block = start_ ? start_ : link_new_block(size);
- if (!block)
- return NULL;
-
- do {
- if (size <= block->remain) {
- if ((subblock = Block_subBlock(block, size))) {
- start_ = block;
- goto allocated;
- }
- }
- } while ((block = block->next) != start_);
-
- block = link_new_block(size);
- if (!block)
- return NULL;
- subblock = Block_subBlock(block, size);
-allocated:
- return (SubBlockBase *) subblock + 1;
-}
-
-static void deallocate_from_var_pools(void *buf) {
- Block *block;
- SubBlock *subblock;
- int flag;
-
- subblock = (SubBlock *) ((long) buf - sizeof(SubBlockBase));
- block = (Block *) ((long) subblock->block & ~1);
- Block_link(block, subblock);
-
- flag = 0;
- subblock = (SubBlock *) (block + 1);
- if (!(subblock->x0 & 2)) {
- if ((subblock->x0 & ~FLAGMASK) == ((block->x14 & ~FLAGMASK) - sizeof(Block) - sizeof(BlockTail)))
- flag = 1;
- }
-
- if (flag)
- unlink_block(block);
-}
-
-static void FixBlock_construct(FixBlock *fixblock, FixBlock *prev, FixBlock *next, int poolIndex, void *buffer, size_t buffersize) {
- size_t entrysize;
- size_t entrycount;
- size_t i;
- FixSubBlock *fsb;
- FixSubBlock *fsbnext;
-
- fixblock->prev = prev;
- fixblock->next = next;
- fixblock->entrysize = fix_pool_sizes[poolIndex];
-
- entrysize = fix_pool_sizes[poolIndex] + sizeof(void *);
- entrycount = (buffersize / entrysize);
- fsb = buffer;
- for (i = 0; i < (entrycount - 1); i++) {
- fsbnext = (FixSubBlock *) ((long) fsb + entrysize);
- fsb->fixblock = fixblock;
- fsb->next = fsbnext;
- fsb = fsbnext;
- }
-
- fsb->fixblock = fixblock;
- fsb->next = fix_start[poolIndex].b;
- fix_start[poolIndex].b = buffer;
-}
-
-static void *allocate_from_fixed_pools(size_t size) {
- int poolIndex;
- FixSubBlock *fsb;
-
- poolIndex = 0;
- while (size > fix_pool_sizes[poolIndex])
- poolIndex++;
-
- if (!fix_start[poolIndex].b) {
- void *buf;
- size_t bufsize;
-
- buf = allocate_from_var_pools(4000);
- if (!buf)
- return NULL;
-
- bufsize = !BUF_IS_VAR(buf) ? FIXBUF_SIZE(buf) : VARBUF_SIZE(buf);
- FixBlock_construct(
- buf, NULL, fix_start[poolIndex].a, poolIndex,
- ((FixBlock *) buf) + 1,
- bufsize - sizeof(FixBlock)
- );
- fix_start[poolIndex].a = buf;
- }
-
- fsb = fix_start[poolIndex].b;
- fix_start[poolIndex].b = fsb->next;
- fix_start[poolIndex].count++;
- return ((FixSubBlockBase *) fsb) + 1;
-}
-
-static void deallocate_from_fixed_pools(void *buf, size_t size) {
- int poolIndex;
- FixBlock *fixblock;
- FixBlock *nextfb;
- FixSubBlock *fsb;
-
- poolIndex = 0;
- while (size > fix_pool_sizes[poolIndex])
- poolIndex++;
-
- fsb = (FixSubBlock *) ((long) buf - sizeof(FixSubBlockBase));
- fsb->next = fix_start[poolIndex].b;
- fix_start[poolIndex].b = fsb;
- if (--fix_start[poolIndex].count == 0) {
- fixblock = fix_start[poolIndex].a;
- while (fixblock) {
- nextfb = fixblock->next;
- deallocate_from_var_pools(fixblock);
- fixblock = nextfb;
- }
- fix_start[poolIndex].a = NULL;
- fix_start[poolIndex].b = NULL;
- }
-}
-
-size_t IRO_msize(void *buf) {
- return BUF_SIZE(buf);
-}
-
-void *IRO_malloc(size_t size) {
- if (!size)
- return NULL;
-
- if (size <= 0x4C)
- return allocate_from_fixed_pools(size);
- else
- return allocate_from_var_pools(size);
-}
-
-void IRO_free(void *buf) {
- if (buf) {
- size_t size = !BUF_IS_VAR(buf) ? FIXBUF_SIZE(buf) : VARBUF_SIZE(buf);
-
- if (size <= 0x4C)
- deallocate_from_fixed_pools(buf, size);
- else
- deallocate_from_var_pools(buf);
- }
-}
-
-void *IRO_realloc(void *buf, size_t newsize) {
- size_t oldsize;
- size_t newblocksize;
- void *newbuf;
-
- if (!buf)
- return IRO_malloc(newsize);
-
- if (!newsize) {
- IRO_free(buf);
- return NULL;
- }
-
- oldsize = !BUF_IS_VAR(buf) ? FIXBUF_SIZE(buf) : VARBUF_SIZE(buf);
- if (newsize > oldsize) {
- if (BUF_IS_VAR(buf)) {
- newblocksize = (newsize + sizeof(Block) - 1) & ~FLAGMASK;
- if (newblocksize < 0x60)
- newblocksize = 0x60;
- SubBlock_merge_next(VARBUF_SB(buf), &BLOCK_TAIL(VARBUF_BLOCK(buf))->unk);
- if (VARBUF_BLOCKSIZE(buf) >= newblocksize) {
- if ((VARBUF_BLOCKSIZE(buf) - newblocksize) >= 0x60) {
- Block_link(VARBUF_BLOCK(buf), SubBlock_split(VARBUF_SB(buf), newblocksize));
- }
- return buf;
- }
- }
-
- newbuf = IRO_malloc(newsize);
- if (!newbuf)
- return NULL;
-
- memcpy(newbuf, buf, oldsize);
- IRO_free(buf);
- return newbuf;
- }
-
- if (BUF_IS_VAR(buf)) {
- newsize = (newsize + sizeof(Block) - 1) & ~FLAGMASK;
- if (newsize < 0x60)
- newsize = 0x60;
- if ((VARBUF_BLOCKSIZE(buf) - newsize) >= 0x60) {
- Block_link(VARBUF_BLOCK(buf), SubBlock_split(VARBUF_SB(buf), newsize));
- }
- }
-
- return buf;
-}
-
-void *IRO_calloc(size_t a, size_t b) {
- void *buf;
- size_t len = b * a;
- buf = IRO_malloc(len);
- if (buf)
- memset(buf, 0, len);
- return buf;
-}
-
-void IRO_pool_free_all(void) {
- int i;
- Block *block;
- if ((block = start_)) {
- do {
- block = block->next;
- } while (block != start_);
- start_ = NULL;
-
- for (i = 0; i < 4; i++) {
- fix_start[i].a = NULL;
- fix_start[i].b = NULL;
- fix_start[i].count = 0;
- }
- }
-}
-
-void IRO_InitializeAllocator(void) {
- if (!initialized) {
- int i;
- for (i = 0; i < 4; i++) {
- fix_start[i].a = NULL;
- fix_start[i].b = NULL;
- fix_start[i].count = 0;
- }
- start_ = NULL;
- initialized = 1;
- }
-}
-
-void IRO_TerminateAllocator(void) {
- initialized = 0;
-}
-
diff --git a/compiler_and_linker/unsorted/IroPointerAnalysis.c b/compiler_and_linker/unsorted/IroPointerAnalysis.c
deleted file mode 100644
index 4fcb8d3..0000000
--- a/compiler_and_linker/unsorted/IroPointerAnalysis.c
+++ /dev/null
@@ -1,5734 +0,0 @@
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroEval.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CDecl.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CPrep.h"
-#include "compiler/CPrepTokenizer.h"
-#include "compiler/CScope.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler_and_linker/unsorted/IroPointerAnalysisADTs.c"
-
-// forward decls
-static Object *GetLocalObject(PALocalVar *local, Object *proc, Boolean flag);
-static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls, Object *var, Stack **stackPtr, ParamMappingFunction *map, Boolean flag);
-static int ExpandLocationSetSetToActuals(Stack **stackPtr, ParamMappingFunction *map, LocationSetSet *thingsPointedTo);
-static Boolean Lookup(LocationSetSet *set, Stack **stackPtr, Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf, LocationSet *dst, PointsToFunction *pointsToFunc, Boolean unk, Type *indRtype);
-static ExtendedParam *CreateExtendedParam(Stack **stackPtr, ParamMappingFunction *map, Object *var, Boolean *result);
-static Boolean Assign(PartialTransferFunction *ptf, LocationSet *dst, LocationSetSet *srcs, Object *proc, IROLinear *nd, IRONode *fnode);
-static ObjectList *FunctionArguments(Object *proc);
-static IRONode **FunctionNodeTable(Object *proc);
-static Boolean ApplySummary(PartialTransferFunction *tgtPTF, ParamMappingFunction *tgtMap, Object *proc, IRONode *fnode, IROLinear *nd, PartialTransferFunction *ptf, ParamMappingFunction *map, Boolean flag);
-static PartialTransferFunction *GetPTF(ParamMappingFunction *map, Object *proc, IROLinear *nd, PartialTransferFunction *ptf, Boolean *needVisit);
-static Boolean ObjectIsAFunctionArgument(Object *proc, Object *obj);
-static Boolean ObjectIsARealFunctionArgument(Object *proc, Object *obj);
-static void EvalProc(Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf);
-static void FindGlobalObjectAction(Object *object, void *refcon);
-
-static Boolean ObjectIsRestrictQualified(Object *obj) {
- return (CParser_GetTypeQualifiers(obj->type, obj->qual) & Q_RESTRICT) != 0;
-}
-
-static Boolean LocationIsVolatile(LocationSet *loc, Object *proc) {
- Boolean result;
- Type *rtype;
-
- IRO_ASSERT(932, loc != NULL);
- IRO_ASSERT(933, proc != NULL);
-
- result = 0;
-
- if ((rtype = LocationSet_rtype(loc))) {
- UInt32 qual;
- switch (rtype->type) {
- case TYPEARRAY:
- qual = TYPE_POINTER(rtype)->qual;
- break;
- case TYPEPOINTER:
- qual = TYPE_POINTER(rtype)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(rtype)->qual;
- break;
- default:
- qual = 0;
- }
- if (qual & Q_VOLATILE)
- result = 1;
- }
-
- if (!result && !LocationSet_IsUnknown(loc)) {
- Object *obj = NULL;
- PAMemoryBlock *block = LocationSet_block(loc);
-
- switch (PAMemoryBlock_kind(block)) {
- case PAMEMORYBLOCKKIND_LOCALVAR: {
- PALocalVar *local = PAMemoryBlock_thing(block);
- if (local)
- obj = GetLocalObject(local, proc, 0);
- break;
- }
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM: {
- ExtendedParam *ep = PAMemoryBlock_thing(block);
- if (ep) {
- ObjectSet *objSet = ExtendedParam_objectSet(ep);
- if (objSet) {
- if (ObjectSet_Count(objSet) == 1)
- obj = ObjectSet_FindFirst(objSet);
- else
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- }
- }
- break;
- }
- }
-
- if (obj && is_volatile_object(obj))
- result = 1;
- }
-
- return result;
-}
-
-static Object *GetLocalObject(PALocalVar *local, Object *proc, Boolean flag) {
- ObjectList *list;
- Object *arg;
- Object *obj;
- char *name;
-
- IRO_ASSERT(999, local != NULL);
- IRO_ASSERT(1000, proc != NULL);
-
- obj = PALocalVar_Get0_sub_4847E0(local);
- name = PALocalVar_Get4_sub_4847D0(local);
-
- if (proc != &stUnknown && !obj && name && name[0] && flag) {
- for (list = FunctionArguments(proc); list && !obj; list = list->next) {
- arg = list->object;
- if (arg && arg != &stUnknown && arg->name && arg->name->name) {
- if (!strcmp(arg->name->name, name))
- obj = arg;
- }
- }
- }
-
- if (obj)
- PALocalVar_SetSth_sub_4847C0(local, obj);
-
- return obj;
-}
-
-static Boolean ObjectIsAnExtendedParamCandidate(Object *obj) {
- IRO_ASSERT(1042, obj != NULL);
-
- return Inline_IsObjectData(obj) ||
- obj->datatype == DABSOLUTE ||
- obj->datatype == DFUNC ||
- obj->datatype == DVFUNC ||
- obj->datatype == DINLINEFUNC;
-}
-
-static Boolean ObjectIsAFunction(Object *obj) {
- IRO_ASSERT(1054, obj != NULL);
-
- return obj->datatype == DFUNC ||
- obj->datatype == DVFUNC ||
- obj->datatype == DINLINEFUNC;
-}
-
-static Boolean LocationSetRepresentsSingleLocation(LocationSet *ls, Object *proc, PointsToFunction *pointsToFunc) {
- Boolean result;
- PAMemoryBlock *mb;
- PAMemoryBlockKind kind;
- ExtendedParam *ep;
- ObjectSet *objSet;
-
- IRO_ASSERT(1073, ls != NULL);
- IRO_ASSERT(1074, proc == NULL || proc != NULL);
- IRO_ASSERT(1075, pointsToFunc == NULL || pointsToFunc != NULL);
-
- result = 1;
- if (LocationSet_IsUnknown(ls) || LocationSet_stride(ls)) {
- result = 0;
- } else {
- mb = LocationSet_block(ls);
- IRO_ASSERT(1084, mb != NULL);
-
- kind = PAMemoryBlock_kind(mb);
- if (kind == PAMEMORYBLOCKKIND_HEAPBLOCK) {
- result = 0;
- } else if (kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- ep = PAMemoryBlock_thing(mb);
- if (!ep) {
- result = 0;
- } else {
- if ((objSet = ExtendedParam_objectSet(ep)) && ObjectSet_Count(objSet) > 1) {
- Object *obj = NULL;
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
-
- if (!obj) {
- LocationSetSet *lss;
- LocationSet *tmp;
- ExtendedParam *ep;
- ObjectSet *objSet;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- GetActualLocsOfExtendedParam(lss, ls, NULL, &stCallingContextStack, NULL, 0);
- if (
- LocationSetSet_Count(lss) != 1 ||
- !(tmp = LocationSetSet_FindFirst(lss)) ||
- LocationSet_IsUnknown(tmp) ||
- (!((mb = LocationSet_block(tmp)) && (PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) && (ep = PAMemoryBlock_thing(mb)) && (objSet = ExtendedParam_objectSet(ep)) && (ObjectSet_Count(objSet) == 1) &&
- ObjectIsAnExtendedParamCandidate(ObjectSet_FindFirst(objSet))) &&
- !LocationSetRepresentsSingleLocation(tmp, proc, pointsToFunc))
- )
- result = 0;
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
- }
- }
- }
- }
-
- return result;
-}
-
-static void EvalExprAction(LocationSet *ls, void *refcon) {
- CInt64 value;
- UInt32 stride;
- PAMemoryBlock *mb;
-
- IRO_ASSERT(1151, ls != NULL);
- IRO_ASSERT(1152, !LocationSet_IsUnknown(ls));
- IRO_ASSERT(1153, refcon != NULL);
-
- value = *((CInt64 *) refcon);
- stride = LocationSet_stride(ls);
- mb = LocationSet_block(ls);
-
- if (mb && PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_INT) {
- Type *rtype = LocationSet_rtype(ls);
- LocationSet_Term(ls);
- value = CInt64_Add(value, *((CInt64 *) PAMemoryBlock_thing(mb)));
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, PAMEMORYBLOCKKIND_INT, &value);
- LocationSet_InitKnown(ls, mb, cint64_zero, stride, rtype);
- } else {
- value = CInt64_Add(value, LocationSet_field(ls));
- if (stride) {
- CInt64 strideval;
- CInt64_SetLong(&strideval, stride);
- value = CInt64_Mod(value, strideval);
- }
- SetsLocationSetField_sub_4851B0(ls, value);
- }
-}
-
-static void EvalExprAction2(LocationSet *ls, void *refcon) {
- UInt32 value;
-
- IRO_ASSERT(1188, ls != NULL);
- IRO_ASSERT(1189, !LocationSet_IsUnknown(ls));
- IRO_ASSERT(1190, refcon != NULL);
-
- value = CInt64_GetULong((CInt64 *) refcon);
- if (value) {
- SetsLocationSetField_sub_4851B0(ls, CInt64_Mod(LocationSet_field(ls), *((CInt64 *) refcon)));
- }
- SetsLocationSetStride_sub_4852D0(ls, value);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalExprAction3Params {
- LocationSetSet *set;
- Stack **stackPtr;
- Object *proc;
- ParamMappingFunction *map;
- PartialTransferFunction *ptf;
- PointsToFunction *pointsToFunc;
- Type *indRtype;
- Boolean x1C;
-} EvalExprAction3Params;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalExprAction3(LocationSet *ls, void *refcon) {
- EvalExprAction3Params *params;
-
- IRO_ASSERT(1219, ls != NULL);
- IRO_ASSERT(1220, refcon != NULL);
-
- params = refcon;
-
- params->x1C |= Lookup(
- params->set,
- params->stackPtr,
- params->proc,
- params->map,
- params->ptf,
- ls,
- params->pointsToFunc,
- 1,
- params->indRtype
- );
-}
-
-static void EvalExprAction4(LocationSet *ls, void *refcon) {
- Type *type;
- PAMemoryBlock *mb;
-
- IRO_ASSERT(1235, ls != NULL);
- IRO_ASSERT(1236, refcon != NULL);
-
- type = refcon;
-
- if (LocationSet_IsUnknown(ls)) {
- LocationSet_SetRtype(ls, type);
- } else if ((mb = LocationSet_block(ls))) {
- if (PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_INT) {
- CInt64 value;
- CInt64 field;
- UInt32 stride;
-
- value = *((CInt64 *) PAMemoryBlock_thing(mb));
- IRO_TruncateValueToType(&value, type);
- field = LocationSet_field(ls);
- IRO_TruncateValueToType(&field, type);
- stride = LocationSet_stride(ls);
- LocationSet_Term(ls);
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, PAMEMORYBLOCKKIND_INT, &value);
-
- LocationSet_InitKnown(ls, mb, field, stride, type);
- }
- LocationSet_SetRtype(ls, type);
- }
-}
-
-static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack **stackPtr, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- Boolean result;
- LocationSetSet *lss;
- LocationSetSet *lss2;
- IROLinear *indirect;
- EvalExprAction3Params params;
- IROLinear *originalInt;
-
- IRO_ASSERT(1284, set == NULL || set != NULL);
- IRO_ASSERT(1285, proc != NULL);
- IRO_ASSERT(1286, Int != NULL);
- IRO_ASSERT(1287, map == NULL || map != NULL);
- IRO_ASSERT(1288, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
-
- result = 0;
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
-
- originalInt = Int;
- while (Int && Int->type == IROLinearOp1Arg && Int->nodetype == ETYPCON)
- Int = Int->u.monadic;
-
- IRO_ASSERT(1302, Int != NULL);
-
- if (IRO_IsAssignment(Int)) {
- if (Int->type == IROLinearOp1Arg)
- indirect = Int->u.monadic;
- else
- indirect = Int->u.diadic.left;
- IRO_ASSERT(1310, indirect->type == IROLinearOp1Arg && indirect->nodetype == EINDIRECT);
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalExpr(lss2, proc, indirect->u.monadic, stackPtr, map, ptf);
-
- memset(&params, 0, sizeof(params));
- params.set = lss;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- if (Int->nodetype == EPOSTINC || Int->nodetype == EPOSTDEC)
- params.pointsToFunc = indirect->pointsToFunction;
- else
- params.pointsToFunc = Int->pointsToFunction;
- params.indRtype = indirect->rtype;
- params.x1C = 0;
- LocationSetSet_ForEach(lss2, EvalExprAction3, &params);
- result |= params.x1C;
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else if (Int->type == IROLinearFunccall) {
- IRO_ASSERT(1338, Int->u.funccall.returnedLocs != NULL);
- LocationSetSet_AddSet(lss, Int->u.funccall.returnedLocs);
- } else if (Int->type == IROLinearOp1Arg && Int->nodetype == EINDIRECT) {
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalExpr(lss2, proc, Int->u.monadic, stackPtr, map, ptf);
-
- memset(&params, 0, sizeof(params));
- params.set = lss;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- params.pointsToFunc = Int->pointsToFunction;
- params.indRtype = Int->rtype;
- params.x1C = 0;
- LocationSetSet_ForEach(lss2, EvalExprAction3, &params);
- result |= params.x1C;
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else if (Int->type == IROLinearOp2Arg && Int->nodetype == EADD) {
- IROAddrRecord *addr = IRO_InitAddrRecordPointer(Int);
- IRO_DecomposeAddressExpression(Int, addr);
- if (addr->numObjRefs > 1) {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- } else {
- CInt64 value;
- CInt64 max;
- CInt64 work;
- Boolean flag1;
- Boolean flag2;
-
- CInt64_SetLong(&value, 0);
- flag1 = 0;
- flag2 = 0;
- if (addr->numObjRefs == 1) {
- Object *obj;
- IRO_ASSERT(1383, addr->objRefs->element->type == IROLinearOperand);
- IRO_ASSERT(1384, addr->objRefs->element->u.node->type == EOBJREF);
- obj = ((IROLinear *) addr->objRefs->element)->u.node->data.objref;
- IRO_ASSERT(1387, obj != NULL);
- result |= EvalExpr(lss, proc, addr->objRefs->element, stackPtr, map, ptf);
- flag2 = 1;
- }
-
- if (addr->numMisc != 0) {
- IROElmList *list;
- IROLinear *nd;
- max = cint64_max;
-
- for (list = addr->misc; list; list = list->next) {
- nd = list->element;
- while (nd && nd->type == IROLinearOp1Arg && nd->nodetype == ETYPCON)
- nd = nd->u.monadic;
-
- if (nd) {
- if (nd->type == IROLinearOp2Arg && nd->nodetype == EMUL) {
- if (IRO_IsIntConstant(nd->u.diadic.left) && IRO_IsIntConstant(nd->u.diadic.right)) {
- if (IRO_IsUnsignedType(nd->rtype))
- work = CInt64_MulU(nd->u.diadic.left->u.node->data.intval, nd->u.diadic.right->u.node->data.intval);
- else
- work = CInt64_Mul(nd->u.diadic.left->u.node->data.intval, nd->u.diadic.right->u.node->data.intval);
- IRO_TruncateValueToType(&work, ((IROLinear *) list->element)->rtype);
- value = CInt64_Add(value, work);
- } else if (IRO_IsIntConstant(nd->u.diadic.left)) {
- work = nd->u.diadic.left->u.node->data.intval;
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else if (IRO_IsIntConstant(nd->u.diadic.right)) {
- work = nd->u.diadic.right->u.node->data.intval;
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else {
- max = cint64_one;
- }
- } else if (nd->type == IROLinearOp2Arg && nd->nodetype == ESHL) {
- if (IRO_IsIntConstant(nd->u.diadic.left) && IRO_IsIntConstant(nd->u.diadic.right)) {
- work = CInt64_Shl(nd->u.diadic.left->u.node->data.intval, nd->u.diadic.right->u.node->data.intval);
- IRO_TruncateValueToType(&work, ((IROLinear *) list->element)->rtype);
- value = CInt64_Add(value, work);
- } else if (IRO_IsIntConstant(nd->u.diadic.right)) {
- work = CInt64_Shl(cint64_one, nd->u.diadic.right->u.node->data.intval);
- IRO_TruncateValueToType(&work, ((IROLinear *) list->element)->rtype);
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else {
- max = cint64_one;
- }
- } else {
- LocationSet *tmp;
- PAMemoryBlock *mb;
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalExpr(lss2, proc, nd, stackPtr, map, ptf);
-
- if (LocationSetSet_FindUnknown(lss2)) {
- max = cint64_one;
- } else if (
- LocationSetSet_Count(lss2) == 1 &&
- (tmp = LocationSetSet_FindFirst(lss2)) &&
- (LocationSet_stride(tmp) == 0) &&
- (mb = LocationSet_block(tmp)) &&
- (PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_INT)
- ) {
- value = CInt64_Add(value, *((CInt64 *) PAMemoryBlock_thing(mb)));
- } else if (!flag2 && (IS_TYPE_POINTER(nd->rtype) || IS_TYPE_MEMBERPOINTER(nd->rtype))) {
- if (flag1) {
- LocationSetSet_RemoveAll(lss);
- max = cint64_one;
- }
- LocationSetSet_AddSet(lss, lss2);
- flag2 = 1;
- } else if (IS_TYPE_POINTER(nd->rtype) || IS_TYPE_MEMBERPOINTER(nd->rtype)) {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- } else if (!flag1) {
- LocationSetSet_AddSet(lss, lss2);
- flag1 = 1;
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- }
- }
- }
-
- if (IS_TYPE_POINTER(Int->rtype))
- CInt64_SetLong(&work, TYPE_POINTER(Int->rtype)->target->size);
- else if (IS_TYPE_MEMBERPOINTER(Int->rtype))
- CInt64_SetLong(&work, TYPE_MEMBER_POINTER(Int->rtype)->ty1->size);
- else
- work = cint64_zero;
-
- if (CInt64_GreaterU(work, max))
- max = work;
- }
-
- if (addr->numInts != 0) {
- IROElmList *list;
- IROLinear *addend;
-
- for (list = addr->ints; list; list = list->next) {
- addend = list->element;
-
- if (addend) {
- IRO_ASSERT(1536, IRO_IsIntConstant(addend));
-
- value = CInt64_Add(value, addend->u.node->data.intval);
- }
- }
- }
-
- IRO_TruncateValueToType(&value, Int->rtype);
-
- if (LocationSetSet_Count(lss) == 0) {
- if (CInt64_Equal(max, cint64_max)) {
- PAMemoryBlock *mb;
- LocationSet *ls;
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, PAMEMORYBLOCKKIND_INT, &value);
-
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, mb, cint64_zero, 0, Int->rtype);
- LocationSetSet_Add(lss, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
- } else {
- if (!LocationSetSet_FindUnknown(lss) && !CInt64_IsZero(&value))
- LocationSetSet_ForEach(lss, EvalExprAction, &value);
- }
-
- if (!LocationSetSet_FindUnknown(lss) && addr->numMisc && !CInt64_Equal(max, cint64_max))
- LocationSetSet_ForEach(lss, EvalExprAction2, &max);
- }
- } else if (Int->type == IROLinearOperand) {
- Object *obj;
- void *thing;
- PAMemoryBlockKind kind;
-
- thing = NULL;
- if (IRO_IsIntConstant(Int)) {
- kind = PAMEMORYBLOCKKIND_INT;
- thing = &Int->u.node->data.intval;
- } else if (Int->u.node->type == ESTRINGCONST) {
- kind = PAMEMORYBLOCKKIND_6;
- thing = Int->u.node;
- } else if (Int->u.node->type == EOBJREF) {
- obj = Int->u.node->data.objref;
- IRO_ASSERT(1597, obj != NULL);
- if (ObjectIsAnExtendedParamCandidate(obj)) {
- kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM;
- thing = CreateExtendedParam(stackPtr, map, obj, &result);
- } else {
- kind = PAMEMORYBLOCKKIND_LOCALVAR;
- thing = PALocalVar_New();
- if (obj->name && obj->name->name && ObjectIsARealFunctionArgument(proc, obj))
- PALocalVar_InitByName(thing, obj->name->name);
- else
- PALocalVar_InitByObject(thing, obj);
- }
- }
-
- if (thing) {
- PAMemoryBlock *mb;
- LocationSet *ls;
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, kind, thing);
-
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, mb, cint64_zero, 0, Int->rtype);
- LocationSetSet_Add(lss, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- }
- } else if (Int->type == IROLinearOp1Arg && Int->nodetype == EBITFIELD) {
- LocationSet *ls;
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalExpr(lss2, proc, Int->u.monadic, stackPtr, map, ptf);
-
- if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2)))
- LocationSetSet_AddUnknown(lss, NULL, NULL, ls);
- else
- CError_FATAL(1643);
-
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
-
- LocationSetSet_ForEach(lss, EvalExprAction4, originalInt->rtype);
-
- if (set && lss)
- LocationSetSet_AddSet(set, lss);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-
- return result;
-}
-
-static IROAddrRecord *IRO_InitENodeAddrRecordPointer(ENode *enode) {
- IROAddrRecord *addr = IRO_malloc(sizeof(IROAddrRecord));
-
- addr->numObjRefs = 0;
- addr->objRefs = NULL;
- addr->numMisc = 0;
- addr->misc = NULL;
- addr->numInts = 0;
- addr->ints = NULL;
- addr->x16 = 0;
- addr->linear = (IROLinear *) enode;
-
- return addr;
-}
-
-static void IRO_AddENodeElmToList(ENode *linear, IROElmList **list) {
- IROElmList *elmlist = IRO_malloc(sizeof(IROElmList));
- elmlist->element = linear;
- elmlist->next = NULL;
- if (!*list) {
- *list = elmlist;
- } else {
- elmlist->next = *list;
- *list = elmlist;
- }
-}
-
-static void IRO_DecomposeENodeAddressExpression(ENode *node, IROAddrRecord *addr) {
- if (node->data.diadic.left->type == EADD) {
- IRO_DecomposeENodeAddressExpression(node->data.diadic.left, addr);
- } else if (node->data.diadic.left->type == EINTCONST) {
- addr->numInts++;
- IRO_AddENodeElmToList(node->data.diadic.left, &addr->ints);
- } else if (node->data.diadic.left->type == EOBJREF) {
- addr->numObjRefs++;
- IRO_AddENodeElmToList(node->data.diadic.left, &addr->objRefs);
- } else {
- addr->numMisc++;
- IRO_AddENodeElmToList(node->data.diadic.left, &addr->misc);
- }
-
- if (node->data.diadic.right->type == EADD) {
- IRO_DecomposeENodeAddressExpression(node->data.diadic.right, addr);
- } else if (node->data.diadic.right->type == EINTCONST) {
- addr->numInts++;
- IRO_AddENodeElmToList(node->data.diadic.right, &addr->ints);
- } else if (node->data.diadic.right->type == EOBJREF) {
- addr->numObjRefs++;
- IRO_AddENodeElmToList(node->data.diadic.right, &addr->objRefs);
- } else {
- addr->numMisc++;
- IRO_AddENodeElmToList(node->data.diadic.right, &addr->misc);
- }
-}
-
-static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stack **stackPtr, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- Boolean result;
- LocationSetSet *lss;
- LocationSetSet *lss2;
- ENode *indirect;
- EvalExprAction3Params params;
- ENode *originalInt;
-
- IRO_ASSERT(0, set == NULL || set != NULL);
- IRO_ASSERT(0, proc != NULL);
- IRO_ASSERT(0, Int != NULL);
- IRO_ASSERT(0, map == NULL || map != NULL);
- IRO_ASSERT(0, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
-
- result = 0;
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
-
- originalInt = Int;
- while (Int && Int->type == ETYPCON)
- Int = Int->data.monadic;
-
- IRO_ASSERT(0, Int != NULL);
-
- if (IRO_IsAssignOp[Int->type]) {
- if (Int->type == EPOSTINC || Int->type == EPOSTDEC || Int->type == EPREINC || Int->type == EPREDEC)
- indirect = Int->data.monadic;
- else
- indirect = Int->data.diadic.left;
- IRO_ASSERT(0, indirect->type == EINDIRECT);
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalENodeExpr(lss2, proc, indirect->data.monadic, stackPtr, map, ptf);
-
- memset(&params, 0, sizeof(params));
- params.set = lss;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- if (Int->type == EPOSTINC || Int->type == EPOSTDEC)
- params.pointsToFunc = indirect->pointsTo;
- else
- params.pointsToFunc = Int->pointsTo;
- params.indRtype = indirect->rtype;
- params.x1C = 0;
- LocationSetSet_ForEach(lss2, EvalExprAction3, &params);
- result |= params.x1C;
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else if (Int->type == EINDIRECT) {
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalENodeExpr(lss2, proc, Int->data.monadic, stackPtr, map, ptf);
-
- memset(&params, 0, sizeof(params));
- params.set = lss;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- params.pointsToFunc = Int->pointsTo;
- params.indRtype = Int->rtype;
- params.x1C = 0;
- LocationSetSet_ForEach(lss2, EvalExprAction3, &params);
- result |= params.x1C;
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else if (Int->type == EADD) {
- IROAddrRecord *addr = IRO_InitENodeAddrRecordPointer(Int);
- IRO_DecomposeENodeAddressExpression(Int, addr);
- if (addr->numObjRefs > 1) {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- } else {
- CInt64 value;
- CInt64 max;
- CInt64 work;
- Boolean flag1;
- Boolean flag2;
-
- CInt64_SetLong(&value, 0);
- flag1 = 0;
- flag2 = 0;
- if (addr->numObjRefs == 1) {
- Object *obj;
- // IRO_ASSERT(addr->objRefs->element->type == IROLinearOperand);
- // IRO_ASSERT(addr->objRefs->element->u.node->type == EOBJREF);
- obj = ((ENode *) addr->objRefs->element)->data.objref;
- IRO_ASSERT(0, obj != NULL);
- result |= EvalENodeExpr(lss, proc, addr->objRefs->element, stackPtr, map, ptf);
- flag2 = 1;
- }
-
- if (addr->numMisc != 0) {
- IROElmList *list;
- ENode *nd;
- max = cint64_max;
-
- for (list = addr->misc; list; list = list->next) {
- nd = list->element;
- while (nd && nd->type == ETYPCON)
- nd = nd->data.monadic;
-
- if (nd) {
- if (nd->type == EMUL) {
- if (nd->data.diadic.left->type == EINTCONST && nd->data.diadic.right->type == EINTCONST) {
- if (IRO_IsUnsignedType(nd->rtype))
- work = CInt64_MulU(nd->data.diadic.left->data.intval,
- nd->data.diadic.right->data.intval);
- else
- work = CInt64_Mul(nd->data.diadic.left->data.intval,
- nd->data.diadic.right->data.intval);
- IRO_TruncateValueToType(&work, ((ENode *) list->element)->rtype);
- value = CInt64_Add(value, work);
- } else if (nd->data.diadic.left->type == EINTCONST) {
- work = nd->data.diadic.left->data.intval;
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else if (nd->data.diadic.right->type == EINTCONST) {
- work = nd->data.diadic.right->data.intval;
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else {
- max = cint64_one;
- }
- } else if (nd->type == ESHL) {
- if (nd->data.diadic.left->type == EINTCONST && nd->data.diadic.right->type == EINTCONST) {
- work = CInt64_Shl(nd->data.diadic.left->data.intval,
- nd->data.diadic.right->data.intval);
- IRO_TruncateValueToType(&work, ((ENode *) list->element)->rtype);
- value = CInt64_Add(value, work);
- } else if (nd->data.diadic.right->type == EINTCONST) {
- work = CInt64_Shl(cint64_one, nd->data.diadic.right->data.intval);
- IRO_TruncateValueToType(&work, ((ENode *) list->element)->rtype);
- if (!CInt64_IsZero(&work) && CInt64_LessU(work, max))
- max = work;
- } else {
- max = cint64_one;
- }
- } else {
- LocationSet *tmp;
- PAMemoryBlock *mb;
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalENodeExpr(lss2, proc, nd, stackPtr, map, ptf);
-
- if (LocationSetSet_FindUnknown(lss2)) {
- max = cint64_one;
- } else if (
- LocationSetSet_Count(lss2) == 1 &&
- (tmp = LocationSetSet_FindFirst(lss2)) &&
- (LocationSet_stride(tmp) == 0) &&
- (mb = LocationSet_block(tmp)) &&
- (PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_INT)
- ) {
- value = CInt64_Add(value, *((CInt64 *) PAMemoryBlock_thing(mb)));
- } else if (!flag2 && (IS_TYPE_POINTER(nd->rtype) || IS_TYPE_MEMBERPOINTER(nd->rtype))) {
- if (flag1) {
- LocationSetSet_RemoveAll(lss);
- max = cint64_one;
- }
- LocationSetSet_AddSet(lss, lss2);
- flag2 = 1;
- } else if (IS_TYPE_POINTER(nd->rtype) || IS_TYPE_MEMBERPOINTER(nd->rtype)) {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- } else if (!flag1) {
- LocationSetSet_AddSet(lss, lss2);
- flag1 = 1;
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- }
- }
- }
-
- if (IS_TYPE_POINTER(Int->rtype))
- CInt64_SetLong(&work, TYPE_POINTER(Int->rtype)->target->size);
- else if (IS_TYPE_MEMBERPOINTER(Int->rtype))
- CInt64_SetLong(&work, TYPE_MEMBER_POINTER(Int->rtype)->ty1->size);
- else
- work = cint64_zero;
-
- if (CInt64_GreaterU(work, max))
- max = work;
- }
-
- if (addr->numInts != 0) {
- IROElmList *list;
- ENode *addend;
-
- for (list = addr->ints; list; list = list->next) {
- addend = list->element;
-
- if (addend) {
- IRO_ASSERT(0, addend->type == EINTCONST);
-
- value = CInt64_Add(value, addend->data.intval);
- }
- }
- }
-
- IRO_TruncateValueToType(&value, Int->rtype);
-
- if (LocationSetSet_Count(lss) == 0) {
- if (CInt64_Equal(max, cint64_max)) {
- PAMemoryBlock *mb;
- LocationSet *ls;
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, PAMEMORYBLOCKKIND_INT, &value);
-
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, mb, cint64_zero, 0, Int->rtype);
- LocationSetSet_Add(lss, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
- } else {
- if (!LocationSetSet_FindUnknown(lss) && !CInt64_IsZero(&value))
- LocationSetSet_ForEach(lss, EvalExprAction, &value);
- }
-
- if (!LocationSetSet_FindUnknown(lss) && addr->numMisc && !CInt64_Equal(max, cint64_max))
- LocationSetSet_ForEach(lss, EvalExprAction2, &max);
- }
- } else if (Int->type == EOBJREF || Int->type == EINTCONST || Int->type == ESTRINGCONST) {
- Object *obj;
- void *thing;
- PAMemoryBlockKind kind;
-
- thing = NULL;
- if (Int->type == EINTCONST) {
- kind = PAMEMORYBLOCKKIND_INT;
- thing = &Int->data.intval;
- } else if (Int->type == ESTRINGCONST) {
- kind = PAMEMORYBLOCKKIND_6;
- thing = Int;
- } else if (Int->type == EOBJREF) {
- obj = Int->data.objref;
- IRO_ASSERT(0, obj != NULL);
- if (ObjectIsAnExtendedParamCandidate(obj)) {
- kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM;
- thing = CreateExtendedParam(stackPtr, map, obj, &result);
- } else {
- kind = PAMEMORYBLOCKKIND_LOCALVAR;
- thing = PALocalVar_New();
- if (obj->name && obj->name->name && ObjectIsARealFunctionArgument(proc, obj))
- PALocalVar_InitByName(thing, obj->name->name);
- else
- PALocalVar_InitByObject(thing, obj);
- }
- }
-
- if (thing) {
- PAMemoryBlock *mb;
- LocationSet *ls;
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, kind, thing);
-
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, mb, cint64_zero, 0, Int->rtype);
- LocationSetSet_Add(lss, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- }
- } else if (Int->type == EBITFIELD) {
- LocationSet *ls;
-
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- result |= EvalENodeExpr(lss2, proc, Int->data.monadic, stackPtr, map, ptf);
-
- if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2)))
- LocationSetSet_AddUnknown(lss, NULL, NULL, ls);
- else
- CError_FATAL(2146);
-
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- } else {
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- }
-
- LocationSetSet_ForEach(lss, EvalExprAction4, originalInt->rtype);
-
- if (set && lss)
- LocationSetSet_AddSet(set, lss);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-
- return result;
-}
-
-static Boolean EvalVarAddr(LocationSetSet *set, Object *proc, VarRecord *var, Stack **stackPtr, ParamMappingFunction *map) {
- Boolean result;
- PAMemoryBlockKind kind;
- void *thing;
- Object *obj;
- PAMemoryBlock *block;
- LocationSet *loc;
-
- result = 0;
- obj = var->object;
-
- if (ObjectIsAnExtendedParamCandidate(obj)) {
- kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM;
- thing = CreateExtendedParam(stackPtr, map, obj, &result);
- } else {
- kind = PAMEMORYBLOCKKIND_LOCALVAR;
- thing = PALocalVar_New();
- if (obj->name && obj->name->name && ObjectIsAFunctionArgument(proc, obj))
- PALocalVar_InitByName(thing, obj->name->name);
- else
- PALocalVar_InitByObject(thing, obj);
- }
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, kind, thing);
-
- loc = LocationSet_New();
- LocationSet_InitKnown(loc, block, cint64_zero, 0, CDecl_NewPointerType(obj->type));
- LocationSetSet_Add(set, loc);
- LocationSet_Term(loc);
- LocationSet_Delete(loc);
-
- return result;
-}
-
-static Boolean EvalVariable(LocationSetSet *set, Object *proc, VarRecord *var, PointsToFunction *pointsToFunc, Stack **stackPtr, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- LocationSetSet *locs;
- Boolean result;
- EvalExprAction3Params params;
-
- locs = LocationSetSet_New();
- LocationSetSet_Init(locs);
- result = EvalVarAddr(locs, proc, var, stackPtr, map);
-
- memset(&params, 0, sizeof(params));
- params.set = set;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- params.pointsToFunc = pointsToFunc;
- params.indRtype = var->object->type;
- params.x1C = 0;
- LocationSetSet_ForEach(locs, EvalExprAction3, &params);
-
- result |= params.x1C;
- LocationSetSet_Term(locs);
- LocationSetSet_Delete(locs);
-
- return result;
-}
-
-static void StoreReturnedLocationsAction(LocationSet *loc, void *refcon) {
- IRO_ASSERT(2275, loc != NULL);
- IRO_ASSERT(2276, refcon != NULL);
-
- if (!LocationSet_IsUnknown(loc)) {
- if (PAMemoryBlock_kind(LocationSet_block(loc)) == PAMEMORYBLOCKKIND_HEAPBLOCK) {
- PAHeapBlock *hb;
- PAMemoryBlock *mb;
- CInt64 field;
- UInt32 stride;
- Type *rtype;
-
- hb = CreateUniqueHeapAlloc_sub_486420();
- InitUniqueHeapAlloc_sub_486410(hb, refcon);
-
- mb = PAMemoryBlock_New();
- PAMemoryBlock_Init(mb, PAMEMORYBLOCKKIND_HEAPBLOCK, hb);
-
- field = LocationSet_field(loc);
- stride = LocationSet_stride(loc);
- rtype = LocationSet_rtype(loc);
- LocationSet_Term(loc);
- LocationSet_InitKnown(loc, mb, field, stride, rtype);
- }
- }
-}
-
-static void StoreReturnedLocations(IROLinear *nd, PartialTransferFunction *ptf, ParamMappingFunction *map) {
- LocationSet *retLoc;
- LocationSetSet *retLocs;
-
- IRO_ASSERT(2307, nd != NULL);
- IRO_ASSERT(2308, nd->type == IROLinearFunccall);
- IRO_ASSERT(2309, ptf != NULL);
- IRO_ASSERT(2310, map != NULL);
-
- retLoc = PartialTransferFunction_returnLocation(ptf);
- retLocs = nd->u.funccall.returnedLocs;
- if (!retLocs) {
- LocationSetSet_Init(retLocs = nd->u.funccall.returnedLocs = LocationSetSet_New());
- } else {
- LocationSetSet_RemoveAll(retLocs);
- }
-
- Lookup(retLocs, NULL, NULL, NULL, NULL, retLoc, PartialTransferFunction_finalPointsToFn(ptf), 0, NULL);
- ExpandLocationSetSetToActuals(&stCallingContextStack, map, retLocs);
- LocationSetSet_ForEach(retLocs, StoreReturnedLocationsAction, nd);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EPParams {
- ParamMappingFunction *map;
- ExtendedParam *ep;
- Object *proc;
- Object *var;
- unsigned char x10;
- unsigned char x11;
-} EPParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void FillInAppropriateMappingsWithExtParamAction(Object *obj, void *refcon) {
- EPParams *params;
- ParamMapping *mapping;
-
- IRO_ASSERT(2352, obj != NULL);
- IRO_ASSERT(2353, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(2357, params->map != NULL);
- IRO_ASSERT(2358, params->ep != NULL);
- IRO_ASSERT(2359, params->proc == NULL || params->proc != NULL);
- IRO_ASSERT(2360, params->proc != &stUnknown);
- IRO_ASSERT(2361, params->var == NULL || params->var != NULL);
- IRO_ASSERT(2362, params->var != &stUnknown);
-
- mapping = ParamMappingFunction_FindMappingByFormal(params->map, obj);
- if (!mapping) {
- if (ObjectIsAnExtendedParamCandidate(obj) || !params->proc || ObjectIsAFunctionArgument(params->proc, obj)) {
- mapping = ParamMapping_New();
- ParamMapping_Init_PROBABLY(mapping, NULL, obj, params->ep);
- Pmf_Add_sub_486610(params->map, mapping);
- ParamMapping_Term(mapping);
- ParamMapping_Delete(mapping);
- params->x11 = 1;
- }
- } else {
- if (ParamMapping_extended(mapping) != params->ep) {
- ParamMapping_SetExtended(mapping, params->ep);
- params->x11 = 1;
- }
- }
-
- if (obj == params->var)
- params->x10 = 1;
-}
-
-static Boolean FillInAppropriateMappingsWithExtParam(ParamMappingFunction *map, Object *var, ExtendedParam *ep, Object *proc) {
- EPParams params;
- ObjectSet *objSet;
-
- IRO_ASSERT(2398, map != NULL);
- IRO_ASSERT(2399, var == NULL || var != NULL);
- IRO_ASSERT(2400, var != &stUnknown);
- IRO_ASSERT(2401, ep != NULL);
- IRO_ASSERT(2402, proc == NULL || proc != NULL);
- IRO_ASSERT(2403, proc != &stUnknown);
-
- memset(&params, 0, sizeof(params));
- params.map = map;
- params.ep = ep;
- params.proc = proc;
- params.var = var;
- params.x10 = 0;
- params.x11 = 0;
-
- if ((objSet = ExtendedParam_objectSet(ep)))
- ObjectSet_ForEach(objSet, FillInAppropriateMappingsWithExtParamAction, &params);
-
- if (var && !params.x10) {
- ExtendedParam_sub_4867B0(ep, var);
- FillInAppropriateMappingsWithExtParamAction(var, &params);
- }
-
- return params.x11;
-}
-
-static void MatchPTFHelper(LocationSet *loc, LocationSetSet *locs, Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- PointsToFunction *initial;
- PAMemoryBlock *block;
- PAMemoryBlockKind kind;
- Object *obj;
-
- IRO_ASSERT(2448, loc != NULL);
- IRO_ASSERT(2449, !LocationSet_IsUnknown(loc));
- IRO_ASSERT(2450, locs != NULL);
- IRO_ASSERT(2451, proc != NULL);
- IRO_ASSERT(2452, map != NULL);
- IRO_ASSERT(2453, ptf != NULL);
-
- initial = PartialTransferFunction_initialPointsToFn(ptf);
- IRO_ASSERT(2456, initial != NULL);
-
- IRO_ASSERT(2458, !LocationSet_IsUnknown(loc));
-
- block = LocationSet_block(loc);
- IRO_ASSERT(2460, block != NULL);
-
- kind = PAMemoryBlock_kind(block);
-
- if (kind == PAMEMORYBLOCKKIND_LOCALVAR) {
- PALocalVar *local;
-
- local = PAMemoryBlock_thing(block);
- IRO_ASSERT(2466, local != NULL);
-
- obj = GetLocalObject(local, proc, 1);
- if (obj && ObjectIsAFunctionArgument(proc, obj)) {
- if (LocationSetSet_Count(locs) == 1) {
- LocationSet *ls;
- ls = LocationSetSet_FindFirst(locs);
- if (ls && !LocationSet_IsUnknown(ls)) {
- if ((block = LocationSet_block(ls))) {
- if (PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- ExtendedParam *ep;
- if ((ep = PAMemoryBlock_thing(block))) {
- ExtendedParam_sub_4867B0(ep, obj);
- if (stExtParamSet)
- ExtParamSet_sub_487630(stExtParamSet, ep);
- FillInAppropriateMappingsWithExtParam(map, obj, ep, proc);
- }
- }
- }
- }
- }
- }
- } else if (kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- void *ep = PAMemoryBlock_thing(block);
- IRO_ASSERT(2489, ep != NULL);
-
- obj = NULL;
- ObjectSet_ForEach(ExtendedParam_objectSet(ep), FindGlobalObjectAction, &obj);
- if (obj && obj != &stUnknown)
- FillInAppropriateMappingsWithExtParam(map, obj, ep, proc);
- } else {
- CError_FATAL(2500);
- }
-
- if (!PointsToFunction_FindByLookupCompatibleLocationSet(initial, loc)) {
- PointsToEntry *pte = PointsToEntry_New();
- PointsToEntry_Init(pte, loc, locs);
- PointsToFunction_AddWithoutChecking(initial, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct MatchPTFActionParams {
- Object *proc;
- PartialTransferFunction *ptfCopy;
- ParamMappingFunction *mapCopy;
- Stack **stackPtr;
-} MatchPTFActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void MatchPTFAction1(PointsToEntry *tgtPTE, void *refcon) {
- MatchPTFActionParams *params;
- LocationSet *loc;
- LocationSetSet *locs;
- PAMemoryBlock *block;
- PAMemoryBlockKind kind;
-
- IRO_ASSERT(2525, tgtPTE != NULL);
- IRO_ASSERT(2526, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(2530, params->proc != NULL);
- IRO_ASSERT(2531, params->ptfCopy != NULL);
- IRO_ASSERT(2532, params->mapCopy != NULL);
-
- if ((loc = PointsToEntry_loc(tgtPTE)) && (locs = PointsToEntry_locs(tgtPTE))) {
- if ((block = LocationSet_block(loc))) {
- kind = PAMemoryBlock_kind(block);
- if (kind == PAMEMORYBLOCKKIND_LOCALVAR) {
- MatchPTFHelper(loc, locs, params->proc, params->mapCopy, params->ptfCopy);
- } else if (kind != PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- CError_FATAL(2547);
- }
- }
- }
-}
-
-static void MatchPTFAction2(PointsToEntry *tgtPTE, void *refcon) {
- MatchPTFActionParams *params;
- LocationSet *loc;
- LocationSetSet *locs;
- PAMemoryBlock *block;
- PAMemoryBlockKind kind;
-
- IRO_ASSERT(2561, tgtPTE != NULL);
- IRO_ASSERT(2562, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(2566, params->proc != NULL);
- IRO_ASSERT(2567, params->ptfCopy != NULL);
- IRO_ASSERT(2568, params->mapCopy != NULL);
-
- if ((loc = PointsToEntry_loc(tgtPTE)) && (locs = PointsToEntry_locs(tgtPTE))) {
- if ((block = LocationSet_block(loc))) {
- kind = PAMemoryBlock_kind(block);
- if (kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- MatchPTFHelper(loc, locs, params->proc, params->mapCopy, params->ptfCopy);
- }
- }
- }
-}
-
-static Boolean MatchPTF(PartialTransferFunction *tgtPTF, Object *proc, ParamMappingFunction *map, IROLinear *nd, PartialTransferFunction *ptf) {
- Boolean result;
- PartialTransferFunction *ptfCopy;
- ParamMappingFunction *mapCopy;
- PointsToFunction *initial;
- MatchPTFActionParams params;
-
- IRO_ASSERT(2593, tgtPTF != NULL);
- IRO_ASSERT(2594, proc != NULL);
- IRO_ASSERT(2595, map != NULL);
- IRO_ASSERT(2596, nd != NULL);
- IRO_ASSERT(2597, ptf != NULL);
-
- ptfCopy = PartialTransferFunction_New();
- PartialTransferFunction_Copy(ptfCopy, ptf);
-
- mapCopy = ParamMappingFunction_New();
- ParamMappingFunction_Copy(mapCopy, map);
-
- initial = PartialTransferFunction_initialPointsToFn(tgtPTF);
- PointsToFunction_SortByExtendedParamNum(initial);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptfCopy = ptfCopy;
- params.mapCopy = mapCopy;
- params.stackPtr = &stCallingContextStack;
-
- PointsToFunction_ForEach(initial, MatchPTFAction1, &params);
- PointsToFunction_ForEach(initial, MatchPTFAction2, &params);
-
- result = PointsToFunctions_Match(initial, PartialTransferFunction_initialPointsToFn(ptfCopy));
- if (result) {
- PartialTransferFunction_Term(ptf);
- PartialTransferFunction_Copy(ptf, ptfCopy);
-
- ParamMappingFunction_Term(map);
- ParamMappingFunction_Copy(map, mapCopy);
- }
-
- PartialTransferFunction_Term(ptfCopy);
- PartialTransferFunction_Delete(ptfCopy);
-
- ParamMappingFunction_Term(mapCopy);
- ParamMappingFunction_Delete(mapCopy);
-
- return result;
-}
-
-static void FindCallTargetsAction2(Object *obj, void *refcon) {
- ObjectSet *procList;
-
- IRO_ASSERT(2650, obj != NULL);
- IRO_ASSERT(2651, refcon != NULL);
-
- procList = refcon;
-
- if (obj == &stUnknown || ObjectIsAFunction(obj))
- ObjectSet_sub_4867D0(procList, obj);
-}
-
-static void FindCallTargetsAction(LocationSet *ls, void *refcon) {
- ObjectSet *procList;
-
- IRO_ASSERT(2669, ls != NULL);
- IRO_ASSERT(2670, refcon != NULL);
-
- procList = refcon;
-
- if (!LocationSet_IsUnknown(ls)) {
- PAMemoryBlock *mb = LocationSet_block(ls);
- if (PAMemoryBlock_kind(mb) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- ExtendedParam *ep = PAMemoryBlock_thing(mb);
- ObjectSet *objSet = ExtendedParam_objectSet(ep);
- ObjectSet_ForEach(objSet, FindCallTargetsAction2, procList);
- }
- } else {
- FindCallTargetsAction2(&stUnknown, procList);
- }
-}
-
-static int FindCallTargets(ObjectSet *procList, Object *proc, IROLinear *nd, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- LocationSetSet *set;
- int evalResult;
- int result;
-
- IRO_ASSERT(2696, procList != NULL);
- IRO_ASSERT(2697, proc != NULL);
- IRO_ASSERT(2698, nd != NULL);
- IRO_ASSERT(2699, nd->type == IROLinearFunccall);
- IRO_ASSERT(2700, map != NULL);
- IRO_ASSERT(2701, ptf != NULL);
-
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- evalResult = EvalExpr(set, proc, nd->u.funccall.linear8, &stCallingContextStack, map, ptf);
- result = evalResult | ExpandLocationSetSetToActuals(&stCallingContextStack, map, set);
- LocationSetSet_ForEach(set, FindCallTargetsAction, procList);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
-
- return result;
-}
-
-static int LookupParam(LocationSetSet *set, LocationSet *ls, Object *var, Stack **stackPtr, Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf, Boolean unkflag) {
- Boolean result;
- ExtendedParam *ep;
-
- IRO_ASSERT(2728, set == NULL || set != NULL);
- IRO_ASSERT(2729, ls != NULL);
- IRO_ASSERT(2730, var != NULL);
- IRO_ASSERT(2731, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(2732, proc != NULL);
- IRO_ASSERT(2733, map == NULL || map != NULL);
- IRO_ASSERT(2734, ptf == NULL || ptf != NULL);
-
- result = 0;
-
- ep = ExtendedParam_FindByObject(var);
- if (!ep)
- ep = CreateExtendedParam(stackPtr, map, var, &result);
-
- IRO_ASSERT(2741, ep != NULL);
-
- if (ep) {
- PAMemoryBlock *block;
- LocationSet *newLS;
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_EXTENDEDPARAM, ep);
-
- newLS = LocationSet_New();
- LocationSet_InitKnown(newLS, block, LocationSet_field(ls), LocationSet_stride(ls), LocationSet_rtype(ls));
- if (set)
- LocationSetSet_Add(set, newLS);
-
- if (unkflag) {
- if (map)
- result |= FillInAppropriateMappingsWithExtParam(map, var, ep, proc);
-
- if (ptf) {
- PointsToFunction *initial;
-
- initial = PartialTransferFunction_initialPointsToFn(ptf);
- if (initial && !PointsToFunction_FindByLookupCompatibleLocationSet(initial, ls)) {
- LocationSet_Term(newLS);
- LocationSet_InitKnown(newLS, LocationSet_block(ls), cint64_zero, 0, LocationSet_rtype(ls));
- if (!PointsToFunction_FindByLookupCompatibleLocationSet(initial, newLS)) {
- LocationSet *newLS2;
- LocationSetSet *newSet;
- PointsToEntry *newPTE;
-
- newLS2 = LocationSet_New();
- LocationSet_InitKnown(newLS2, block, cint64_zero, 0, LocationSet_rtype(ls));
-
- newSet = LocationSetSet_New();
- LocationSetSet_Init(newSet);
- LocationSetSet_Add(newSet, newLS2);
-
- newPTE = PointsToEntry_New();
- PointsToEntry_Init(newPTE, newLS, newSet);
- result |= PointsToFunction_Add(initial, newPTE);
- PointsToEntry_Term(newPTE);
- PointsToEntry_Delete(newPTE);
-
- LocationSetSet_Term(newSet);
- LocationSetSet_Delete(newSet);
-
- LocationSet_Term(newLS2);
- LocationSet_Delete(newLS2);
- }
- }
- }
- }
-
- LocationSet_Term(newLS);
- LocationSet_Delete(newLS);
- }
-
- return result;
-}
-
-static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls, Object *var, Stack **stackPtr, ParamMappingFunction *map, Boolean flag) {
- Boolean result;
- PAMemoryBlock *block;
- IROLinear *nd;
- ExtendedParam *ep;
- ParamMapping *mapping;
- Type *savedRtype;
- CInt64 savedField;
- UInt32 savedStride;
- LocationSetSet *newSet;
-
- IRO_ASSERT(2821, set == NULL || set != NULL);
- IRO_ASSERT(2822, (ls != NULL && var == NULL) || (ls == NULL && var != NULL));
- IRO_ASSERT(2823, ls == NULL || !LocationSet_IsUnknown(ls));
- IRO_ASSERT(2824, var != &stUnknown);
- IRO_ASSERT(2825, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(2826, map == NULL || map != NULL);
-
- result = 0;
- block = NULL;
- nd = 0;
- ep = NULL;
- mapping = NULL;
-
- if (ls) {
- block = LocationSet_block(ls);
- IRO_ASSERT(2838, block != NULL);
- IRO_ASSERT(2839, PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM);
-
- ep = PAMemoryBlock_thing(block);
- IRO_ASSERT(2842, ep != NULL);
-
- savedField = LocationSet_field(ls);
- savedStride = LocationSet_stride(ls);
- savedRtype = LocationSet_rtype(ls);
- }
-
- IRO_ASSERT(2848, ep == NULL || ep != NULL);
-
- if (stackPtr && *stackPtr) {
- StackElement *element = Stack_Top(stackPtr);
- if (element && !map)
- map = StackElement_map(element);
- }
-
- IRO_ASSERT(2859, map == NULL || map != NULL);
-
- if (ep) {
- IRO_ASSERT(2863, var == NULL);
- ObjectSet_ForEach(ExtendedParam_objectSet(ep), FindGlobalObjectAction, &var);
- if (!var)
- var = ObjectSet_FindFirst(ExtendedParam_objectSet(ep));
- if (!var)
- var = &stUnknown;
- }
-
- IRO_ASSERT(2870, var != NULL);
-
- if (map && var != &stUnknown) {
- if (flag)
- result |= FillInAppropriateMappingsWithExtParam(map, var, ep, NULL);
- mapping = ParamMappingFunction_FindMappingByFormal(map, var);
- }
-
- newSet = LocationSetSet_New();
- LocationSetSet_Init(newSet);
-
- IRO_ASSERT(2884, mapping == NULL || mapping != NULL);
-
- if (mapping)
- nd = ParamMapping_actual(mapping);
-
- if (!nd) {
- if (!ls) {
- IRO_ASSERT(2893, var != NULL);
- IRO_ASSERT(2894, ep == NULL);
-
- if (var != &stUnknown) {
- ep = CreateExtendedParam(stackPtr, NULL, var, &result);
- if (flag && mapping && ParamMapping_extended(mapping) != ep) {
- ParamMapping_SetExtended(mapping, ep);
- result = 1;
- }
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_EXTENDEDPARAM, ep);
- savedField = cint64_zero;
- savedStride = 0;
- savedRtype = CDecl_NewPointerType(var->type);
- } else {
- block = LocationSet_block(stUnknownLs);
- savedRtype = NULL;
- }
- } else if (var == &stUnknown || !ObjectIsAnExtendedParamCandidate(var)) {
- block = LocationSet_block(stUnknownLs);
- savedRtype = NULL;
- }
-
- IRO_ASSERT(2925, block != NULL);
-
- if (block == LocationSet_block(stUnknownLs)) {
- LocationSetSet_AddUnknown(newSet, savedRtype, NULL, NULL);
- } else {
- LocationSet *tmp = LocationSet_New();
- LocationSet_InitKnown(tmp, block, savedField, savedStride, savedRtype);
- LocationSetSet_Add(newSet, tmp);
- LocationSet_Term(tmp);
- LocationSet_Delete(tmp);
- }
- } else {
- Stack *next;
- StackElement *element;
- if (stackPtr && *stackPtr && (next = Stack_Next(stackPtr)) && (element = Stack_Top(&next))) {
- if (ls) {
- if (!savedStride && !CInt64_IsZero(&savedField)) {
- IROLinear *ic;
- IROLinear *d;
- ic = IRO_NewIntConst(savedField, TYPE(&stunsignedlong));
- d = IRO_NewLinear(IROLinearOp2Arg);
- d->index = ++IRO_NumLinear;
- d->rtype = nd->rtype;
- d->u.diadic.left = nd;
- d->u.diadic.right = ic;
- nd = d;
- }
- if (savedStride) {
- IROLinear *call;
- IROLinear *d;
- call = IRO_NewLinear(IROLinearFunccall);
- call->u.funccall.returnedLocs = LocationSetSet_New();
- LocationSetSet_Init(call->u.funccall.returnedLocs);
- LocationSetSet_AddUnknown(call->u.funccall.returnedLocs, NULL, NULL, NULL);
- d = IRO_NewLinear(IROLinearOp2Arg);
- d->index = ++IRO_NumLinear;
- d->rtype = nd->rtype;
- d->u.diadic.left = nd;
- d->u.diadic.right = call;
- nd = d;
- }
- }
- EvalExpr(newSet, StackElement_proc(element), nd, &next, StackElement_map(element), StackElement_ptf(element));
- } else {
- LocationSetSet_AddUnknown(newSet, NULL, NULL, NULL);
- }
- }
-
- if (set)
- LocationSetSet_AddSet(set, newSet);
-
- LocationSetSet_Term(newSet);
- LocationSetSet_Delete(newSet);
-
- return result;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct ExpandLocationSetSetActionParams {
- LocationSetSet *toBeRemoved;
- LocationSetSet *toBeAdded;
- Stack **stackPtr;
- ParamMappingFunction *map;
- Boolean x10;
-} ExpandLocationSetSetActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void ExpandLocationSetSetToActualsAction(LocationSet *ls, void *refcon) {
- ExpandLocationSetSetActionParams *params;
-
- IRO_ASSERT(3021, ls != NULL);
- IRO_ASSERT(3022, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(3026, params->toBeRemoved != NULL);
- IRO_ASSERT(3027, params->toBeAdded != NULL);
- IRO_ASSERT(3028, params->stackPtr == NULL || *params->stackPtr == NULL || *params->stackPtr != NULL);
- IRO_ASSERT(3029, params->map == NULL || params->map != NULL);
-
- if (!LocationSet_IsUnknown(ls)) {
- PAMemoryBlock *block = LocationSet_block(ls);
- if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- ExtendedParam *ep = PAMemoryBlock_thing(block);
- if (ep) {
- ObjectSet *objSet = ExtendedParam_objectSet(ep);
- Object *obj = NULL;
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- if (!obj) {
- LocationSetSet_Add(params->toBeRemoved, ls);
- params->x10 |= GetActualLocsOfExtendedParam(params->toBeAdded, ls, NULL, params->stackPtr, params->map, 0);
- }
- }
- }
- }
-}
-
-static int ExpandLocationSetSetToActuals(Stack **stackPtr, ParamMappingFunction *map, LocationSetSet *thingsPointedTo) {
- LocationSetSet *toBeRemoved;
- LocationSetSet *toBeAdded;
- ExpandLocationSetSetActionParams params;
- Boolean result;
-
- IRO_ASSERT(3063, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(3064, map == NULL || map != NULL);
- IRO_ASSERT(3065, thingsPointedTo != NULL);
-
- toBeRemoved = LocationSetSet_New();
- LocationSetSet_Init(toBeRemoved);
-
- toBeAdded = LocationSetSet_New();
- LocationSetSet_Init(toBeAdded);
-
- memset(&params, 0, sizeof(params));
- params.toBeRemoved = toBeRemoved;
- params.toBeAdded = toBeAdded;
- params.stackPtr = stackPtr;
- params.map = map;
- params.x10 = 0;
-
- LocationSetSet_ForEach(thingsPointedTo, ExpandLocationSetSetToActualsAction, &params);
-
- result = params.x10;
- LocationSetSet_sub_488700(thingsPointedTo, toBeRemoved);
- LocationSetSet_AddSet(thingsPointedTo, toBeAdded);
-
- LocationSetSet_Term(toBeRemoved);
- LocationSetSet_Delete(toBeRemoved);
-
- LocationSetSet_Term(toBeAdded);
- LocationSetSet_Delete(toBeAdded);
-
- return result;
-}
-
-static void EvaluatePartialAbsolute(LocationSetSet *set, LocationSetSet *thingsPointedTo, LocationSet *dst, Type *indRtype) {
- LocationSet *absLoc;
- Type *absLocRtype;
- PAMemoryBlock *block;
-
- IRO_ASSERT(3108, set != NULL);
- IRO_ASSERT(3109, thingsPointedTo != NULL);
- IRO_ASSERT(3110, dst != NULL);
- IRO_ASSERT(3111, indRtype != NULL);
-
- absLoc = LocationSetSet_FindFirst(thingsPointedTo);
- IRO_ASSERT(3114, absLoc != NULL);
-
- if (!LocationSet_IsUnknown(absLoc))
- absLocRtype = LocationSet_rtype(absLoc);
-
- if (!LocationSet_IsUnknown(absLoc) && indRtype->size == absLocRtype->size) {
- LocationSetSet_AddSet(set, thingsPointedTo);
- } else if (
- !LocationSet_IsUnknown(absLoc) &&
- !LocationSet_stride(absLoc) &&
- LocationSetSet_Count(thingsPointedTo) == 1 &&
- (block = LocationSet_block(absLoc)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_INT &&
- absLocRtype->size <= stsignedlonglong.size &&
- indRtype->size < absLocRtype->size
- ) {
- CInt64 val2;
- CInt64 val8;
- CInt64 val4;
- CInt64 val5;
- CInt64 val1;
- CInt64 val3;
- CInt64 val7;
- CInt64 val6;
- LocationSet *ls;
-
- val1 = LocationSet_field(absLoc);
- val2 = *((CInt64 *) PAMemoryBlock_thing(block));
- CInt64_SetLong(&val3, 8);
- val4 = cint64_zero;
- CInt64_SetLong(&val5, stsignedlonglong.size - absLocRtype->size);
- val6 = CInt64_Sub(LocationSet_field(dst), val1);
- CInt64_SetLong(&val7, absLocRtype->size - indRtype->size);
- val5 = CInt64_Add(val5, val6);
- val4 = CInt64_Add(val4, val7);
- val4 = CInt64_Sub(val4, val6);
- val5 = CInt64_MulU(val5, val3);
- val4 = CInt64_MulU(val4, val3);
- val8 = cint64_negone;
- val8 = CInt64_Shl(val8, val5);
- val8 = CInt64_ShrU(val8, val5);
- val2 = CInt64_And(val2, val8);
- val2 = CInt64_ShrU(val2, val4);
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_INT, &val2);
-
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, block, cint64_zero, 0, indRtype);
- LocationSetSet_Add(set, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- } else {
- LocationSetSet_AddUnknown(set, indRtype, NULL, NULL);
- }
-}
-
-static Boolean AddToInitialPointsToFunc(Boolean flag, PartialTransferFunction *ptf, LocationSet *dst, LocationSetSet *set) {
- Boolean result;
- LocationSet *ls;
- PointsToFunction *initial;
- PointsToEntry *pte;
-
- IRO_ASSERT(3192, ptf == NULL || ptf != NULL);
- IRO_ASSERT(3193, dst != NULL);
- IRO_ASSERT(3194, set != NULL);
-
- result = 0;
-
- if (flag && ptf) {
- ls = LocationSetSet_FindUnknown(set);
- if (!ls || LocationSet_rtype(ls)) {
- initial = PartialTransferFunction_initialPointsToFn(ptf);
- if (initial && !PointsToFunction_FindByLookupCompatibleLocationSet(initial, dst)) {
- IRO_ASSERT(3208, dst != NULL);
-
- pte = PointsToEntry_New();
- PointsToEntry_Init(pte, dst, set);
- result = PointsToFunction_AddWithoutChecking(initial, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- }
- }
- }
-
- return result;
-}
-
-static Boolean Lookup(LocationSetSet *set, Stack **stackPtr, Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf, LocationSet *dst, PointsToFunction *pointsToFunc, Boolean unk, Type *indRtype) {
- Boolean result;
- LocationSetSet *mySet;
- LocationSetSet *set2;
- PAMemoryBlock *block;
- ExtendedParam *ep;
- PALocalVar *local;
- ObjectSet *objSet;
- Object *obj;
-
- IRO_ASSERT(3245, set == NULL || set != NULL);
- IRO_ASSERT(3246, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(3247, proc == NULL || proc != NULL);
- IRO_ASSERT(3248, map == NULL || map != NULL);
- IRO_ASSERT(3249, ptf == NULL || ptf != NULL);
- IRO_ASSERT(3250, dst != NULL);
- IRO_ASSERT(3251, pointsToFunc == NULL || pointsToFunc != NULL);
- IRO_ASSERT(3252, indRtype == NULL || indRtype != NULL);
-
- result = 0;
-
- set2 = NULL;
-
- mySet = LocationSetSet_New();
- LocationSetSet_Init(mySet);
-
- if (proc) {
- if (LocationIsVolatile(dst, proc))
- LocationSetSet_AddUnknown(mySet, indRtype, NULL, NULL);
- }
-
- if (pointsToFunc && !LocationSet_IsUnknown(dst)) {
- PointsToEntry *pte = PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, dst);
- if (pte) {
- set2 = PointsToEntry_locs(pte);
- } else if (indRtype) {
- pte = PointsToFunction_FindContainingLocationSet(pointsToFunc, dst, indRtype);
- if (pte)
- set2 = PointsToEntry_locs(pte);
- }
- }
-
- if (set2) {
- if (indRtype)
- EvaluatePartialAbsolute(mySet, set2, dst, indRtype);
- else
- LocationSetSet_AddSet(mySet, set2);
- } else if (!set2) {
- block = NULL;
- if (!LocationSet_IsUnknown(dst))
- block = LocationSet_block(dst);
-
- if (!LocationSet_IsUnknown(dst) && LocationSet_stride(dst)) {
- LocationSetSet_AddUnknown(mySet, indRtype, NULL, NULL);
- } else if (
- block &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM &&
- (ep = PAMemoryBlock_thing(block)) &&
- (objSet = ExtendedParam_objectSet(ep))
- ) {
- obj = NULL;
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- if (!obj) {
- LocationSetSet *lss3;
- LocationSet *tmp;
- // Boolean result1;
- EvalExprAction3Params params;
-
- lss3 = LocationSetSet_New();
- LocationSetSet_Init(lss3);
- result = GetActualLocsOfExtendedParam(lss3, dst, NULL, stackPtr, map, unk);
-
- memset(&params, 0, sizeof(params));
- params.set = mySet;
- params.stackPtr = stackPtr;
- params.proc = proc;
- params.map = map;
- params.ptf = ptf;
- params.pointsToFunc = pointsToFunc;
- params.indRtype = indRtype;
- params.x1C = 0;
- LocationSetSet_ForEach(lss3, EvalExprAction3, &params);
- result |= params.x1C;
-
- LocationSetSet_Term(lss3);
- LocationSetSet_Delete(lss3);
-
- if ((tmp = LocationSetSet_FindUnknown(mySet))) {
- if (!LocationSet_restriction(tmp) && ObjectSet_Count(objSet) == 1) {
- if ((obj = ObjectSet_FindFirst(objSet))) {
- if (ObjectIsRestrictQualified(obj)) {
- LocationSet_Term(tmp);
- LocationSet_InitUnknown(tmp, indRtype, block, NULL);
- }
- }
- }
- }
-
- result |= AddToInitialPointsToFunc(unk, ptf, dst, mySet);
- } else {
- // Boolean result1;
- Stack *next;
- StackElement *element;
-
- result = GetActualLocsOfExtendedParam(NULL, dst, NULL, stackPtr, map, unk);
- if (stackPtr && *stackPtr && (next = Stack_Next(stackPtr)) && (element = Stack_Top(&next))) {
- result |= Lookup(mySet, &next, StackElement_proc(element), StackElement_map(element),
- StackElement_ptf(element), dst, StackElement_funcCall(element)->pointsToFunction, unk, indRtype);
- } else {
- LocationSetSet_AddUnknown(mySet, indRtype, NULL, NULL);
- }
-
- result |= AddToInitialPointsToFunc(unk, ptf, dst, mySet);
- }
- } else if (
- block &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_LOCALVAR &&
- (local = PAMemoryBlock_thing(block)) &&
- proc &&
- (obj = GetLocalObject(local, proc, 1)) &&
- ObjectIsAFunctionArgument(proc, obj)
- ) {
- result = LookupParam(mySet, dst, obj, stackPtr, proc, map, ptf, unk);
- } else {
- LocationSetSet_AddUnknown(mySet, indRtype, NULL, NULL);
- }
- }
-
- if (set)
- LocationSetSet_AddSet(set, mySet);
-
- LocationSetSet_Term(mySet);
- LocationSetSet_Delete(mySet);
-
- return result;
-}
-
-static Boolean InputsHaveNewPointerValues(PartialTransferFunction *tgtPTF, PartialTransferFunction *ptf) {
- IRO_ASSERT(3393, tgtPTF != NULL);
- IRO_ASSERT(3394, ptf != NULL);
-
- return 0;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct CreateEPActionParams {
- ParamMapping *last;
- ParamMapping *lowest;
-} CreateEPActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void CreateExtendedParamAction(ParamMapping *mapping, void *refcon) {
- CreateEPActionParams *params;
- ExtendedParam *ep;
- uint32 value;
- ExtendedParam *lowestEP;
- uint32 lowestValue;
- ExtendedParam *lastEP;
- uint32 lastValue;
-
- IRO_ASSERT(3417, mapping != NULL);
- IRO_ASSERT(3418, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(3422, params->last == NULL || params->last != NULL);
- IRO_ASSERT(3423, params->lowest == NULL || params->lowest != NULL);
-
- if ((ep = ParamMapping_extended(mapping))) {
- value = ExtendedParam_sub_489110(ep);
-
- if (params->lowest) {
- lowestEP = ParamMapping_extended(params->lowest);
- lowestValue = ExtendedParam_sub_489110(lowestEP);
- if (params->last) {
- lastEP = ParamMapping_extended(params->last);
- lastValue = ExtendedParam_sub_489110(lastEP);
- if (value > lastValue && value < lowestValue)
- params->lowest = mapping;
- } else if (value < lowestValue) {
- params->lowest = mapping;
- }
- } else if (params->last) {
- lastEP = ParamMapping_extended(params->last);
- lastValue = ExtendedParam_sub_489110(lastEP);
- if (value > lastValue)
- params->lowest = mapping;
- } else {
- params->lowest = mapping;
- }
- }
-}
-
-static ExtendedParam *FindMatchingExtendedParam(Stack **stackPtr, ParamMappingFunction *map, LocationSetSet *lss, ParamMapping *lowest, Boolean *result) {
- ExtendedParam *ep;
- ExtendedParam *lowestEP;
-
- IRO_ASSERT(3473, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(3474, map == NULL || map != NULL);
- IRO_ASSERT(3475, lss != NULL);
- IRO_ASSERT(3476, lowest != NULL);
-
- ep = NULL;
- if ((lowestEP = ParamMapping_extended(lowest))) {
- PAMemoryBlock *block;
- LocationSet *lowestLS;
- LocationSetSet *lowestLSS;
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_EXTENDEDPARAM, lowestEP);
-
- lowestLS = LocationSet_New();
- LocationSet_InitKnown(lowestLS, block, cint64_zero, 0, TYPE(&void_ptr));
-
- lowestLSS = LocationSetSet_New();
- LocationSetSet_Init(lowestLSS);
-
- *result |= GetActualLocsOfExtendedParam(lowestLSS, lowestLS, NULL, stackPtr, map, 0);
- if (LocationSetSets_Equal(lowestLSS, lss))
- ep = lowestEP;
-
- LocationSetSet_Term(lowestLSS);
- LocationSetSet_Delete(lowestLSS);
-
- LocationSet_Term(lowestLS);
- LocationSet_Delete(lowestLS);
- }
-
- return ep;
-}
-
-static ExtendedParam *CreateExtendedParam(Stack **stackPtr, ParamMappingFunction *map, Object *var, Boolean *result) {
- ExtendedParam *ep;
- ParamMapping *mapping;
- LocationSetSet *lss;
- CreateEPActionParams params;
-
- IRO_ASSERT(3518, map == NULL || map != NULL);
- IRO_ASSERT(3519, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL);
- IRO_ASSERT(3520, var != NULL);
-
- mapping = NULL;
- if (map)
- mapping = ParamMappingFunction_FindMappingByFormal(map, var);
-
- ep = ExtendedParam_FindByObject(var);
- if (ep) {
- if (mapping)
- IRO_ASSERT(3535, ep == ParamMapping_extended(mapping) || ParamMapping_extended(mapping) == NULL);
- } else if (map && !ObjectIsRestrictQualified(var)) {
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- *result |= GetActualLocsOfExtendedParam(lss, NULL, var, stackPtr, map, 0);
-
- memset(&params, 0, sizeof(params));
- params.last = NULL;
- do {
- params.lowest = NULL;
- pmf_sub_487C70(map, CreateExtendedParamAction, &params);
- if (params.lowest && params.lowest != mapping)
- ep = FindMatchingExtendedParam(stackPtr, map, lss, params.lowest, result);
- params.last = params.lowest;
- } while (params.lowest && !ep);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
-
- if (!ep)
- ep = ExtendedParam_FindByObject(var);
-
- if (!ep) {
- ep = ExtendedParam_New();
- ExtendedParam_Init(ep, var);
- } else {
- ExtendedParam_sub_4867B0(ep, var);
- }
-
- if (stExtParamSet)
- ExtParamSet_sub_487630(stExtParamSet, ep);
-
- IRO_ASSERT(3583, ep != NULL);
-
- return ep;
-}
-
-#ifdef IRO_DEBUG
-void __assertion_failed(char *expr, char *filename, int line) {
- CError_ASSERT(3605, filename);
- CError_Internal(filename, line);
-}
-#endif
-
-static void RecordActuals(IROLinear *nd, Object *proc, ParamMappingFunction *map) {
- IRO_ASSERT(3628, nd != NULL);
- IRO_ASSERT(3629, nd->type == IROLinearFunccall);
- IRO_ASSERT(3630, proc != NULL);
- IRO_ASSERT(3631, map != NULL);
-
- if (proc != &stUnknown) {
- int i;
- ObjectList *args;
- Object *arg;
-
- args = FunctionArguments(proc);
- if (args)
- arg = args->object;
- else
- arg = &stUnknown;
-
- for (i = 0; i < nd->u.funccall.argCount; i++) {
- IRO_ASSERT(3643, arg != NULL);
-
- if (arg != &stUnknown) {
- ParamMapping *mapping = ParamMapping_New();
- ParamMapping_Init_PROBABLY(mapping, nd->u.funccall.args[i], arg, NULL);
- Pmf_Add_sub_486610(map, mapping);
- ParamMapping_Term(mapping);
- ParamMapping_Delete(mapping);
- }
-
- if (args) {
- args = args->next;
- if (args)
- arg = args->object;
- else
- arg = &stUnknown;
- }
- }
- }
-}
-
-static Boolean IsAddressableLocation(LocationSet *loc, Object *proc, IRONode *fnode, IROLinear *nd) {
- IRO_ASSERT(3676, loc != NULL);
- IRO_ASSERT(3677, fnode != NULL);
- IRO_ASSERT(3678, nd != NULL);
-
- if (!LocationSet_IsUnknown(loc)) {
- PAMemoryBlock *block;
- PALocalVar *local;
- Object *obj;
- ExtendedParam *ep;
- ObjectSet *objSet;
-
- block = LocationSet_block(loc);
- if (
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_LOCALVAR &&
- (local = PAMemoryBlock_thing(block)) &&
- (obj = GetLocalObject(local, proc, 0)) &&
- fnode->addressed &&
- !ObjectSet_sub_485020(fnode->addressed, obj)
- ) {
- return 0;
- }
-
- if (
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM &&
- (ep = PAMemoryBlock_thing(block)) &&
- (objSet = ExtendedParam_objectSet(ep)) &&
- ObjectSet_Count(objSet) == 1 &&
- (obj = ObjectSet_FindFirst(objSet)) &&
- ObjectIsAFunctionArgument(proc, obj) &&
- ObjectIsRestrictQualified(obj)
- ) {
- return 0;
- }
- }
-
- return 1;
-}
-
-static Boolean LocationSetsAlias(LocationSet *ls1, LocationSet *ls2) {
- IRO_ASSERT(3719, ls1 != NULL);
- IRO_ASSERT(3720, ls2 != NULL);
-
- return
- (ls1 == ls2) ||
- LocationSet_IsUnknown(ls1) ||
- LocationSet_IsUnknown(ls2) ||
- (
- (LocationSet_stride(ls1) ||
- LocationSet_stride(ls2) ||
- CInt64_Equal(LocationSet_field(ls1), LocationSet_field(ls2))) &&
- MemoryBlocks_Equal(LocationSet_block(ls1), LocationSet_block(ls2))
- );
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct FindAliasingParams {
- LocationSetSet *x0;
- LocationSet *x4;
- Boolean x8;
-} FindAliasingParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void FindAliasingAction2(LocationSet *ls, void *refcon) {
- FindAliasingParams *params;
-
- params = refcon;
-
- if (!params->x8) {
- if (LocationSetsAlias(params->x4, ls))
- params->x8 = 1;
- }
-}
-
-static void FindAliasingAction(LocationSet *ls, void *refcon) {
- FindAliasingParams *params;
-
- IRO_ASSERT(3751, ls != NULL);
- IRO_ASSERT(3752, refcon != NULL);
-
- params = refcon;
-
- if (!params->x8) {
- params->x4 = ls;
- LocationSetSet_ForEach(params->x0, FindAliasingAction2, params);
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct KillLocationParams {
- Object *proc;
- IRONode *fnode;
- IROLinear *nd;
- PartialTransferFunction *ptf;
- PointsToFunction *toBeKilled;
- LocationSet *dst;
- Boolean x18;
-} KillLocationParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void KillAllAddressableLocationsAction(PointsToEntry *pte, void *refcon) {
- KillLocationParams *params;
- LocationSet *loc;
-
- IRO_ASSERT(3779, pte != NULL);
- IRO_ASSERT(3780, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(3784, params->proc != NULL);
- IRO_ASSERT(3785, params->fnode != NULL);
- IRO_ASSERT(3786, params->nd != NULL);
- IRO_ASSERT(3787, params->ptf != NULL);
- IRO_ASSERT(3788, params->toBeKilled != NULL);
- IRO_ASSERT(3789, params->dst == NULL);
-
- loc = PointsToEntry_loc(pte);
- IRO_ASSERT(3793, loc != NULL);
- IRO_ASSERT(3794, !LocationSet_IsUnknown(loc));
-
- if (IsAddressableLocation(loc, params->proc, params->fnode, params->nd))
- PointsToFunction_Add(params->toBeKilled, pte);
-}
-
-static void KillAllAliasingExtParamLocsAction(PointsToEntry *pte, void *refcon) {
- KillLocationParams *params;
- LocationSet *loc;
-
- IRO_ASSERT(3813, pte != NULL);
- IRO_ASSERT(3814, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(3818, params->proc != NULL);
- IRO_ASSERT(3819, params->fnode != NULL);
- IRO_ASSERT(3820, params->nd != NULL);
- IRO_ASSERT(3821, params->ptf != NULL);
- IRO_ASSERT(3822, params->toBeKilled != NULL);
- IRO_ASSERT(3823, params->dst != NULL);
- IRO_ASSERT(3824, LocationSet_block(params->dst) != NULL);
- IRO_ASSERT(3825, PAMemoryBlock_kind(LocationSet_block(params->dst)) == PAMEMORYBLOCKKIND_EXTENDEDPARAM);
-
- loc = PointsToEntry_loc(pte);
- IRO_ASSERT(3829, loc != NULL);
- IRO_ASSERT(3830, !LocationSet_IsUnknown(loc));
-
- if (loc != params->dst) {
- if (LocationSetsAlias(loc, params->dst)) {
- PointsToFunction_Add(params->toBeKilled, pte);
- } else {
- ExtendedParam *ep;
- ObjectSet *objSet;
- Object *obj;
- PAMemoryBlock *block;
-
- if (
- (ep = PAMemoryBlock_thing(LocationSet_block(params->dst))) &&
- (objSet = ExtendedParam_objectSet(ep)) &&
- (ObjectSet_Count(objSet) != 1 || !(obj = ObjectSet_FindFirst(objSet)) || !ObjectIsRestrictQualified(obj)) &&
- (block = LocationSet_block(loc)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM &&
- (ep = PAMemoryBlock_thing(block)) &&
- (objSet = ExtendedParam_objectSet(ep)) &&
- (ObjectSet_Count(objSet) != 1 || !(obj = ObjectSet_FindFirst(objSet)) || !ObjectIsRestrictQualified(obj))
- ) {
- LocationSetSet *lss1;
- LocationSetSet *lss2;
- Boolean changed;
- FindAliasingParams aparams;
-
- lss1 = LocationSetSet_New();
- LocationSetSet_Init(lss1);
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
-
- changed = GetActualLocsOfExtendedParam(lss1, loc, NULL, &stCallingContextStack, NULL, 0);
- changed |= GetActualLocsOfExtendedParam(lss2, params->dst, NULL, &stCallingContextStack, NULL, 0);
-
- memset(&aparams, 0, sizeof(aparams));
- aparams.x8 = 0;
- aparams.x0 = lss2;
- LocationSetSet_ForEach(lss1, FindAliasingAction, &aparams);
- if (aparams.x8)
- PointsToFunction_Add(params->toBeKilled, pte);
-
- LocationSetSet_Term(lss1);
- LocationSetSet_Delete(lss1);
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
- }
- }
- }
-}
-
-static void KillLocationsAction(PointsToEntry *pte, void *refcon) {
- KillLocationParams *params;
- LocationSet *loc;
- LocationSetSet *lss;
-
- IRO_ASSERT(3886, pte != NULL);
- IRO_ASSERT(3887, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(3891, params->proc != NULL);
- IRO_ASSERT(3892, params->fnode != NULL);
- IRO_ASSERT(3893, params->nd != NULL);
- IRO_ASSERT(3894, params->ptf != NULL);
- IRO_ASSERT(3895, params->toBeKilled != NULL);
- IRO_ASSERT(3896, params->dst == NULL);
-
- loc = PointsToEntry_loc(pte);
- IRO_ASSERT(3900, loc != NULL);
- IRO_ASSERT(3901, !LocationSet_IsUnknown(loc));
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
-
- params->x18 |= Assign(params->ptf, loc, lss, params->proc, params->nd, params->fnode);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-}
-
-static Boolean KillAllAddressableLocations(Object *proc, IRONode *fnode, IROLinear *nd, PartialTransferFunction *ptf) {
- Boolean result;
- PointsToFunction *pointsToFunc;
- PointsToFunction *pointsToFuncCopy;
- PointsToFunction *toBeKilled;
- KillLocationParams params;
-
- IRO_ASSERT(3921, proc != NULL);
- IRO_ASSERT(3922, fnode == NULL || fnode != NULL);
- IRO_ASSERT(3923, nd == NULL || nd != NULL);
- IRO_ASSERT(3924, ptf != NULL);
-
- if (nd && nd->pointsToFunction)
- pointsToFunc = nd->pointsToFunction;
- else
- pointsToFunc = PartialTransferFunction_finalPointsToFn(ptf);
-
- pointsToFuncCopy = PointsToFunction_New();
- PointsToFunction_Copy(pointsToFuncCopy, pointsToFunc);
-
- toBeKilled = PointsToFunction_New();
- PointsToFunction_Init(toBeKilled);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.fnode = fnode;
- params.nd = nd;
- params.ptf = ptf;
- params.toBeKilled = toBeKilled;
- params.dst = NULL;
- params.x18 = 0;
-
- if (pointsToFunc) {
- PointsToFunction_ForEach(pointsToFunc, KillAllAddressableLocationsAction, &params);
- PointsToFunction_ForEach(params.toBeKilled, KillLocationsAction, &params);
- }
-
- PointsToFunction_Term(toBeKilled);
- PointsToFunction_Delete(toBeKilled);
-
- if (params.x18)
- result = !PointsToFunctions_Equal(pointsToFuncCopy, pointsToFunc);
- else
- result = 0;
-
- PointsToFunction_Term(pointsToFuncCopy);
- PointsToFunction_Delete(pointsToFuncCopy);
-
- return result;
-}
-
-static void KillAllAliasingExtParamLocs(Object *proc, IRONode *fnode, IROLinear *nd, PartialTransferFunction *ptf, LocationSet *dst) {
- PointsToFunction *pointsToFunc;
- PointsToFunction *toBeKilled;
- KillLocationParams params;
-
- IRO_ASSERT(3974, proc != NULL);
- IRO_ASSERT(3975, fnode == NULL || fnode != NULL);
- IRO_ASSERT(3976, nd == NULL || nd != NULL);
- IRO_ASSERT(3977, ptf != NULL);
- IRO_ASSERT(3978, dst != NULL);
-
- if (!LocationSet_IsUnknown(dst) && LocationSet_block(dst)) {
- if (PAMemoryBlock_kind(LocationSet_block(dst)) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
-
- if (nd && nd->pointsToFunction)
- pointsToFunc = nd->pointsToFunction;
- else
- pointsToFunc = PartialTransferFunction_finalPointsToFn(ptf);
-
- toBeKilled = PointsToFunction_New();
- PointsToFunction_Init(toBeKilled);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.fnode = fnode;
- params.nd = nd;
- params.ptf = ptf;
- params.toBeKilled = toBeKilled;
- params.dst = dst;
- params.x18 = 0;
-
- if (pointsToFunc) {
- PointsToFunction_ForEach(pointsToFunc, KillAllAliasingExtParamLocsAction, &params);
- PointsToFunction_ForEach(params.toBeKilled, KillLocationsAction, &params);
- }
-
- PointsToFunction_Term(toBeKilled);
- PointsToFunction_Delete(toBeKilled);
- }
- }
-}
-
-static Boolean Assign(PartialTransferFunction *ptf, LocationSet *dst, LocationSetSet *srcs, Object *proc, IROLinear *nd, IRONode *fnode) {
- PointsToFunction *pointsToFunc;
- Boolean result;
- PointsToEntry *pte;
- LocationSet *loc;
- LocationSetSet *locs;
- LocationSet *bitfieldOf;
- LocationSetSet *lss;
-
- IRO_ASSERT(4027, ptf != NULL);
- IRO_ASSERT(4028, dst != NULL);
- IRO_ASSERT(4029, srcs != NULL);
- IRO_ASSERT(4030, proc != NULL);
- IRO_ASSERT(4031, nd == NULL || nd != NULL);
- IRO_ASSERT(4032, fnode == NULL || fnode != NULL);
-
- if (nd) {
- if (!nd->pointsToFunction) {
- nd->pointsToFunction = PointsToFunction_New();
- PointsToFunction_Init(nd->pointsToFunction);
- }
- pointsToFunc = nd->pointsToFunction;
- } else {
- pointsToFunc = PartialTransferFunction_finalPointsToFn(ptf);
- }
-
- pte = PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, dst);
- if (pte) {
- loc = PointsToEntry_loc(pte);
- locs = PointsToEntry_locs(pte);
- IRO_ASSERT(4056, !LocationSet_IsUnknown(dst));
- IRO_ASSERT(4057, LocationSet_stride(dst) == 0 || LocationSet_stride(loc) != 0);
-
- result = !LocationSetSets_Equal(srcs, locs) || LocationSet_stride(dst) != LocationSet_stride(loc);
-
- if (result) {
- pte = PointsToEntry_New();
- PointsToEntry_Init(pte, dst, srcs);
- PointsToFunction_RemoveByLocationSet(pointsToFunc, loc);
- PointsToFunction_AddWithoutChecking(pointsToFunc, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- }
- } else if (!LocationSet_IsUnknown(dst)) {
- KillAllAliasingExtParamLocs(proc, fnode, nd, ptf, dst);
-
- pte = PointsToEntry_New();
- PointsToEntry_Init(pte, dst, srcs);
- result = PointsToFunction_AddWithoutChecking(pointsToFunc, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- } else if ((bitfieldOf = LocationSet_bitfieldOf(dst))) {
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- LocationSetSet_AddUnknown(lss, NULL, NULL, NULL);
- result = Assign(ptf, bitfieldOf, lss, proc, nd, fnode);
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- } else if (!LocationSet_restriction(dst)) {
- result = KillAllAddressableLocations(proc, fnode, nd, ptf);
- }
-
- return result;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalMeetActionParams {
- Object *proc;
- IRONode *fnode;
- IRONode *pred;
- IROLinear *nd;
- PartialTransferFunction *ptf;
- Boolean x14;
- Boolean x15;
-} EvalMeetActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalMeetAction(PointsToEntry *pte, void *refcon) {
- EvalMeetActionParams *params;
- LocationSet *loc;
- LocationSetSet *set;
- UInt16 i;
-
- IRO_ASSERT(4123, pte != NULL);
- IRO_ASSERT(4124, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(4128, params->proc != NULL);
- IRO_ASSERT(4129, params->fnode != NULL);
- IRO_ASSERT(4130, params->pred != NULL);
- IRO_ASSERT(4131, params->nd != NULL);
- IRO_ASSERT(4132, params->ptf != NULL);
-
- loc = PointsToEntry_loc(pte);
-
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- LocationSetSet_AddSet(set, PointsToEntry_locs(pte));
-
- for (i = 0; i < params->fnode->numpred; i++) {
- IRONode *pred = FunctionNodeTable(params->proc)[params->fnode->pred[i]];
- if (pred->x3C && pred != params->pred) {
- params->x14 |= Lookup(set, &stCallingContextStack, params->proc, NULL, params->ptf, loc, pred->last->pointsToFunction, 0, NULL);
- }
- }
-
- params->x15 |= Assign(params->ptf, loc, set, params->proc, params->nd, params->fnode);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
-}
-
-static Boolean EvalMeet(Object *proc, IRONode *fnode, IROLinear *nd, PartialTransferFunction *ptf) {
- PointsToFunction *pointsToFunc;
- EvalMeetActionParams params;
- int i;
-
- IRO_ASSERT(4163, proc != NULL);
- IRO_ASSERT(4164, fnode != NULL);
- IRO_ASSERT(4165, nd != NULL);
- IRO_ASSERT(4166, ptf != NULL);
-
- pointsToFunc = PointsToFunction_New();
- if (nd->pointsToFunction)
- PointsToFunction_Copy(pointsToFunc, nd->pointsToFunction);
- else
- PointsToFunction_Init(pointsToFunc);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.fnode = fnode;
- params.nd = nd;
- params.ptf = ptf;
- params.x14 = 0;
- params.x15 = 0;
-
- for (i = 0; i < fnode->numpred; i++) {
- IRONode *pred = FunctionNodeTable(proc)[fnode->pred[i]];
- params.pred = pred;
- if (pred->x3C && pred->last->pointsToFunction) {
- PointsToFunction_ForEach(pred->last->pointsToFunction, EvalMeetAction, &params);
- }
- }
-
- if (!params.x14 && params.x15) {
- if (nd->pointsToFunction)
- params.x14 = !PointsToFunctions_Equal(pointsToFunc, nd->pointsToFunction);
- else
- params.x14 = PointsToFunction_FindFirst(pointsToFunc) != NULL;
- }
-
- PointsToFunction_Term(pointsToFunc);
- PointsToFunction_Delete(pointsToFunc);
-
- return params.x14;
-}
-
-static PartialTransferFunction *AllocatePTF(Object *proc, IROLinear *nd, PartialTransferFunction *ptf) {
- PartialTransferFunction *newPTF;
-
- IRO_ASSERT(4210, proc != NULL);
- IRO_ASSERT(4211, proc->u.func.ptfList != NULL);
- IRO_ASSERT(4212, nd == NULL || nd != NULL);
- IRO_ASSERT(4213, ptf == NULL || ptf != NULL);
-
- newPTF = PartialTransferFunction_New();
- PartialTransferFunction_Init(newPTF, nd, ptf);
- PTFList_sub_48A050(proc->u.func.ptfList, newPTF);
- return newPTF;
-}
-
-static Object *FindMainEntryPoint(Object *function) {
- IRO_ASSERT(4229, function != NULL);
-
- return function;
-}
-
-static ObjectList *FunctionArguments(Object *proc) {
- Object *search;
- ObjectList *scan;
- ObjectList *list;
- ObjectList *prev;
- ExtendedParam *ep;
- char *name;
- VarInfo *vi;
- Object *obj;
- FuncArg *args;
- Boolean notFound;
-
- IRO_ASSERT(4252, proc != NULL);
-
- if (proc == stCurrentProc) {
- for (list = arguments; list; list = list->next) {
- if ((obj = list->object) && obj->name && (name = obj->name->name) && name[0]) {
- prev = NULL;
- for (scan = proc->u.func.argList; scan; scan = scan->next) {
- prev = scan;
- if ((search = scan->object) && search->name && search->name->name) {
- if (!strcmp(name, search->name->name))
- break;
- }
- }
-
- if (!scan)
- search = NULL;
-
- notFound = !search;
-
- if (!search) {
- search = IRO_malloc(sizeof(Object));
- ep = NULL;
- search->u.var.info = IRO_malloc(sizeof(VarInfo));
- memset(search->u.var.info, 0, sizeof(VarInfo));
- search->u.var.info->func = proc;
- } else {
- ep = search->extParam;
- }
-
- vi = search->u.var.info;
- memcpy(search, obj, sizeof(Object));
- search->extParam = ep;
- search->u.var.info = vi;
- search->u.var.realObj = obj;
-
- if (notFound) {
- scan = IRO_malloc(sizeof(ObjectList));
- scan->next = NULL;
- scan->object = search;
- if (!prev)
- proc->u.func.argList = scan;
- else
- prev->next = scan;
- }
- }
- }
- } else if (proc->type) {
- for (args = TYPE_FUNC(proc->type)->args; args; args = args->next) {
- if (args->name && (name = args->name->name) && name[0]) {
- prev = NULL;
- for (scan = proc->u.func.argList; scan; scan = scan->next) {
- prev = scan;
- if ((search = scan->object) && search->name && search->name->name) {
- if (!strcmp(name, search->name->name))
- break;
- }
- }
-
- if (!scan)
- search = NULL;
-
- if (!search) {
- search = IRO_malloc(sizeof(Object));
- memset(search, 0, sizeof(Object));
- search->datatype = DLOCAL;
- search->extParam = NULL;
- search->name = GetHashNameNodeExport(name);
- search->type = args->type;
- search->qual = args->qual;
- search->u.var.info = IRO_malloc(sizeof(VarInfo));
- memset(search->u.var.info, 0, sizeof(VarInfo));
- search->u.var.info->func = proc;
-
- scan = IRO_malloc(sizeof(ObjectList));
- scan->next = NULL;
- scan->object = search;
- if (!prev)
- proc->u.func.argList = scan;
- else
- prev->next = scan;
- }
- }
- }
- }
-
- return proc->u.func.argList;
-}
-
-static IRONode **FunctionNodeTable(Object *proc) {
- IRO_ASSERT(4383, proc != NULL);
-
- IRO_ASSERT(4391, proc == stCurrentProc);
-
- return IRO_NodeTable;
-}
-
-static IRONode *FunctionFirstNode(Object *proc) {
- IRO_ASSERT(4401, proc != NULL);
-
- IRO_ASSERT(4409, proc == stCurrentProc);
-
- return IRO_FirstNode;
-}
-
-static void UpdatePTFDomain() {
- // no idea what this would've done
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalCallActionParams {
- Object *proc;
- IRONode *fnode;
- IROLinear *nd;
- PartialTransferFunction *ptf;
- ParamMappingFunction *map;
- int x14;
- Boolean x18;
- Boolean x19;
- Boolean x1A;
-} EvalCallActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalCallAction(Object *proc, void *refcon) {
- EvalCallActionParams *params;
- ParamMappingFunction *pmf;
- PartialTransferFunction *tgtPTF;
- Boolean flag;
- Boolean flag2;
-
- IRO_ASSERT(4458, proc != NULL);
- IRO_ASSERT(4459, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(4463, params->proc != NULL);
- IRO_ASSERT(4464, params->fnode != NULL);
- IRO_ASSERT(4465, params->nd != NULL);
- IRO_ASSERT(4466, params->ptf != NULL);
- IRO_ASSERT(4467, params->map == NULL || params->map != NULL);
-
- if (!params->x18) {
- pmf = ParamMappingFunction_New();
- ParamMappingFunction_Init(pmf);
- RecordActuals(params->nd, proc, pmf);
-
- flag = 0;
- if (!Stack_sub_48A710(&stCallingContextStack, proc)) {
- StackElement *element;
-
- flag2 = 0;
- tgtPTF = GetPTF(pmf, proc, params->nd, params->ptf, &flag2);
-
- element = StackElement_New();
- StackElement_Init(element, proc, tgtPTF, pmf, params->nd);
- Stack_sub_48A660(&stCallingContextStack, element);
- StackElement_Term(element);
- StackElement_Delete(element);
-
- IRO_ASSERT(4490, tgtPTF != NULL);
-
- flag = 1;
-
- if (stPTFList)
- PTFList_sub_48A050(stPTFList, tgtPTF);
- PartialTransferFunction_sub_48A610(tgtPTF, 0);
-
- if (flag2 || params->x1A) {
- if (params->x1A) {
- params->x1A = 0;
- EvalProc(proc, pmf, tgtPTF);
- } else {
- tgtPTF = stUnknownPTF;
- }
- }
- } else {
- tgtPTF = stUnknownPTF;
- }
-
- if (params->map)
- params->x19 |= ApplySummary(tgtPTF, pmf, params->proc, params->fnode, params->nd, params->ptf, params->map, params->x14 == 1);
-
- if (flag) {
- StackElement *element = Stack_sub_48A5B0(&stCallingContextStack);
- StackElement_Term(element);
- StackElement_Delete(element);
- }
-
- ParamMappingFunction_Term(pmf);
- ParamMappingFunction_Delete(pmf);
- }
-}
-
-static Boolean EvalCall(Object *proc, IRONode *fnode, IROLinear *nd, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- EvalCallActionParams params;
- ObjectSet *objSet;
-
- IRO_ASSERT(4548, proc != NULL);
- IRO_ASSERT(4549, fnode != NULL);
- IRO_ASSERT(4550, nd != NULL);
- IRO_ASSERT(4551, map != NULL);
- IRO_ASSERT(4552, ptf != NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.fnode = fnode;
- params.nd = nd;
- params.ptf = ptf;
- params.map = map;
- params.x18 = 0;
- params.x19 = 0;
- params.x1A = 0;
-
- objSet = ObjectSet_New();
- ObjectSet_Init(objSet);
-
- params.x19 |= FindCallTargets(objSet, proc, nd, map, ptf);
- params.x14 = ObjectSet_Count(objSet);
- ObjectSet_ForEach(objSet, EvalCallAction, &params);
-
- ObjectSet_Term(objSet);
- ObjectSet_Delete(objSet);
-
- return params.x19;
-}
-
-static void AdjustTypesForVolatilityAction(LocationSet *ls, void *refcon) {
- Type *type;
- Type *newtype;
- UInt32 qual;
-
- type = LocationSet_rtype(ls);
- switch (type->type) {
- case TYPEARRAY:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEPOINTER:
- qual = TYPE_POINTER(type)->qual;
- break;
- case TYPEMEMBERPOINTER:
- qual = TYPE_MEMBER_POINTER(type)->qual;
- break;
- default:
- CError_FATAL(4604);
- }
-
- if (!(qual & Q_VOLATILE)) {
- switch (type->type) {
- case TYPEARRAY:
- newtype = CDecl_NewArrayType(TYPE_POINTER(type)->target, type->size);
- TYPE_POINTER(newtype)->qual |= Q_VOLATILE;
- break;
- case TYPEPOINTER:
- newtype = CDecl_NewPointerType(TYPE_POINTER(type)->target);
- TYPE_POINTER(newtype)->qual |= Q_VOLATILE;
- break;
- case TYPEMEMBERPOINTER:
- newtype = galloc(sizeof(TypeMemberPointer));
- memcpy(newtype, type, sizeof(TypeMemberPointer));
- TYPE_MEMBER_POINTER(newtype)->qual |= Q_VOLATILE;
- break;
- }
-
- LocationSet_SetRtype(ls, newtype);
- }
-}
-
-static void AdjustTypesForVolatility(LocationSetSet *set, Object *proc, IROLinear *nd) {
- if (nd->rtype && CParser_IsVolatile(nd->rtype, nd->nodeflags & ENODE_FLAG_QUALS))
- LocationSetSet_ForEach(set, AdjustTypesForVolatilityAction, NULL);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalAssignAction2Params {
- CInt64 x0;
- IROLinear *nd;
- Boolean xC;
-} EvalAssignAction2Params;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalAssignAction2(LocationSet *ls, void *refcon) {
- EvalAssignAction2Params *params;
- CInt64 value;
- IROLinear *nd;
- ENodeType oper;
- UInt32 stride;
- Type *rtype;
- PAMemoryBlock *block;
-
- IRO_ASSERT(4657, ls != NULL);
- IRO_ASSERT(4658, refcon != NULL);
-
- params = refcon;
-
- if (!params->xC && !LocationSet_IsUnknown(ls)) {
- value = params->x0;
- nd = params->nd;
- IRO_ASSERT(4665, nd != NULL);
- oper = nd->nodetype;
-
- stride = LocationSet_stride(ls);
- rtype = LocationSet_rtype(ls);
- block = LocationSet_block(ls);
-
- if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_INT) {
- LocationSet_Term(ls);
-
- switch (oper) {
- case EPOSTINC:
- case EPREINC:
- case EADDASS:
- value = CInt64_Add(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EPOSTDEC:
- case EPREDEC:
- case ESUBASS:
- value = CInt64_Sub(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EMULASS:
- if (IRO_IsUnsignedType(nd->rtype))
- value = CInt64_MulU(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- else
- value = CInt64_Mul(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EDIVASS:
- if (CInt64_IsZero(&value)) {
- if (nd->stmt->sourceoffset) {
- TStreamElement *e = CPrep_CurStreamElement();
- e->tokenoffset = nd->stmt->sourceoffset;
- CError_SetErrorToken(e);
- }
- CError_Warning(CErrorStr139);
- params->xC = 1;
- } else {
- if (IRO_IsUnsignedType(nd->rtype))
- value = CInt64_DivU(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- else
- value = CInt64_Div(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- }
- break;
- case EMODASS:
- if (CInt64_IsZero(&value)) {
- if (nd->stmt->sourceoffset) {
- TStreamElement *e = CPrep_CurStreamElement();
- e->tokenoffset = nd->stmt->sourceoffset;
- CError_SetErrorToken(e);
- }
- CError_Warning(CErrorStr139);
- params->xC = 1;
- } else {
- if (IRO_IsUnsignedType(nd->rtype))
- value = CInt64_ModU(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- else
- value = CInt64_Mod(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- }
- break;
- case ESHLASS:
- value = CInt64_Shl(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case ESHRASS:
- if (IRO_IsUnsignedType(nd->rtype))
- value = CInt64_ShrU(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- else
- value = CInt64_Shr(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EANDASS:
- value = CInt64_And(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EXORASS:
- value = CInt64_Xor(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- case EORASS:
- value = CInt64_Or(*((CInt64 *) PAMemoryBlock_thing(block)), value);
- break;
- default:
- CError_FATAL(4746);
- }
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_INT, &value);
- LocationSet_InitKnown(ls, block, cint64_zero, stride, rtype);
- } else {
- if (oper == EPOSTDEC || oper == EPREDEC || oper == ESUBASS)
- value = CInt64_Neg(value);
-
- switch (oper) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- case EADDASS:
- case ESUBASS:
- value = CInt64_Add(LocationSet_field(ls), value);
- if (stride) {
- CInt64 tmp;
- CInt64_SetLong(&tmp, stride);
- value = CInt64_Mod(value, tmp);
- }
- SetsLocationSetField_sub_4851B0(ls, value);
- break;
- default:
- params->xC = 1;
- break;
- }
- }
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalAssignActionParams {
- Object *proc;
- PartialTransferFunction *ptf;
- IROLinear *nd;
- IRONode *fnode;
- LocationSetSet *srcs;
- Boolean x14;
- Boolean x15;
- Boolean x16;
-} EvalAssignActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalAssignAction(LocationSet *dst, void *refcon) {
- EvalAssignActionParams *params;
- LocationSetSet *srcs;
-
- IRO_ASSERT(4797, dst != NULL);
- IRO_ASSERT(4798, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(4802, params->proc != NULL);
- IRO_ASSERT(4802, params->ptf != NULL);
- IRO_ASSERT(4803, params->nd != NULL);
- IRO_ASSERT(4804, params->fnode != NULL);
- IRO_ASSERT(4805, params->srcs != NULL);
-
- srcs = params->srcs;
- if (
- !params->x14 ||
- !LocationSetRepresentsSingleLocation(dst, params->proc, params->nd->pointsToFunction) ||
- LocationIsVolatile(dst, params->proc) ||
- LocationSet_sub_48AF30(dst)
- ) {
- LocationSetSet *set = LocationSetSet_New();
- LocationSetSet_Init(set);
- params->x15 |= Lookup(set, &stCallingContextStack, params->proc, NULL, params->ptf, dst, params->nd->pointsToFunction, 0, params->nd->rtype);
- LocationSetSet_AddSet(srcs, set);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-
- params->x16 |= Assign(params->ptf, dst, srcs, params->proc, params->nd, params->fnode);
-}
-
-static Boolean EvalAssign(Object *proc, IROLinear *nd, IRONode *fnode, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- EvalAssignActionParams params;
- EvalAssignAction2Params params2;
- LocationSetSet *set;
- LocationSet *tmp;
- PAMemoryBlock *block;
- Type *type;
-
- IRO_ASSERT(4840, proc != NULL);
- IRO_ASSERT(4841, nd != NULL);
- IRO_ASSERT(4842, fnode != NULL);
- IRO_ASSERT(4843, map != NULL);
- IRO_ASSERT(4844, ptf != NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptf = ptf;
- params.nd = nd;
- params.fnode = fnode;
- params.x15 = 0;
- params.x16 = 0;
-
- set = LocationSetSet_New();
- params.srcs = LocationSetSet_New();
- LocationSetSet_Init(set);
- LocationSetSet_Init(params.srcs);
-
- if (nd->type == IROLinearOp2Arg) {
- IRO_ASSERT(4861, nd->u.diadic.left->type == IROLinearOp1Arg && nd->u.diadic.left->nodetype == EINDIRECT);
-
- params.x15 |= EvalExpr(set, proc, nd->u.diadic.left->u.monadic, &stCallingContextStack, map, ptf);
- AdjustTypesForVolatility(set, proc, nd->u.diadic.left);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.diadic.right, &stCallingContextStack, map, ptf);
-
- if (nd->nodetype != EASS) {
- switch (nd->nodetype) {
- case EMULASS:
- case EDIVASS:
- case EMODASS:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EANDASS:
- case EXORASS:
- case EORASS:
- if (
- LocationSetSet_Count(params.srcs) == 1 &&
- (tmp = LocationSetSet_FindFirst(params.srcs)) &&
- !LocationSet_IsUnknown(tmp) &&
- !LocationSet_stride(tmp) &&
- (block = LocationSet_block(tmp)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_INT
- ) {
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.diadic.left, &stCallingContextStack, map, ptf);
-
- memset(&params2, 0, sizeof(params2));
- params2.x0 = *((CInt64 *) PAMemoryBlock_thing(block));
- IRO_TruncateValueToType(&params2.x0, nd->u.diadic.right->rtype);
- params2.nd = nd;
- params2.xC = 0;
-
- if (!CInt64_IsZero(&params2.x0)) {
- LocationSetSet_ForEach(params.srcs, EvalAssignAction2, &params2);
- if (params2.xC) {
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.diadic.left, &stCallingContextStack, map, ptf);
- if (!LocationSetSet_FindUnknown(params.srcs))
- LocationSetSet_ForEach(params.srcs, EvalExprAction2, (void *) &cint64_one);
- }
- }
- } else {
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.diadic.left, &stCallingContextStack, map, ptf);
- if (!LocationSetSet_FindUnknown(params.srcs))
- LocationSetSet_ForEach(params.srcs, EvalExprAction2, (void *) &cint64_one);
- }
- break;
- default:
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- LocationSetSet_AddUnknown(params.srcs, nd->rtype, NULL, NULL);
- break;
- }
- }
- } else if (nd->type == IROLinearOp1Arg) {
- IRO_ASSERT(4958, nd->u.monadic.left->type == IROLinearOp1Arg && nd->u.monadic->nodetype == EINDIRECT);
-
- params.x15 |= EvalExpr(set, proc, nd->u.monadic->u.monadic, &stCallingContextStack, map, ptf);
- AdjustTypesForVolatility(set, proc, nd->u.monadic);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.monadic, &stCallingContextStack, map, ptf);
-
- switch (nd->nodetype) {
- case EPOSTINC:
- case EPOSTDEC:
- case EPREINC:
- case EPREDEC:
- memset(&params2, 0, sizeof(params2));
- params2.x0 = cint64_one;
- params2.nd = nd;
- params2.xC = 0;
-
- type = NULL;
- if (IS_TYPE_POINTER(nd->rtype))
- type = TPTR_TARGET(nd->rtype);
- else if (IS_TYPE_MEMBERPOINTER(nd->rtype))
- type = TYPE_MEMBER_POINTER(nd->rtype)->ty1;
-
- if (type)
- CInt64_SetLong(&params2.x0, type->size);
-
- if (!CInt64_IsZero(&params2.x0)) {
- LocationSetSet_ForEach(params.srcs, EvalAssignAction2, &params2);
- if (params2.xC) {
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.monadic, &stCallingContextStack, map, ptf);
- if (!LocationSetSet_FindUnknown(params.srcs))
- LocationSetSet_ForEach(params.srcs, EvalExprAction2, (void *) &cint64_one);
- }
- }
- break;
-
- default:
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Init(params.srcs);
- LocationSetSet_AddUnknown(params.srcs, nd->rtype, NULL, NULL);
- break;
- }
- } else {
- CError_FATAL(5006);
- }
-
- if (LocationSetSet_Count(params.srcs) != 0) {
- PointsToFunction *pointsToFunc;
-
- pointsToFunc = PointsToFunction_New();
- if (nd->pointsToFunction)
- PointsToFunction_Copy(pointsToFunc, nd->pointsToFunction);
- else
- PointsToFunction_Init(pointsToFunc);
-
- params.x14 = LocationSetSet_Count(set) == 1;
- LocationSetSet_ForEach(set, EvalAssignAction, &params);
-
- if (!params.x15 && params.x16) {
- if (nd->pointsToFunction)
- params.x15 = !PointsToFunctions_Equal(pointsToFunc, nd->pointsToFunction);
- else
- params.x15 = PointsToFunction_FindFirst(pointsToFunc) != NULL;
- }
-
- PointsToFunction_Term(pointsToFunc);
- PointsToFunction_Delete(pointsToFunc);
- }
-
- LocationSetSet_Term(set);
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Delete(set);
- LocationSetSet_Delete(params.srcs);
-
- return params.x15;
-}
-
-static Boolean EvalReturn(Object *proc, IROLinear *nd, IRONode *fnode, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- EvalAssignActionParams params;
- LocationSet *loc;
-
- IRO_ASSERT(5046, proc != NULL);
- IRO_ASSERT(5047, nd != NULL);
- IRO_ASSERT(5048, nd->type == IROLinearReturn);
- IRO_ASSERT(5049, fnode != NULL);
- IRO_ASSERT(5050, map != NULL);
- IRO_ASSERT(5051, ptf != NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptf = ptf;
- params.nd = nd;
- params.fnode = fnode;
- params.x15 = 0;
- params.x16 = 0;
-
- if (nd->u.monadic) {
- params.srcs = LocationSetSet_New();
- LocationSetSet_Init(params.srcs);
-
- loc = PartialTransferFunction_returnLocation(ptf);
- params.x15 |= EvalExpr(params.srcs, proc, nd->u.monadic, &stCallingContextStack, map, ptf);
-
- if (LocationSetSet_Count(params.srcs) != 0) {
- params.x14 = 1;
- EvalAssignAction(loc, &params);
- params.x15 |= params.x16;
- }
-
- LocationSetSet_Term(params.srcs);
- LocationSetSet_Delete(params.srcs);
- }
-
- return params.x15;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct ApplySummaryActionParams {
- ParamMappingFunction *tgtMap;
- Object *proc;
- IRONode *fnode;
- IROLinear *nd;
- PartialTransferFunction *ptf;
- ParamMappingFunction *map;
- LocationSet *loc;
- LocationSetSet *locs;
- Boolean x20;
- Boolean x21;
- Boolean x22;
-} ApplySummaryActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void ApplySummaryAction2(ParamMapping *mapping, void *refcon) {
- ApplySummaryActionParams *params;
- PAMemoryBlock *block;
- ExtendedParam *ep;
- IROLinear *nd;
- LocationSetSet *set;
- EvalAssignActionParams assignParams;
-
- IRO_ASSERT(5108, mapping != NULL);
- IRO_ASSERT(5109, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5113, params->tgtMap != NULL);
- IRO_ASSERT(5114, params->proc != NULL);
- IRO_ASSERT(5115, params->fnode != NULL);
- IRO_ASSERT(5116, params->nd != NULL);
- IRO_ASSERT(5117, params->nd->type == IROLinearFunccall);
- IRO_ASSERT(5118, params->ptf != NULL);
- IRO_ASSERT(5119, params->map != NULL);
- IRO_ASSERT(5120, params->loc != NULL);
- IRO_ASSERT(5121, params->locs != NULL);
-
- block = LocationSet_block(params->loc);
-
- IRO_ASSERT(5124, block != NULL);
- IRO_ASSERT(5125, PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM);
-
- ep = PAMemoryBlock_thing(block);
-
- IRO_ASSERT(5127, ep != NULL);
-
- if (ParamMapping_extended(mapping) == ep && (nd = ParamMapping_actual(mapping))) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- params->x21 |= EvalExpr(set, params->proc, nd, &stCallingContextStack, params->map, params->ptf);
-
- if (!LocationSetSet_FindUnknown(set)) {
- CInt64 stride64;
- CInt64 value;
-
- value = LocationSet_field(params->loc);
- LocationSetSet_ForEach(set, EvalExprAction, &value);
-
- CInt64_SetULong(&stride64, LocationSet_stride(params->loc));
- LocationSetSet_ForEach(set, EvalExprAction2, &stride64);
- }
-
- memset(&assignParams, 0, sizeof(assignParams));
- assignParams.proc = params->proc;
- assignParams.ptf = params->ptf;
- assignParams.nd = params->nd;
- assignParams.fnode = params->fnode;
- assignParams.srcs = params->locs;
- assignParams.x14 = params->x20 && (LocationSetSet_Count(set) == 1);
- assignParams.x15 = 0;
- assignParams.x16 = 0;
- LocationSetSet_ForEach(set, EvalAssignAction, &assignParams);
-
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
-
- params->x21 |= assignParams.x15;
- params->x22 |= assignParams.x16;
- }
-}
-
-static void ApplySummaryAction(PointsToEntry *pte, void *refcon) {
- ApplySummaryActionParams *params;
- LocationSet *loc;
- PAMemoryBlock *block;
-
- IRO_ASSERT(5175, pte != NULL);
- IRO_ASSERT(5176, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5180, params->tgtMap != NULL);
- IRO_ASSERT(5181, params->proc != NULL);
- IRO_ASSERT(5182, params->fnode != NULL);
- IRO_ASSERT(5183, params->nd != NULL);
- IRO_ASSERT(5184, params->nd->type == IROLinearFunccall);
- IRO_ASSERT(5185, params->ptf != NULL);
- IRO_ASSERT(5186, params->map != NULL);
-
- loc = PointsToEntry_loc(pte);
-
- IRO_ASSERT(5189, loc != NULL);
- IRO_ASSERT(5190, !LocationSet_IsUnknown(loc));
-
- block = LocationSet_block(loc);
- if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- params->loc = loc;
- params->locs = PointsToEntry_locs(pte);
- pmf_sub_487C70(params->tgtMap, ApplySummaryAction2, params);
- }
-}
-
-static Boolean ApplySummary(PartialTransferFunction *tgtPTF, ParamMappingFunction *tgtMap, Object *proc, IRONode *fnode, IROLinear *nd, PartialTransferFunction *ptf, ParamMappingFunction *map, Boolean flag) {
- Boolean result;
- ApplySummaryActionParams params;
- PointsToFunction *pointsToFunc;
-
- IRO_ASSERT(5208, tgtPTF != NULL);
- IRO_ASSERT(5209, tgtMap != NULL);
- IRO_ASSERT(5210, proc != NULL);
- IRO_ASSERT(5211, fnode != NULL);
- IRO_ASSERT(5212, nd != NULL);
- IRO_ASSERT(5213, nd->type == IROLinearFunccall);
- IRO_ASSERT(5214, ptf != NULL);
- IRO_ASSERT(5215, map != NULL);
-
- StoreReturnedLocations(nd, tgtPTF, tgtMap);
- if (tgtPTF == stUnknownPTF) {
- result = KillAllAddressableLocations(proc, fnode, nd, ptf);
- } else {
- pointsToFunc = PointsToFunction_New();
- if (nd->pointsToFunction)
- PointsToFunction_Copy(pointsToFunc, nd->pointsToFunction);
- else
- PointsToFunction_Init(pointsToFunc);
-
- memset(&params, 0, sizeof(params));
- params.tgtMap = tgtMap;
- params.proc = proc;
- params.fnode = fnode;
- params.nd = nd;
- params.ptf = ptf;
- params.map = map;
- params.loc = NULL;
- params.locs = NULL;
- params.x20 = flag;
- params.x21 = 0;
- params.x22 = 0;
-
- PointsToFunction_ForEach(PartialTransferFunction_finalPointsToFn(tgtPTF), ApplySummaryAction, &params);
-
- result = params.x21;
- if (!params.x21 && params.x22) {
- if (nd->pointsToFunction)
- result = !PointsToFunctions_Equal(pointsToFunc, nd->pointsToFunction);
- else
- result = PointsToFunction_FindFirst(pointsToFunc) != NULL;
- }
- }
-
- return result;
-}
-
-static void GetPTFAction2(ParamMapping *mapping, void *refcon) {
- IRO_ASSERT(5331, mapping != NULL);
-
- if (ParamMapping_extended(mapping))
- ParamMapping_SetExtended(mapping, NULL);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct GetPTFActionParams {
- ParamMappingFunction *map;
- Object *proc;
- IROLinear *nd;
- PartialTransferFunction *ptf;
- Boolean *needVisit;
- PartialTransferFunction *x14;
- PartialTransferFunction *x18;
-} GetPTFActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void GetPTFAction(PartialTransferFunction *tgtPTF, void *refcon) {
- GetPTFActionParams *params;
-
- IRO_ASSERT(5359, tgtPTF != NULL);
- IRO_ASSERT(5360, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5364, params->map != NULL);
- IRO_ASSERT(5365, params->proc != NULL);
- IRO_ASSERT(5366, params->proc != &stUnknown);
- IRO_ASSERT(5367, params->nd != NULL);
- IRO_ASSERT(5368, params->ptf != NULL);
- IRO_ASSERT(5369, params->needVisit != NULL);
-
- if (!params->x18) {
- if (MatchPTF(tgtPTF, params->proc, params->map, params->nd, params->ptf)) {
- if (InputsHaveNewPointerValues(tgtPTF, params->ptf))
- *params->needVisit = 1;
- params->x18 = tgtPTF;
- } else {
- pmf_sub_487C70(params->map, GetPTFAction2, NULL);
- if (PTF_sub_48B980(tgtPTF) == params->nd && PTF_sub_48B970(tgtPTF) == params->ptf)
- params->x14 = tgtPTF;
- }
- }
-}
-
-static PartialTransferFunction *GetPTF(ParamMappingFunction *map, Object *proc, IROLinear *nd, PartialTransferFunction *ptf, Boolean *needVisit) {
- PartialTransferFunction *found;
- PartialTransferFunction *result;
- GetPTFActionParams params;
-
- IRO_ASSERT(5396, map != NULL);
- IRO_ASSERT(5397, proc != NULL);
- IRO_ASSERT(5398, nd != NULL);
- IRO_ASSERT(5399, ptf != NULL);
- IRO_ASSERT(5400, needVisit != NULL);
-
- if (proc == &stUnknown) {
- result = stUnknownPTF;
- } else {
- memset(&params, 0, sizeof(params));
- params.map = map;
- params.proc = proc;
- params.nd = nd;
- params.ptf = PartialTransferFunction_New();
- PartialTransferFunction_Init(params.ptf, nd, ptf);
- params.needVisit = needVisit;
- params.x14 = NULL;
- params.x18 = NULL;
-
- if (!proc->u.func.ptfList) {
- proc->u.func.ptfList = PTFList_New();
- PTFList_Init(proc->u.func.ptfList);
- }
-
- PTFList_ForEach(proc->u.func.ptfList, GetPTFAction, &params);
-
- found = params.x18;
- if (found && !*needVisit) {
- PartialTransferFunction_Copy(result = PartialTransferFunction_New(), found);
- } else {
- result = stUnknownPTF;
- }
-
- PartialTransferFunction_Term(params.ptf);
- PartialTransferFunction_Delete(params.ptf);
- }
-
- return result;
-}
-
-static Boolean IsMeetNode(IRONode *fnode, IROLinear *nd) {
- return (fnode->numpred > 1) && (fnode->first == nd);
-}
-
-static Boolean IsExitNode(Object *proc, IRONode *fnode) {
- IRO_ASSERT(5467, proc != NULL);
- IRO_ASSERT(5468, fnode != NULL);
-
- return (fnode->numsucc == 0) && Bv_IsBitSet(FunctionFirstNode(proc)->index, fnode->dom);
-}
-
-static Boolean SomePredecessorHasBeenVisited(Object *proc, IRONode *fnode) {
- UInt16 i;
-
- IRO_ASSERT(5479, proc != NULL);
- IRO_ASSERT(5480, fnode != NULL);
-
- for (i = 0; i < fnode->numpred; i++) {
- if (FunctionNodeTable(proc)[fnode->pred[i]]->x3C)
- return 1;
- }
-
- return 0;
-}
-
-static Boolean AllPredecessorsHaveBeenVisited(Object *proc, IRONode *fnode) {
- UInt16 i;
-
- IRO_ASSERT(0, proc != NULL);
- IRO_ASSERT(0, fnode != NULL);
-
- for (i = 0; i < fnode->numpred; i++) {
- if (!FunctionNodeTable(proc)[fnode->pred[i]]->x3C)
- return 0;
- }
-
- return 1;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct EvalProcActionParams {
- Object *proc;
- IRONode *fnode;
- PartialTransferFunction *ptf;
-} EvalProcActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalProcAction2(PointsToEntry *pte, void *refcon) {
- EvalProcActionParams *params;
- LocationSet *dst;
- PAMemoryBlock *block;
- LocationSetSet *set;
- IRONode *node;
-
- IRO_ASSERT(5525, pte != NULL);
- IRO_ASSERT(5526, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5530, params->proc != NULL);
- IRO_ASSERT(5531, params->fnode != NULL);
- IRO_ASSERT(5532, params->ptf != NULL);
-
- dst = PointsToEntry_loc(pte);
-
- IRO_ASSERT(5535, dst != NULL);
- IRO_ASSERT(5536, !LocationSet_IsUnknown(dst));
-
- block = LocationSet_block(dst);
-
- if (block && (LocationSet_sub_48AF30(dst) || PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM)) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- LocationSetSet_AddSet(set, PointsToEntry_locs(pte));
-
- for (node = FunctionFirstNode(params->proc); node; node = node->nextnode) {
- if (node->x3C && node != params->fnode && IsExitNode(params->proc, node)) {
- if (node->last->pointsToFunction)
- Lookup(set, &stCallingContextStack, params->proc, NULL, params->ptf, dst, node->last->pointsToFunction, 0, NULL);
- }
- }
-
- Assign(params->ptf, dst, set, params->proc, NULL, NULL);
-
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct AssignEachInPointsToFunctionActionParams {
- Object *proc;
- IROLinear *nd;
- IRONode *fnode;
- PartialTransferFunction *ptf;
- Boolean x10;
-} AssignEachInPointsToFunctionActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void AssignEachInPointsToFunctionAction(PointsToEntry *pte, void *refcon) {
- AssignEachInPointsToFunctionActionParams *params;
- LocationSet *dst;
- LocationSetSet *srcs;
-
- IRO_ASSERT(5577, pte != NULL);
- IRO_ASSERT(5578, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5582, params->proc != NULL);
- IRO_ASSERT(5583, params->nd != NULL);
- IRO_ASSERT(5584, params->fnode != NULL);
- IRO_ASSERT(5585, params->ptf != NULL);
-
- dst = PointsToEntry_loc(pte);
-
- srcs = LocationSetSet_New();
- LocationSetSet_Init(srcs);
- LocationSetSet_AddSet(srcs, PointsToEntry_locs(pte));
- params->x10 |= Assign(params->ptf, dst, srcs, params->proc, params->nd, params->fnode);
- LocationSetSet_Term(srcs);
- LocationSetSet_Delete(srcs);
-}
-
-static void AssignEachInPointsToFunction(PointsToFunction *pointsTo, void *refcon) {
- AssignEachInPointsToFunctionActionParams *params;
- PointsToFunction *pointsToFunc;
-
- IRO_ASSERT(5602, pointsTo != NULL);
- IRO_ASSERT(5603, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(5607, params->nd != NULL);
-
- pointsToFunc = PointsToFunction_New();
- if (params->nd->pointsToFunction)
- PointsToFunction_Copy(pointsToFunc, params->nd->pointsToFunction);
- else
- PointsToFunction_Init(pointsToFunc);
-
- if (PointsToFunction_FindFirst(pointsToFunc)) {
- PointsToFunction_ForEach(pointsTo, AssignEachInPointsToFunctionAction, params);
- } else {
- if (!params->nd->pointsToFunction)
- params->nd->pointsToFunction = PointsToFunction_New();
- else
- PointsToFunction_Term(params->nd->pointsToFunction);
-
- PointsToFunction_Copy(params->nd->pointsToFunction, pointsTo);
- params->x10 = 1;
- }
-
- if (params->x10) {
- if (params->nd->pointsToFunction)
- params->x10 = !PointsToFunctions_Equal(pointsToFunc, params->nd->pointsToFunction);
- else
- params->x10 = PointsToFunction_FindFirst(pointsToFunc) != NULL;
- }
-
- PointsToFunction_Term(pointsToFunc);
- PointsToFunction_Delete(pointsToFunc);
-}
-
-static Boolean ObjectIsAFunctionArgument(Object *proc, Object *obj) {
- ObjectList *list;
-
- IRO_ASSERT(5643, proc != NULL);
- IRO_ASSERT(5644, proc != &stUnknown);
- IRO_ASSERT(5645, obj != NULL);
-
- if (obj->datatype == DLOCAL) {
- for (list = FunctionArguments(proc); list; list = list->next) {
- if (obj == list->object)
- return 1;
- }
- }
-
- return 0;
-}
-
-static Boolean ObjectIsARealFunctionArgument(Object *proc, Object *obj) {
- ObjectList *list;
-
- IRO_ASSERT(5661, proc != NULL);
- IRO_ASSERT(5662, proc != &stUnknown);
- IRO_ASSERT(5663, obj != NULL);
-
- if (obj->datatype == DLOCAL && proc == cscope_currentfunc) {
- for (list = arguments; list; list = list->next) {
- if (obj == list->object)
- return 1;
- }
- }
-
- return 0;
-}
-
-static void AddLocalVarsAddressedByExceptionUses(Object *var) {
- IRO_ASSERT(5699, var != NULL);
- IRO_ASSERT(5700, stExceptionFNode != NULL);
- IRO_ASSERT(5701, stExceptionFNode->addressed != NULL);
-
- if (var->datatype == DLOCAL)
- ObjectSet_sub_4867D0(stExceptionFNode->addressed, var);
-}
-
-static Boolean LinearNodeIsInFlowgraphNode(IROLinear *nd, IRONode *fnode) {
- IROLinear *first;
- IROLinear *last;
- IROLinear *scan;
-
- if (fnode && (first = fnode->first) && (last = fnode->last)) {
- for (scan = first; scan && scan != last->next; scan = scan->next) {
- if (scan == nd)
- return 1;
- }
- }
-
- return 0;
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-static struct {
- Object *proc;
- IRONode *fnode;
- ParamMappingFunction *map;
- PartialTransferFunction *ptf;
- PointsToFunction *pointsToFunc;
- Boolean *changed;
- Boolean x18;
- Boolean x19;
-} stEvalProcActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void EvalProcAction(IROLinear *Int, Boolean flag) {
- Boolean *changed;
- Boolean result;
- Object *proc;
- PartialTransferFunction *ptf;
- Boolean x18;
- Boolean x19;
- IRONode *fnode;
- PointsToFunction *pointsToFunc;
- ParamMappingFunction *map;
- Object *obj;
- AssignEachInPointsToFunctionActionParams params;
-
- static int userBreakCounter;
-
- if (!flag && !Int->x1E) {
- IRO_ASSERT(5748, Int != NULL);
- IRO_ASSERT(5749, stEvalProcActionParams.changed != NULL);
-
- proc = stEvalProcActionParams.proc;
- fnode = stEvalProcActionParams.fnode;
- map = stEvalProcActionParams.map;
- ptf = stEvalProcActionParams.ptf;
- pointsToFunc = stEvalProcActionParams.pointsToFunc;
- changed = stEvalProcActionParams.changed;
- x18 = stEvalProcActionParams.x18;
- x19 = stEvalProcActionParams.x19;
-
- IRO_ASSERT(5760, proc != NULL);
- IRO_ASSERT(5761, fnode != NULL);
- IRO_ASSERT(5762, map != NULL);
- IRO_ASSERT(5763, ptf != NULL);
-
- if (++userBreakCounter > 40) {
- IRO_CheckForUserBreak();
- userBreakCounter = 0;
- }
-
- result = 0;
-
- if (x19 && Int->pointsToFunction) {
- PointsToFunction_Term(Int->pointsToFunction);
- PointsToFunction_Delete(Int->pointsToFunction);
- Int->pointsToFunction = NULL;
- }
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.nd = Int;
- params.fnode = fnode;
- params.ptf = ptf;
- params.x10 = 0;
-
- if (x18) {
- PointsToFunction *initial = PartialTransferFunction_initialPointsToFn(ptf);
- if (fnode == FunctionFirstNode(proc) && initial) {
- AssignEachInPointsToFunction(initial, &params);
- result |= params.x10;
- }
- result |= EvalMeet(proc, fnode, Int, ptf);
- pointsToFunc = Int->pointsToFunction;
- x18 = 0;
- } else if (!Int->pointsToFunction) {
- if (pointsToFunc)
- AssignEachInPointsToFunction(pointsToFunc, &params);
- result |= params.x10;
- pointsToFunc = Int->pointsToFunction;
- }
-
- if (IRO_IsAssignment(Int)) {
- if (Int->flags & IROLF_4000)
- longjmp(stAbortPointerAnalysis, 1);
- result |= EvalAssign(proc, Int, fnode, map, ptf);
- pointsToFunc = Int->pointsToFunction;
- } else if (Int->type == IROLinearReturn) {
- result |= EvalReturn(proc, Int, fnode, map, ptf);
- pointsToFunc = Int->pointsToFunction;
- } else if (Int->type == IROLinearFunccall) {
- if (Int->flags & IROLF_4000)
- longjmp(stAbortPointerAnalysis, 1);
- if (Int->stmt && IRO_FunctionCallMightThrowException(Int)) {
- stExceptionFNode = fnode;
- IRO_WalkExcActions(Int->stmt->dobjstack, AddLocalVarsAddressedByExceptionUses);
- }
- result |= EvalCall(proc, fnode, Int, map, ptf);
- pointsToFunc = Int->pointsToFunction;
- } else if (Int->type == IROLinearOp1Arg && Int->nodetype == EINDIRECT && (!(Int->flags & IROLF_Assigned) || (Int->flags & IROLF_Used))) {
- result |= EvalExpr(NULL, proc, Int, &stCallingContextStack, map, ptf);
- } else if (Int->type == IROLinearOperand && !(Int->flags & IROLF_Ind) && Int->u.node->type == EOBJREF && (obj = Int->u.node->data.objref) && obj->datatype == DLOCAL) {
- ObjectSet_sub_4867D0(fnode->addressed, obj);
- } else if (Int->type == IROLinearAsm) {
- IAEffects effects;
- int i;
- CodeGen_GetAsmEffects(Int->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++) {
- obj = effects.operands[i].object;
- if (obj && obj->datatype == DLOCAL && effects.operands[i].type == IAEffect_3) {
- ObjectSet_sub_4867D0(fnode->addressed, obj);
- }
- }
- }
-
- if (result && Int != fnode->last && fnode->last->pointsToFunction) {
- PointsToFunction_Term(fnode->last->pointsToFunction);
- PointsToFunction_Delete(fnode->last->pointsToFunction);
- fnode->last->pointsToFunction = NULL;
- }
-
- *changed |= result;
- x19 |= result;
-
- stEvalProcActionParams.pointsToFunc = pointsToFunc;
- stEvalProcActionParams.x18 = x18;
- stEvalProcActionParams.x19 = x19;
-
- Int->x1E = 1;
-
- if (Int->type != IROLinearReturn) {
- IROLinear *father = IRO_LocateFather(Int);
- if (father && father->type == IROLinearReturn) {
- if (LinearNodeIsInFlowgraphNode(father, fnode))
- EvalProcAction(father, 0);
- else
- longjmp(stAbortPointerAnalysis, 1);
- }
- }
- }
-}
-
-static void EvalProc(Object *proc, ParamMappingFunction *map, PartialTransferFunction *ptf) {
- IRONode *fnode;
- IRONode *pred;
- IROLinear *nd;
- UInt32 passCount;
- Boolean changed;
- UInt16 i;
- AssignEachInPointsToFunctionActionParams assignParams;
- EvalProcActionParams params;
-
- IRO_ASSERT(5964, proc != NULL);
- IRO_ASSERT(5965, map != NULL);
- IRO_ASSERT(5966, ptf != NULL);
-
- for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode)
- fnode->x3C = 0;
-
- passCount = 0;
- do {
- clock();
- changed = 0;
- for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode) {
- if (fnode->last && ((fnode->numpred == 0) || SomePredecessorHasBeenVisited(proc, fnode))) {
- clock();
- if (!fnode->addressed) {
- fnode->addressed = ObjectSet_New();
- ObjectSet_Init(fnode->addressed);
- }
-
- for (i = 0; i < fnode->numpred; i++) {
- pred = FunctionNodeTable(proc)[fnode->pred[i]];
- if (pred->addressed)
- ObjectSet_sub_48C590(fnode->addressed, pred->addressed);
- }
-
- memset(&stEvalProcActionParams, 0, sizeof(stEvalProcActionParams));
- stEvalProcActionParams.proc = proc;
- stEvalProcActionParams.fnode = fnode;
- stEvalProcActionParams.map = map;
- stEvalProcActionParams.ptf = ptf;
- stEvalProcActionParams.pointsToFunc = NULL;
- stEvalProcActionParams.changed = &changed;
- stEvalProcActionParams.x18 = 1;
- stEvalProcActionParams.x19 = 0;
-
- for (nd = fnode->first; nd && nd != fnode->last->next; nd = nd->next)
- nd->x1E = 0;
- IRO_WalkInts(fnode->first, fnode->last, EvalProcAction);
-
- if (stEvalProcActionParams.x18 || !fnode->last->pointsToFunction) {
- memset(&assignParams, 0, sizeof(assignParams));
- assignParams.proc = proc;
- assignParams.nd = fnode->last;
- assignParams.fnode = fnode;
- assignParams.ptf = ptf;
- assignParams.x10 = 0;
- if (stEvalProcActionParams.x18) {
- PointsToFunction *initial = PartialTransferFunction_initialPointsToFn(ptf);
- if (fnode == FunctionFirstNode(proc) && initial) {
- AssignEachInPointsToFunction(initial, &assignParams);
- changed |= assignParams.x10;
- }
- changed |= EvalMeet(proc, fnode, fnode->last, ptf);
- stEvalProcActionParams.x18 = 0;
- } else {
- if (stEvalProcActionParams.pointsToFunc)
- AssignEachInPointsToFunction(stEvalProcActionParams.pointsToFunc, &assignParams);
- changed |= assignParams.x10;
- }
- }
-
- fnode->x3C = 1;
- clock();
- }
- }
-
- clock();
- if (++passCount > 32)
- CError_FATAL(6072);
- } while (changed);
-
- if (passCount > stMaxPassCount)
- stMaxPassCount = passCount;
-
- PartialTransferFunction_sub_48A610(ptf, 1);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptf = ptf;
- for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode) {
- if (fnode->x3C && IsExitNode(proc, fnode) && fnode->last->pointsToFunction) {
- params.fnode = fnode;
- PointsToFunction_ForEach(fnode->last->pointsToFunction, EvalProcAction2, &params);
- }
- }
-}
-
-static void PointerAnalysis_Init(void) {
- stCallingContextStack = Stack_New();
- Stack_Init(stCallingContextStack);
-
- stUnknownPTF = PartialTransferFunction_New();
- PartialTransferFunction_Init(stUnknownPTF, NULL, NULL);
-
- stExtParamSet = AllocsExtParamSet_sub_4876C0();
- InitsExtParamSet_sub_4876A0(stExtParamSet);
-
- stPTFList = PTFList_New();
- PTFList_Init(stPTFList);
-}
-
-static void CleanseLocationSet(LocationSet *loc, void *refcon) {
- PAMemoryBlock *block;
- PALocalVar *local;
-
- IRO_ASSERT(6161, loc != NULL);
- IRO_ASSERT(6162, refcon == NULL);
-
- if (
- !LocationSet_IsUnknown(loc) &&
- (block = LocationSet_block(loc)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_LOCALVAR &&
- (local = PAMemoryBlock_thing(block))
- ) {
- PALocalVar_SetSth_sub_4847C0(local, NULL);
- }
-}
-
-static void CleansePointsToEntry(PointsToEntry *pte, void *refcon) {
- IRO_ASSERT(6177, pte != NULL);
- IRO_ASSERT(6178, refcon == NULL);
-
- CleanseLocationSet(PointsToEntry_loc(pte), NULL);
- LocationSetSet_ForEach(PointsToEntry_locs(pte), CleanseLocationSet, NULL);
-}
-
-static void PointerAnalysis_TermAction4(PartialTransferFunction *ptf, void *refcon) {
- IRO_ASSERT(6187, ptf != NULL);
- IRO_ASSERT(6188, refcon == NULL);
-
- if (ptf != stUnknownPTF) {
- PointsToFunction_ForEach(PartialTransferFunction_initialPointsToFn(ptf), CleansePointsToEntry, NULL);
- PointsToFunction_ForEach(PartialTransferFunction_finalPointsToFn(ptf), CleansePointsToEntry, NULL);
- }
-}
-
-static void PointerAnalysis_TermAction3(ExtendedParam *ep) {
- ExtendedParam_Term(ep);
- ExtendedParam_Delete(ep);
-}
-
-static void PointerAnalysis_TermAction2(Object *obj, void *refcon) {
- ObjectSet *objSet;
- Object *proc;
- ObjectList *list;
-
- objSet = refcon;
-
- if (!ObjectIsAnExtendedParamCandidate(obj)) {
- if (
- obj->datatype == DLOCAL &&
- obj->u.var.info &&
- (proc = obj->u.var.info->func) &&
- ObjectIsAFunction(proc) &&
- proc->u.func.argList
- ) {
- for (list = proc->u.func.argList; list; list = list->next) {
- if (obj == list->object)
- break;
- }
-
- if (!list)
- ObjectSet_sub_4867D0(objSet, obj);
- } else {
- ObjectSet_sub_4867D0(objSet, obj);
- }
- }
-}
-
-static void PointerAnalysis_TermAction1(ExtendedParam *ep, void *refcon) {
- ObjectSet *objSet;
- ObjectSet *epObjSet;
- Object *obj;
-
- objSet = ObjectSet_New();
- ObjectSet_Init(objSet);
-
- epObjSet = ExtendedParam_objectSet(ep);
- obj = NULL;
- ObjectSet_ForEach(epObjSet, FindGlobalObjectAction, &obj);
- if (obj) {
- ObjectSet_ForEach(epObjSet, PointerAnalysis_TermAction2, objSet);
- if (ObjectSet_FindFirst(objSet))
- EP_sub_48C850(ep, objSet);
- }
-
- ObjectSet_Term(objSet);
- ObjectSet_Delete(objSet);
-}
-
-static void PointerAnalysis_Term(void) {
- if (stExtParamSet) {
- MaybeWalkExtParamSet_sub_48CBE0(stExtParamSet, PointerAnalysis_TermAction1, NULL);
- TermsExtParamSet_sub_48CB00(stExtParamSet);
- FreesExtParamSet_sub_48CAE0(stExtParamSet);
- stExtParamSet = NULL;
- }
-
- if (stPTFList) {
- PTFList_ForEach(stPTFList, PointerAnalysis_TermAction4, NULL);
- PTFList_Term(stPTFList);
- PTFList_Delete(stPTFList);
- stPTFList = NULL;
- }
-
- PartialTransferFunction_Term(stUnknownPTF);
- PartialTransferFunction_Delete(stUnknownPTF);
- stUnknownPTF = NULL;
-
- Stack_Term(&stCallingContextStack);
- Stack_Delete(stCallingContextStack);
- stCallingContextStack = NULL;
-}
-
-static void InvalidatePointsToFunctions(Object *proc) {
- IRONode *fnode;
- IROLinear *nd;
-
- IRO_ASSERT(6302, proc != NULL);
-
- for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode) {
- if (fnode->last) {
- if (fnode->addressed) {
- ObjectSet_Term(fnode->addressed);
- ObjectSet_Delete(fnode->addressed);
- fnode->addressed = NULL;
- }
-
- for (nd = fnode->first; nd && nd != fnode->last->next; nd = nd->next) {
- if (nd->pointsToFunction) {
- PointsToFunction_Term(nd->pointsToFunction);
- PointsToFunction_Delete(nd->pointsToFunction);
- nd->pointsToFunction = NULL;
- }
- }
- }
- }
-}
-
-static void InitialSetup(void) {
-}
-
-static void PointerAnalysis_HeapErrorProc(void) {
- longjmp(stAbortPointerAnalysis, 2);
-}
-
-void PointerAnalysis_Setup(void) {
- IRO_InitializeAllocator();
- stExtendedParamNum = 0;
- stParamObjs = NULL;
- stMaxPassCount = 0;
-}
-
-void PointerAnalysis_Cleanup(void) {
- ObjectList *list;
- ObjectList *next;
-
- for (list = stParamObjs; list; list = next) {
- IRO_free(list->object);
- next = list->next;
- IRO_free(list);
- }
- stParamObjs = NULL;
- IRO_TerminateAllocator();
-}
-
-void IRO_AnalyzePointers(Object *function) {
- EvalCallActionParams params;
- IROLinear nd;
- IRONode fnode;
- int code;
- volatile heaperror_t saveheaperror;
-
- IRO_ASSERT(6393, function != NULL);
-
- PointerAnalysis_Init();
-
- memset(&params, 0, sizeof(params));
- memset(&nd, 0, sizeof(nd));
- nd.type = IROLinearFunccall;
- memset(&fnode, 0, sizeof(fnode));
- params.proc = &stUnknown;
- params.fnode = &fnode;
- params.nd = &nd;
- params.ptf = stUnknownPTF;
- params.map = NULL;
- params.x18 = 0;
- params.x19 = 0;
- params.x1A = 1;
-
- stCurrentProc = FindMainEntryPoint(function);
-
- if ((code = setjmp(stAbortPointerAnalysis)) == 0) {
- saveheaperror = getheaperror();
- setheaperror(PointerAnalysis_HeapErrorProc);
- InitialSetup();
- EvalCallAction(stCurrentProc, &params);
- PointerAnalysis_Term();
- stCurrentProc = NULL;
- setheaperror(saveheaperror);
- } else {
- setheaperror(saveheaperror);
- InvalidatePointsToFunctions(stCurrentProc);
- PointerAnalysis_Term();
- stCurrentProc = NULL;
- if (code == 2 && saveheaperror)
- saveheaperror();
- }
-}
-
-static void RemoveRestrictedExtendedParamsAction(LocationSet *ls, void *refcon) {
- LocationSetSet *locs;
- PAMemoryBlock *block;
- ExtendedParam *ep;
- ObjectSet *objSet;
- Object *obj;
-
- locs = refcon;
-
- if (
- !LocationSet_IsUnknown(ls) &&
- (block = LocationSet_block(ls)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM &&
- (ep = PAMemoryBlock_thing(block))
- ) {
- objSet = ExtendedParam_objectSet(ep);
- if (
- ObjectSet_Count(objSet) == 1 &&
- (obj = ObjectSet_FindFirst(objSet)) &&
- ObjectIsRestrictQualified(obj)
- ) {
- LocationSetSet_Add(locs, ls);
- }
- }
-}
-
-static void RemoveRestrictedExtendedParams(LocationSetSet *locs) {
- LocationSetSet *set;
-
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- LocationSetSet_ForEach(locs, RemoveRestrictedExtendedParamsAction, set);
- LocationSetSet_sub_488700(locs, set);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
-}
-
-Boolean PointerAnalysis_TwoLinearNodePointerExprsMightAlias(Object *proc, IROLinear *nd1, IROLinear *nd2) {
- LocationSetSet *lss1;
- LocationSetSet *lss2;
- PointsToFunction *pointsTo1;
- PointsToFunction *pointsTo2;
- PointsToFunction *savePointsTo1;
- PointsToFunction *savePointsTo2;
- FindAliasingParams params;
-
- pointsTo1 = nd1->pointsToFunction;
- pointsTo2 = nd2->pointsToFunction;
- if (!pointsTo1)
- pointsTo1 = pointsTo2;
- if (!pointsTo2)
- pointsTo2 = pointsTo1;
-
- if (copts.opt_pointer_analysis_mode == 2 && !is_typeequal(nd1->rtype, nd2->rtype))
- return 0;
- if (!pointsTo1 || !pointsTo2)
- return 1;
-
- lss1 = LocationSetSet_New();
- LocationSetSet_Init(lss1);
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
-
- savePointsTo1 = nd1->pointsToFunction;
- nd1->pointsToFunction = pointsTo1;
- EvalExpr(lss1, proc, nd1, NULL, NULL, NULL);
- nd1->pointsToFunction = savePointsTo1;
-
- savePointsTo2 = nd2->pointsToFunction;
- nd2->pointsToFunction = pointsTo2;
- EvalExpr(lss2, proc, nd2, NULL, NULL, NULL);
- nd2->pointsToFunction = savePointsTo2;
-
- memset(&params, 0, sizeof(params));
- params.x8 = 0;
- params.x0 = lss2;
- LocationSetSet_ForEach(lss1, FindAliasingAction, &params);
-
- if (!params.x8) {
- params.x0 = lss1;
- LocationSetSet_ForEach(lss2, FindAliasingAction, &params);
-
- if (!params.x8) {
- RemoveRestrictedExtendedParams(lss1);
- RemoveRestrictedExtendedParams(lss2);
- ExpandLocationSetSetToActuals(&stCallingContextStack, NULL, lss1);
- ExpandLocationSetSetToActuals(&stCallingContextStack, NULL, lss2);
-
- params.x0 = lss2;
- LocationSetSet_ForEach(lss1, FindAliasingAction, &params);
-
- if (!params.x8) {
- params.x0 = lss1;
- LocationSetSet_ForEach(lss2, FindAliasingAction, &params);
- }
- }
- }
-
- LocationSetSet_Term(lss1);
- LocationSetSet_Delete(lss1);
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
-
- return params.x8;
-}
-
-Boolean PointerAnalysis_TwoENodePointerExprsMightAlias(Object *proc, ENode *nd1, ENode *nd2) {
- LocationSetSet *lss1;
- LocationSetSet *lss2;
- PointsToFunction *pointsTo1;
- PointsToFunction *pointsTo2;
- PointsToFunction *savePointsTo1;
- PointsToFunction *savePointsTo2;
- FindAliasingParams params;
-
- pointsTo1 = nd1->pointsTo;
- pointsTo2 = nd2->pointsTo;
- if (!pointsTo1)
- pointsTo1 = pointsTo2;
- if (!pointsTo2)
- pointsTo2 = pointsTo1;
-
- if (copts.opt_pointer_analysis_mode == 2 && !is_typeequal(nd1->rtype, nd2->rtype))
- return 0;
- if (!pointsTo1 || !pointsTo2)
- return 1;
-
- lss1 = LocationSetSet_New();
- LocationSetSet_Init(lss1);
- lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
-
- savePointsTo1 = nd1->pointsTo;
- nd1->pointsTo = pointsTo1;
- EvalENodeExpr(lss1, proc, nd1, NULL, NULL, NULL);
- nd1->pointsTo = savePointsTo1;
-
- savePointsTo2 = nd2->pointsTo;
- nd2->pointsTo = pointsTo2;
- EvalENodeExpr(lss2, proc, nd2, NULL, NULL, NULL);
- nd2->pointsTo = savePointsTo2;
-
- memset(&params, 0, sizeof(params));
- params.x8 = 0;
- params.x0 = lss2;
- LocationSetSet_ForEach(lss1, FindAliasingAction, &params);
-
- if (!params.x8) {
- params.x0 = lss1;
- LocationSetSet_ForEach(lss2, FindAliasingAction, &params);
-
- if (!params.x8) {
- RemoveRestrictedExtendedParams(lss1);
- RemoveRestrictedExtendedParams(lss2);
- ExpandLocationSetSetToActuals(&stCallingContextStack, NULL, lss1);
- ExpandLocationSetSetToActuals(&stCallingContextStack, NULL, lss2);
-
- params.x0 = lss2;
- LocationSetSet_ForEach(lss1, FindAliasingAction, &params);
-
- if (!params.x8) {
- params.x0 = lss1;
- LocationSetSet_ForEach(lss2, FindAliasingAction, &params);
- }
- }
- }
-
- LocationSetSet_Term(lss1);
- LocationSetSet_Delete(lss1);
- LocationSetSet_Term(lss2);
- LocationSetSet_Delete(lss2);
-
- return params.x8;
-}
-
-Boolean PointerAnalysis_IsLinearNodePointerExprDefinite(Object *proc, IROLinear *nd) {
- LocationSetSet *lss;
- LocationSet *loc;
- Boolean result;
-
- if (!nd->pointsToFunction)
- return 0;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- EvalExpr(lss, proc, nd, NULL, NULL, NULL);
-
- result =
- (LocationSetSet_Count(lss) == 1) &&
- (loc = LocationSetSet_FindFirst(lss)) &&
- LocationSetRepresentsSingleLocation(loc, NULL, NULL);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-
- return result;
-}
-
-Boolean PointerAnalysis_IsENodePointerExprDefinite(Object *proc, ENode *nd) {
- LocationSetSet *lss;
- LocationSet *loc;
- Boolean result;
-
- if (!nd->pointsTo)
- return 0;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- EvalENodeExpr(lss, proc, nd, NULL, NULL, NULL);
-
- result =
- (LocationSetSet_Count(lss) == 1) &&
- (loc = LocationSetSet_FindFirst(lss)) &&
- LocationSetRepresentsSingleLocation(loc, NULL, NULL);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-
- return result;
-}
-
-Boolean PointerAnalysis_IsVariableValueDefinite(Object *proc, VarRecord *var, PointsToFunction *pointsTo) {
- LocationSetSet *lss;
- LocationSet *loc;
- Boolean result;
-
- if (!pointsTo)
- return 0;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- EvalVariable(lss, proc, var, pointsTo, NULL, NULL, NULL);
-
- result =
- (LocationSetSet_Count(lss) == 1) &&
- (loc = LocationSetSet_FindFirst(lss)) &&
- LocationSetRepresentsSingleLocation(loc, NULL, NULL);
-
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
-
- return result;
-}
-
-static void FindGlobalObjectAction(Object *object, void *refcon) {
- if (ObjectIsAnExtendedParamCandidate(object)) {
- Object **ptr = refcon;
- *ptr = object;
- }
-}
-
-static void GetDefiniteObjectOfExtendedParamLoc(LocationSet *loc, Object **resultObj, CInt64 *resultField) {
- Object *obj;
- CInt64 field;
- PAMemoryBlock *block;
- ExtendedParam *ep;
- ObjectSet *objSet;
- LocationSetSet *locs;
- LocationSet *tmp;
- PALocalVar *local;
-
- IRO_ASSERT(6763, loc != NULL);
- IRO_ASSERT(6764, resultObj != NULL);
- IRO_ASSERT(6765, resultField != NULL);
-
- obj = NULL;
- field = LocationSet_field(loc);
- block = LocationSet_block(loc);
-
- if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- if ((ep = PAMemoryBlock_thing(block)) && (objSet = ExtendedParam_objectSet(ep))) {
- IRO_ASSERT(6777, obj == NULL);
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- }
- }
-
- if (!obj) {
- locs = LocationSetSet_New();
- LocationSetSet_Init(locs);
- GetActualLocsOfExtendedParam(locs, loc, NULL, &stCallingContextStack, NULL, 0);
-
- if (
- LocationSetSet_Count(locs) == 1 &&
- (tmp = LocationSetSet_FindFirst(locs)) &&
- !LocationSet_IsUnknown(tmp))
- {
- field = CInt64_Add(field, LocationSet_field(tmp));
- if (
- (block = LocationSet_block(tmp)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM &&
- (ep = PAMemoryBlock_thing(block)) &&
- (objSet = ExtendedParam_objectSet(ep))
- )
- {
- IRO_ASSERT(6801, obj == NULL);
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- } else if (
- (block = LocationSet_block(tmp)) &&
- PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_LOCALVAR &&
- (local = PAMemoryBlock_thing(block))
- )
- {
- obj = GetLocalObject(local, &stUnknown, 0);
- }
- }
-
- LocationSetSet_Term(locs);
- LocationSetSet_Delete(locs);
- }
-
- *resultObj = obj;
- *resultField = field;
-}
-
-static void CreateExpressionForLocationSet(LocationSet *loc, IROList *list, Type *rtype, Object *proc) {
- CInt64 field;
- PAMemoryBlock *block;
- PAMemoryBlockKind kind;
- void *thing;
- IROLinear *nd;
- Object *obj;
-
- IRO_ASSERT(6833, loc != NULL);
- IRO_ASSERT(6834, !LocationSet_IsUnknown(loc));
- IRO_ASSERT(6835, LocationSet_stride(loc) == 0);
- IRO_ASSERT(6836, list != NULL);
- IRO_ASSERT(6837, rtype != NULL);
- IRO_ASSERT(6838, proc != NULL);
-
- field = LocationSet_field(loc);
- block = LocationSet_block(loc);
- kind = PAMemoryBlock_kind(block);
- thing = PAMemoryBlock_thing(block);
- nd = NULL;
-
- switch (kind) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- GetDefiniteObjectOfExtendedParamLoc(loc, &obj, &field);
- if (obj) {
- nd = IRO_NewLinear(IROLinearOperand);
- nd->u.node = create_objectrefnode(obj);
- nd->rtype = rtype;
- nd->index = ++IRO_NumLinear;
- IRO_AddToList(nd, list);
- }
- break;
- case PAMEMORYBLOCKKIND_LOCALVAR:
- obj = GetLocalObject(thing, proc, 0);
- if (obj) {
- if (ObjectIsAFunctionArgument(proc, obj) && obj->u.var.realObj)
- obj = obj->u.var.realObj;
- nd = IRO_NewLinear(IROLinearOperand);
- nd->u.node = create_objectrefnode(obj);
- nd->rtype = rtype;
- nd->index = ++IRO_NumLinear;
- IRO_AddToList(nd, list);
- }
- break;
- case PAMEMORYBLOCKKIND_INT:
- if (IS_TYPE_INT(rtype)) {
- nd = IRO_NewIntConst(*((CInt64 *) thing), rtype);
- IRO_AddToList(nd, list);
- }
- break;
- case PAMEMORYBLOCKKIND_6:
- break;
- default:
- CError_FATAL(6894);
- }
-
- if (nd && !CInt64_IsZero(&field)) {
- IROLinear *nd2;
- IROLinear *nd3;
-
- nd2 = IRO_NewIntConst(field, TYPE(&stunsignedlong));
- IRO_AddToList(nd2, list);
-
- nd3 = IRO_NewLinear(IROLinearOp2Arg);
- nd3->nodetype = EADD;
- nd3->index = ++IRO_NumLinear;
- nd3->rtype = rtype;
- nd3->u.diadic.left = nd;
- nd3->u.diadic.right = nd2;
- IRO_AddToList(nd3, list);
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct LookupLinearExprActionParams {
- Object *proc;
- Type *indirectType;
- IROListNode **list;
-} LookupLinearExprActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void LookupLinearExprAction(LocationSet *loc, void *refcon) {
- LookupLinearExprActionParams *params;
- IROListNode *list;
-
- IRO_ASSERT(6926, loc != NULL);
- IRO_ASSERT(6927, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(6931, params->proc != NULL);
- IRO_ASSERT(6932, params->indirectType != NULL);
- IRO_ASSERT(6933, params->list != NULL);
-
- list = *params->list = IRO_malloc(sizeof(IROListNode));
- IRO_InitList(&list->list);
- list->nextList = NULL;
-
- if (!LocationSet_IsUnknown(loc) && LocationSetRepresentsSingleLocation(loc, NULL, NULL))
- CreateExpressionForLocationSet(loc, &list->list, params->indirectType, params->proc);
-
- params->list = &list->nextList;
-}
-
-void PointerAnalysis_LookupLinearNodePointerExpr(Object *proc, IROLinear *indirect, IROListNode **list) {
- LocationSetSet *set;
- LookupLinearExprActionParams params;
-
- IRO_ASSERT(6957, indirect != NULL);
-
- if (indirect->pointsToFunction) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- EvalExpr(set, proc, indirect, NULL, NULL, NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.indirectType = indirect->rtype;
- params.list = list;
-
- LocationSetSet_ForEach(set, LookupLinearExprAction, &params);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-static void CreateENodeForLocationSet(LocationSet *loc, ENode **resultNode, Type *rtype, Object *proc) {
- CInt64 field;
- PAMemoryBlock *block;
- PAMemoryBlockKind kind;
- void *thing;
- ENode *nd;
- Object *obj;
-
- IRO_ASSERT(0, loc != NULL);
- IRO_ASSERT(0, !LocationSet_IsUnknown(loc));
- IRO_ASSERT(0, LocationSet_stride(loc) == 0);
- IRO_ASSERT(0, resultNode != NULL);
- IRO_ASSERT(0, rtype != NULL);
- IRO_ASSERT(0, proc != NULL);
-
- field = LocationSet_field(loc);
- block = LocationSet_block(loc);
- kind = PAMemoryBlock_kind(block);
- thing = PAMemoryBlock_thing(block);
- nd = NULL;
-
- switch (kind) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- GetDefiniteObjectOfExtendedParamLoc(loc, &obj, &field);
- if (obj) {
- nd = create_objectrefnode(obj);
- nd->rtype = rtype;
- }
- break;
- case PAMEMORYBLOCKKIND_LOCALVAR:
- obj = GetLocalObject(thing, proc, 0);
- if (obj) {
- if (ObjectIsAFunctionArgument(proc, obj) && obj->u.var.realObj)
- obj = obj->u.var.realObj;
- nd = create_objectrefnode(obj);
- nd->rtype = rtype;
- }
- break;
- case PAMEMORYBLOCKKIND_INT:
- if (IS_TYPE_INT(rtype)) {
- nd = IRO_NewENode(EINTCONST);
- nd->data.intval = *((CInt64 *) thing);
- nd->rtype = rtype;
- }
- break;
- case PAMEMORYBLOCKKIND_6:
- break;
- default:
- CError_FATAL(7040);
- }
-
- if (nd && !CInt64_IsZero(&field)) {
- ENode *nd2;
- ENode *nd3;
-
- nd2 = IRO_NewENode(EINTCONST);
- nd2->data.intval = field;
- nd2->rtype = TYPE(&stunsignedlong);
-
- nd3 = IRO_NewENode(EADD);
- nd3->data.diadic.left = nd;
- nd3->data.diadic.right = nd2;
- nd3->rtype = rtype;
-
- *resultNode = nd3;
- } else {
- *resultNode = nd;
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct LookupENodeExprActionParams {
- Object *proc;
- Type *indirectType;
- ENodeList **list;
-} LookupENodeExprActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void LookupENodeExprAction(LocationSet *loc, void *refcon) {
- LookupENodeExprActionParams *params;
- ENodeList *list;
-
- IRO_ASSERT(0, loc != NULL);
- IRO_ASSERT(0, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(0, params->proc != NULL);
- IRO_ASSERT(0, params->indirectType != NULL);
- IRO_ASSERT(0, params->list != NULL);
-
- list = *params->list = IRO_malloc(sizeof(ENodeList));
- list->node = NULL;
- list->next = NULL;
-
- if (!LocationSet_IsUnknown(loc) && LocationSetRepresentsSingleLocation(loc, NULL, NULL))
- CreateENodeForLocationSet(loc, &list->node, params->indirectType, params->proc);
-
- params->list = &list->next;
-}
-
-void PointerAnalysis_LookupENodePointerExpr(Object *proc, ENode *indirect, ENodeList **list) {
- LocationSetSet *set;
- LookupENodeExprActionParams params;
-
- IRO_ASSERT(0, indirect != NULL);
-
- if (indirect->pointsTo) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- EvalENodeExpr(set, proc, indirect, NULL, NULL, NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.indirectType = indirect->rtype;
- params.list = list;
-
- LocationSetSet_ForEach(set, LookupENodeExprAction, &params);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROListNode **list) {
- LocationSetSet *set;
- LookupLinearExprActionParams params;
-
- if (pointsTo) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- EvalVariable(set, proc, var, pointsTo, NULL, NULL, NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.indirectType = var->object->type;
- params.list = list;
-
- LocationSetSet_ForEach(set, LookupLinearExprAction, &params);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-void PointerAnalysis_LookupVariableIntoENodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, ENodeList **list) {
- LocationSetSet *set;
- LookupENodeExprActionParams params;
-
- if (pointsTo) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- EvalVariable(set, proc, var, pointsTo, NULL, NULL, NULL);
-
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.indirectType = var->object->type;
- params.list = list;
-
- LocationSetSet_ForEach(set, LookupENodeExprAction, &params);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct GetFunctionDepsOrKillsActionParams {
- Object *proc;
- PartialTransferFunction *ptf;
- IROLinear *funccall;
- ParamMappingFunction *map;
- ObjectList **list;
-} GetFunctionDepsOrKillsActionParams;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void GetFunctionDepsOrKillsAction(LocationSet *ls, void *refcon) {
- GetFunctionDepsOrKillsActionParams *params;
- ObjectList *list;
- PAMemoryBlock *block;
- ExtendedParam *ep;
- ObjectSet *objSet;
- PALocalVar *local;
- Object *obj;
-
- IRO_ASSERT(7204, ls != NULL);
- IRO_ASSERT(7205, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(7209, params->proc != NULL);
- IRO_ASSERT(7210, params->ptf != NULL);
- IRO_ASSERT(7211, params->funccall != NULL);
- IRO_ASSERT(7212, params->map == NULL || params->map != NULL);
- IRO_ASSERT(7213, params->list != NULL);
-
- list = *params->list = IRO_malloc(sizeof(ObjectList));
- list->object = NULL;
- list->next = NULL;
-
- if (!LocationSet_IsUnknown(ls) && (block = LocationSet_block(ls))) {
- obj = NULL;
- switch (PAMemoryBlock_kind(block)) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- if ((ep = PAMemoryBlock_thing(block)) && (objSet = ExtendedParam_objectSet(ep))) {
- IRO_ASSERT(7232, obj == NULL);
- ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj);
- }
- break;
- case PAMEMORYBLOCKKIND_LOCALVAR:
- if ((local = PAMemoryBlock_thing(block))) {
- obj = GetLocalObject(local, &stUnknown, 0);
- if (ObjectIsAFunctionArgument(FunctionName, obj) && obj->u.var.realObj)
- obj = obj->u.var.realObj;
- }
- break;
- }
-
- list->object = obj;
- }
-
- params->list = &list->next;
-}
-
-static void GetFunctionDepsOrKillsAction2(PointsToEntry *pte, void *refcon) {
- GetFunctionDepsOrKillsActionParams *params;
- LocationSet *loc;
- PAMemoryBlock *block;
- LocationSetSet *set;
-
- IRO_ASSERT(7264, pte != NULL);
- IRO_ASSERT(7265, refcon != NULL);
-
- params = refcon;
-
- IRO_ASSERT(7269, params->proc != NULL);
- IRO_ASSERT(7270, params->ptf != NULL);
- IRO_ASSERT(7271, params->funccall != NULL);
- IRO_ASSERT(7272, params->map != NULL);
- IRO_ASSERT(7273, params->list != NULL);
-
- loc = PointsToEntry_loc(pte);
-
- IRO_ASSERT(7277, !LocationSet_IsUnknown(loc));
-
- if ((block = LocationSet_block(loc)) && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) {
- set = LocationSetSet_New();
- LocationSetSet_Init(set);
- GetActualLocsOfExtendedParam(set, loc, NULL, &stCallingContextStack, params->map, 0);
- LocationSetSet_ForEach(set, GetFunctionDepsOrKillsAction, params);
- LocationSetSet_Term(set);
- LocationSetSet_Delete(set);
- }
-}
-
-static void CreateFalseContext(Object *proc, IROLinear *funccall, PartialTransferFunction **resultPTF, ParamMappingFunction **resultMap) {
- IROLinear myFunccall;
- Boolean needVisit;
- ParamMappingFunction *map;
- PartialTransferFunction *ptf;
- StackElement *stackElement;
- ParamMappingFunction *map2;
- PartialTransferFunction *ptf2;
- StackElement *stackElement2;
-
- PointerAnalysis_Init();
- memset(&myFunccall, 0, sizeof(myFunccall));
- myFunccall.type = IROLinearFunccall;
-
- map = ParamMappingFunction_New();
- ParamMappingFunction_Init(map);
- RecordActuals(&myFunccall, FunctionName, map);
-
- needVisit = 0;
- ptf = GetPTF(map, FunctionName, &myFunccall, stUnknownPTF, &needVisit);
-
- stackElement = StackElement_New();
- StackElement_Init(stackElement, FunctionName, ptf, map, &myFunccall);
- Stack_sub_48A660(&stCallingContextStack, stackElement);
- StackElement_Term(stackElement);
- StackElement_Delete(stackElement);
-
- map2 = ParamMappingFunction_New();
- ParamMappingFunction_Init(map2);
- RecordActuals(funccall, proc, map2);
-
- if (FunctionName != proc) {
- needVisit = 0;
- ptf2 = GetPTF(map2, proc, funccall, ptf, &needVisit);
-
- stackElement2 = StackElement_New();
- StackElement_Init(stackElement2, proc, ptf2, map2, funccall);
- Stack_sub_48A660(&stCallingContextStack, stackElement2);
- StackElement_Term(stackElement2);
- StackElement_Delete(stackElement2);
- } else {
- ptf2 = stUnknownPTF;
- }
-
- *resultPTF = ptf2;
- *resultMap = map2;
-}
-
-static void DestroyFalseContext(Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map) {
- StackElement *element;
-
- if (FunctionName != proc) {
- element = Stack_sub_48A5B0(&stCallingContextStack);
- StackElement_Term(element);
- StackElement_Delete(element);
- }
-
- ParamMappingFunction_Term(map);
- ParamMappingFunction_Delete(map);
-
- element = Stack_sub_48A5B0(&stCallingContextStack);
- map = StackElement_map(element);
- ParamMappingFunction_Term(map);
- ParamMappingFunction_Delete(map);
- StackElement_Term(element);
- StackElement_Delete(element);
-
- PointerAnalysis_Term();
-}
-
-void PointerAnalysis_GetFunctionKills(Object *proc, IROLinear *funccall, ObjectList **list) {
- Boolean fail;
- PartialTransferFunction *ptf;
- LocationSetSet *set;
- GetFunctionDepsOrKillsActionParams params;
-
- IRO_ASSERT(7398, proc != NULL);
- IRO_ASSERT(7399, funccall != NULL);
- IRO_ASSERT(7400, funccall->type == IROLinearFunccall);
-
- if (!ObjectIsAFunction(proc))
- return;
-
- fail = !proc->u.func.ptfList || !(ptf = PTFList_FindFirst(proc->u.func.ptfList));
- if (!fail) {
- fail = !(set = PTF_sub_48D750(ptf));
- if (!fail) {
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptf = ptf;
- params.funccall = funccall;
- params.map = NULL;
- params.list = list;
- LocationSetSet_ForEach(set, GetFunctionDepsOrKillsAction, &params);
- }
- }
-
- if (fail) {
- *list = IRO_malloc(sizeof(ObjectList));
- (*list)->object = NULL;
- (*list)->next = NULL;
- }
-}
-
-void PointerAnalysis_GetFunctionDependencies(Object *proc, IROLinear *funccall, ObjectList **list) {
- Boolean fail;
- PartialTransferFunction *ptf;
- ParamMappingFunction *map;
- PointsToFunction *finalPointsTo;
- GetFunctionDepsOrKillsActionParams params;
-
- IRO_ASSERT(7446, proc != NULL);
- IRO_ASSERT(7447, funccall != NULL);
- IRO_ASSERT(7448, funccall->type == IROLinearFunccall);
-
- if (!ObjectIsAFunction(proc))
- return;
-
- fail = !proc->u.func.ptfList || !PTFList_FindFirst(proc->u.func.ptfList);
- if (!fail) {
- CreateFalseContext(proc, funccall, &ptf, &map);
- fail = !ptf || !map || !(finalPointsTo = PartialTransferFunction_finalPointsToFn(ptf));
- if (!fail) {
- memset(&params, 0, sizeof(params));
- params.proc = proc;
- params.ptf = ptf;
- params.funccall = funccall;
- params.map = map;
- params.list = list;
- PointsToFunction_ForEach(finalPointsTo, GetFunctionDepsOrKillsAction2, &params);
- }
- DestroyFalseContext(proc, ptf, map);
- }
-
- if (fail) {
- *list = IRO_malloc(sizeof(ObjectList));
- (*list)->object = NULL;
- (*list)->next = NULL;
- }
-}
-
-void PointerAnalysis_PragmaMode(void) {
- if (cparamblkptr->preprocess) {
- skipendofline();
- return;
- }
-
- if (notendofline()) {
- if (plex() == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "addr")) {
- copts.opt_pointer_analysis_mode = 0;
- return;
- }
- if (!strcmp(tkidentifier->name, "ansi")) {
- copts.opt_pointer_analysis_mode = 1;
- return;
- }
- if (!strcmp(tkidentifier->name, "type")) {
- copts.opt_pointer_analysis_mode = 2;
- return;
- }
- }
-
- CPrep_Warning(CErrorStr105);
- skipendofline();
- return;
- }
-
- if (copts.warn_illpragma)
- CPrep_Warning(CErrorStr186);
- skipendofline();
-}
-
-typedef enum CreateNewParamObjects {
- CREATE_NEW_PARAM_OBJECTS_FALSE,
- CREATE_NEW_PARAM_OBJECTS_TRUE
-} CreateNewParamObjects;
-
-static void ParseLocationSet(LocationSet *loc, Type *rtype, Object *proc, CreateNewParamObjects createNewParamObjects, Boolean arg5, int arg6, Boolean *arg7, Boolean *resultFailed) {
- CInt64 field;
- UInt32 stride;
- PAMemoryBlock *block;
- PAMemoryBlock *restriction;
- Boolean failed;
- Boolean flag37;
- Boolean epFlag;
- Boolean anotherFlag;
- Boolean isUnknown;
-
- IRO_ASSERT(7552, loc != NULL);
- IRO_ASSERT(7553, rtype == NULL || rtype != NULL);
- IRO_ASSERT(7554, proc != NULL);
- IRO_ASSERT(7555, createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE);
- IRO_ASSERT(7556, resultFailed != NULL);
- IRO_ASSERT(7557, *resultFailed == false);
- IRO_ASSERT(7558, proc != NULL);
- IRO_ASSERT(7559, proc == NULL || ObjectIsAFunction(proc));
-
- failed = 0;
- isUnknown = 0;
- anotherFlag = 0;
- field = cint64_zero;
- stride = 0;
-
- tk = lex();
- if (tk == TK_IDENTIFIER) {
- if (!strcmp(tkidentifier->name, "__unknown")) {
- flag37 = 0;
- isUnknown = 1;
- tk = lookahead();
- if (tk == '(') {
- lex();
- tk = lex();
- if (tk != TK_IDENTIFIER) {
- CError_Error(CErrorStr107);
- failed = 1;
- }
- if (!failed) {
- PALocalVar *local;
- local = PALocalVar_New();
- PALocalVar_InitByName(local, tkidentifier->name);
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_LOCALVAR, local);
-
- tk = lex();
- if (tk != ')') {
- CError_Error(CErrorStr115);
- failed = 1;
- }
- if (!failed) {
- rtype = NULL;
- restriction = block;
- }
- }
- } else {
- rtype = NULL;
- restriction = NULL;
- }
- } else if (arg5 && !strcmp(tkidentifier->name, "__return_value")) {
- flag37 = 0;
- anotherFlag = 1;
- } else if (!strcmp(tkidentifier->name, "__unique_heap_allocation")) {
- PAHeapBlock *hb;
-
- flag37 = 0;
- hb = CreateUniqueHeapAlloc_sub_486420();
- InitUniqueHeapAlloc_sub_486410(hb, NULL);
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_HEAPBLOCK, hb);
- } else if (!strcmp(tkidentifier->name, "__parameter_representative")) {
- flag37 = 1;
- tk = lex();
-
- if (tk == '(') {
- tk = lex();
- if (tk != TK_INTCONST) {
- CError_Error(CErrorStr121);
- failed = 1;
- }
- if (!failed) {
- Object *obj;
- ObjectList *list;
- ExtendedParam *ep;
- obj = NULL;
- for (list = stParamObjs; list; list = list->next) {
- if ((obj = list->object) && (obj->u.var.uid == CInt64_GetULong(&tkintconst)))
- break;
- }
- if (!list)
- obj = NULL;
-
- if (!obj) {
- if (createNewParamObjects) {
- obj = IRO_malloc(sizeof(Object));
- memset(obj, 0, sizeof(Object));
- obj->datatype = DLOCAL;
- obj->extParam = NULL;
- obj->name = CParser_GetUniqueName();
- obj->type = TYPE(&stunsignedlong);
- obj->qual = 0;
- obj->u.var.info = NULL;
- obj->u.var.uid = CInt64_GetULong(&tkintconst);
-
- list = IRO_malloc(sizeof(ObjectList));
- list->next = stParamObjs;
- list->object = obj;
- stParamObjs = list;
-
- ep = CreateExtendedParam(NULL, NULL, obj, &epFlag);
- } else {
- char buf[64];
- sprintf(buf, "__parameter_representative(%" PRId32 ")", obj->u.var.uid);
- CError_Error(CErrorStr140, buf);
- failed = 1;
- }
- } else {
- ep = obj->extParam;
- IRO_ASSERT(7687, ep != NULL);
- }
-
- if (!failed) {
- tk = lex();
- if (tk != ')') {
- CError_Error(CErrorStr115);
- failed = 1;
- }
- }
- if (!failed) {
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_EXTENDEDPARAM, ep);
- }
- }
- }
- } else {
- Object *obj;
- NameSpace *nspace;
-
- obj = NULL;
- for (nspace = cscope_current; nspace; nspace = nspace->parent) {
- NameSpaceObjectList *chk;
- if ((chk = CScope_GetLocalObject(nspace, tkidentifier)) && chk->object->otype == OT_OBJECT) {
- if (notendofline()) {
- obj = OBJECT(chk->object);
- break;
- }
- }
- }
-
- if (!obj) {
- ObjectList *chk;
- for (chk = FunctionArguments(proc); chk; chk = chk->next) {
- if (chk->object && chk->object->name && chk->object->name->name && !strcmp(tkidentifier->name, chk->object->name->name)) {
- obj = chk->object;
- }
- }
- }
-
- if (obj) {
- PAMemoryBlockKind kind;
- void *thing;
-
- if (ObjectIsAnExtendedParamCandidate(obj)) {
- kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM;
- thing = CreateExtendedParam(NULL, NULL, obj, &epFlag);
- } else {
- kind = PAMEMORYBLOCKKIND_LOCALVAR;
- thing = PALocalVar_New();
- if (obj->name && obj->name->name && ObjectIsAFunctionArgument(proc, obj))
- PALocalVar_InitByName(thing, obj->name->name);
- else
- PALocalVar_InitByObject(thing, obj);
- }
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, kind, thing);
- rtype = CDecl_NewPointerType(obj->type);
- } else {
- CError_Error(CErrorStr140, tkidentifier->name);
- failed = 1;
- }
- }
- } else if (tk == TK_INTCONST) {
- flag37 = 0;
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_INT, &tkintconst);
- } else if (tk == '(') {
- ParseLocationSet(loc, rtype, proc, createNewParamObjects, arg5, 1, &anotherFlag, &failed);
- if (!failed) {
- tk = plex();
- if (tk != ')')
- CError_Error(CErrorStr115);
- failed = 1;
- }
- } else {
- CError_Error(CErrorStr121);
- failed = 1;
- }
-
- if (!failed && flag37) {
- tk = lookahead();
- if (tk == '[') {
- lex();
- if (rtype && IS_TYPE_POINTER(rtype) && IS_TYPE_POINTER(TPTR_TARGET(rtype))) {
- tk = lex();
- if (tk == ']') {
- if ((stride = rtype->size)) {
- CInt64 tmp;
- CInt64_SetLong(&tmp, stride);
- field = CInt64_Mod(field, tmp);
- }
- rtype = TPTR_TARGET(rtype);
- } else {
- CError_Error(CErrorStr125);
- }
- } else {
- CError_Error(CErrorStr148);
- }
- } else if (tk == '.') {
- lex();
- if (rtype && IS_TYPE_POINTER(rtype) && IS_TYPE_STRUCT(TPTR_TARGET(rtype))) {
- if (TPTR_TARGET(rtype)->size) {
- tk = lex();
- if (tk == TK_IDENTIFIER) {
- StructMember *member;
- if ((member = ismember(TYPE_STRUCT(TPTR_TARGET(rtype)), tkidentifier))) {
- CInt64_SetLong(&field, member->offset);
- rtype = CDecl_NewPointerType(member->type);
- } else {
- CError_Error(CErrorStr150, tkidentifier);
- }
- } else {
- CError_Error(CErrorStr107);
- }
- } else {
- CError_Error(CErrorStr136, TPTR_TARGET(rtype), 0);
- }
- } else {
- CError_Error(CErrorStr149);
- }
- }
- }
-
- if (!failed && !anotherFlag) {
- LocationSet_Term(loc);
- if (!isUnknown)
- LocationSet_InitKnown(loc, block, field, stride, rtype);
- else
- LocationSet_InitUnknown(loc, rtype, restriction, NULL);
- }
-
- *arg7 = anotherFlag;
- *resultFailed = failed;
-}
-
-static void ParseLocationSetSet(LocationSetSet *locs, Type *rtype, Object *proc, CreateNewParamObjects createNewParamObjects, Boolean *resultFailed) {
- Boolean failed;
-
- IRO_ASSERT(7892, locs != NULL);
- IRO_ASSERT(7893, rtype == NULL || rtype != NULL);
- IRO_ASSERT(7894, proc != NULL);
- IRO_ASSERT(7895, createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE);
- IRO_ASSERT(7896, resultFailed != NULL);
- IRO_ASSERT(7897, *resultFailed == false);
- IRO_ASSERT(7898, proc != NULL);
- IRO_ASSERT(7899, proc == NULL || ObjectIsAFunction(proc));
-
- failed = 0;
-
- tk = lex();
- if (tk != '(') {
- CError_Error(CErrorStr114);
- failed = 1;
- }
-
- if (!failed) {
- Boolean anotherFlag;
-
- LocationSet *ls;
- ls = LocationSet_New();
- LocationSet_InitUnknown(ls, NULL, NULL, NULL);
-
- tk = lookahead();
- while (!failed && tk != ')') {
- ParseLocationSet(ls, rtype, proc, createNewParamObjects, 0, 0, &anotherFlag, &failed);
- if (!failed)
- LocationSetSet_Add(locs, ls);
-
- if (!failed) {
- tk = lookahead();
- if (tk == ',') {
- lex();
- tk = lookahead();
- } else if (tk != ')') {
- lex();
- CError_Error(CErrorStr121);
- failed = 1;
- }
- }
- }
-
- if (!failed)
- lex();
-
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- }
-
- *resultFailed = failed;
-}
-
-static Object *GetFunctionObjectFromDeclInfo(DeclInfo *di) {
- Object *proc;
-
- IRO_ASSERT(7953, di != NULL);
-
- if (di->storageclass != TK_TYPEDEF && IS_TYPE_FUNC(di->thetype)) {
- Boolean flag;
- proc = CDecl_GetFunctionObject(di, NULL, &flag, 1);
- if (flag)
- di->x64 = 1;
- } else {
- proc = NULL;
- }
-
- return proc;
-}
-
-void PointerAnalysis_ParseEntryPointsToSpecifier(DeclInfo *di) {
- Object *proc;
- Boolean failed;
- Boolean anotherFlag;
-
- IRO_ASSERT(7982, di != NULL);
-
- proc = GetFunctionObjectFromDeclInfo(di);
- if (proc) {
- IRO_ASSERT(7987, proc == NULL || ObjectIsAFunction(proc));
-
- tk = lex();
- IRO_ASSERT(7996, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"entry_points_to") == 0);
-
- failed = 0;
-
- tk = lex();
- if (tk != '(') {
- CError_Error(CErrorStr114);
- failed = 1;
- }
-
- if (!failed) {
- LocationSet *ls;
- ls = LocationSet_New();
- LocationSet_InitUnknown(ls, NULL, NULL, NULL);
- ParseLocationSet(ls, NULL, proc, CREATE_NEW_PARAM_OBJECTS_FALSE, 0, 0, &anotherFlag, &failed);
- if (!failed) {
- if ((tk = lex()) != ',') {
- CError_Error(CErrorStr116);
- failed = 1;
- }
- }
- if (!failed) {
- Type *type;
- Type *innerType;
- LocationSetSet *lss;
-
- type = LocationSet_rtype(ls);
- if (type && IS_TYPE_POINTER(type))
- innerType = TPTR_TARGET(type);
- else
- innerType = NULL;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- ParseLocationSetSet(lss, innerType, proc, CREATE_NEW_PARAM_OBJECTS_TRUE, &failed);
- if (!failed) {
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- failed = 1;
- }
- }
- if (!failed) {
- PartialTransferFunction *ptf;
- PointsToFunction *pointsToFunc;
- PointsToEntry *pte;
-
- if (!proc->u.func.ptfList) {
- proc->u.func.ptfList = PTFList_New();
- PTFList_Init(proc->u.func.ptfList);
- }
- ptf = PTFList_FindFirst(proc->u.func.ptfList);
- if (!ptf)
- ptf = AllocatePTF(proc, NULL, NULL);
-
- pointsToFunc = PartialTransferFunction_initialPointsToFn(ptf);
- pte = PointsToEntry_New();
- PointsToEntry_Init(pte, ls, lss);
- PointsToFunction_Add(pointsToFunc, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- }
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- }
- }
-}
-
-void PointerAnalysis_ParseExitPointsToSpecifier(DeclInfo *di) {
- Object *proc;
- Boolean failed;
- Boolean anotherFlag;
-
- IRO_ASSERT(8097, di != NULL);
-
- proc = GetFunctionObjectFromDeclInfo(di);
- if (proc) {
- IRO_ASSERT(8102, proc == NULL || ObjectIsAFunction(proc));
-
- tk = lex();
- IRO_ASSERT(8111, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"exit_points_to") == 0);
-
- failed = 0;
-
- tk = lex();
- if (tk != '(') {
- CError_Error(CErrorStr114);
- failed = 1;
- }
-
- if (!failed) {
- LocationSet *ls;
- ls = LocationSet_New();
- LocationSet_InitUnknown(ls, NULL, NULL, NULL);
- ParseLocationSet(ls, NULL, proc, CREATE_NEW_PARAM_OBJECTS_FALSE, 1, 0, &anotherFlag, &failed);
- if (!failed) {
- if ((tk = lex()) != ',') {
- CError_Error(CErrorStr116);
- failed = 1;
- }
- }
- if (!failed) {
- Type *type;
- Type *innerType;
- LocationSetSet *lss;
-
- type = LocationSet_rtype(ls);
- if (type && IS_TYPE_POINTER(type))
- innerType = TPTR_TARGET(type);
- else
- innerType = NULL;
-
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- ParseLocationSetSet(lss, innerType, proc, CREATE_NEW_PARAM_OBJECTS_FALSE, &failed);
- if (!failed) {
- if ((tk = lex()) != ')') {
- CError_Error(CErrorStr115);
- failed = 1;
- }
- }
- if (!failed) {
- PartialTransferFunction *ptf;
- PointsToFunction *pointsToFunc;
- PointsToEntry *pte;
-
- if (!proc->u.func.ptfList) {
- proc->u.func.ptfList = PTFList_New();
- PTFList_Init(proc->u.func.ptfList);
- }
- ptf = PTFList_FindFirst(proc->u.func.ptfList);
- if (!ptf)
- ptf = AllocatePTF(proc, NULL, NULL);
-
- pointsToFunc = PartialTransferFunction_finalPointsToFn(ptf);
- pte = PointsToEntry_New();
- if (anotherFlag)
- PointsToEntry_Init(pte, PartialTransferFunction_returnLocation(ptf), lss);
- else
- PointsToEntry_Init(pte, ls, lss);
- PointsToFunction_Add(pointsToFunc, pte);
- PointsToEntry_Term(pte);
- PointsToEntry_Delete(pte);
- }
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
- }
- }
-}
-
-void PointerAnalysis_ParseFunctionModifiesSpecifier(DeclInfo *di) {
- Object *proc;
- Boolean failed;
- LocationSetSet *lss;
- PartialTransferFunction *ptf;
- LocationSetSet *ptfLSS;
-
- IRO_ASSERT(8211, di != NULL);
-
- proc = GetFunctionObjectFromDeclInfo(di);
- if (proc) {
- IRO_ASSERT(8216, proc == NULL || ObjectIsAFunction(proc));
-
- tk = lex();
- IRO_ASSERT(8225, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"function_modifies") == 0);
-
- failed = 0;
- lss = LocationSetSet_New();
- LocationSetSet_Init(lss);
- ParseLocationSetSet(lss, NULL, proc, CREATE_NEW_PARAM_OBJECTS_FALSE, &failed);
- if (!failed) {
- if (!proc->u.func.ptfList) {
- proc->u.func.ptfList = PTFList_New();
- PTFList_Init(proc->u.func.ptfList);
- }
- ptf = PTFList_FindFirst(proc->u.func.ptfList);
- if (!ptf)
- ptf = AllocatePTF(proc, NULL, NULL);
- ptfLSS = PTF_sub_48D750(ptf);
- LocationSetSet_RemoveAll(ptfLSS);
- LocationSetSet_AddSet(ptfLSS, lss);
- }
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
-}
-
diff --git a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c b/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c
deleted file mode 100644
index 6e24e6f..0000000
--- a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c
+++ /dev/null
@@ -1,2736 +0,0 @@
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/CError.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-// TODO: this should really be elsewhere (but where?)
-CW_INLINE UInt32 gcd(UInt32 a, UInt32 b) {
- UInt32 chk;
-
- if (!a)
- return b;
- if (!b)
- return a;
-
- while (1) {
- chk = a % b;
- if (!chk)
- return b;
- a = b;
- b = chk;
- }
-}
-
-// #define IRO_DEBUG
-
-typedef struct ExtendedParamSet ExtendedParamSet;
-typedef struct LocationSet LocationSet;
-typedef struct LocationSetSet LocationSetSet;
-typedef struct ObjectSet ObjectSet;
-typedef struct PAHeapBlock PAHeapBlock;
-typedef struct PALocalVar PALocalVar;
-typedef struct PAMemoryBlock PAMemoryBlock;
-typedef struct ParamMapping ParamMapping;
-typedef struct ParamMappingFunction ParamMappingFunction;
-typedef struct PartialTransferFunction PartialTransferFunction;
-typedef struct PointsToEntry PointsToEntry;
-// typedef struct PointsToFunction PointsToFunction;
-typedef struct Stack Stack;
-typedef struct StackElement StackElement;
-
-typedef UInt32 uint32;
-
-void __assertion_failed(char *expr, char *filename, int line);
-
-#ifdef IRO_DEBUG
-#define IRO_ASSERT(line, expr) \
- do { \
- if (!(expr)) { \
- __assertion_failed(#expr, __FILE__, line); \
- } \
- } while (0);
-
-#define IRO_DEBUG_CLEAR(obj, type) \
- memset((obj), 0xFF, sizeof(type))
-#else
-#define IRO_ASSERT(line, expr) ((void) 0)
-#define IRO_DEBUG_CLEAR(obj, type) ((void) 0)
-#endif
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-struct StackElement {
- Object *proc;
- PartialTransferFunction *ptf;
- ParamMappingFunction *map;
- IROLinear *funcCall;
-};
-
-struct Stack {
- StackElement *top;
- Stack *next;
-};
-
-struct ObjectSet {
- Object *proc;
- ObjectSet *otherProcs;
-};
-
-struct ExtendedParam {
- ObjectSet *objectSet;
- uint32 x4;
-};
-
-struct ExtendedParamSet {
- ExtendedParam *ep;
- ExtendedParamSet *otherEps;
-};
-
-struct PAHeapBlock {
- IROLinear *x0;
-};
-
-struct PALocalVar {
- Object *x0;
- char *x4;
-};
-
-typedef enum {
- PAMEMORYBLOCKKIND_INVALID,
- PAMEMORYBLOCKKIND_1,
- PAMEMORYBLOCKKIND_EXTENDEDPARAM,
- PAMEMORYBLOCKKIND_LOCALVAR,
- PAMEMORYBLOCKKIND_HEAPBLOCK,
- PAMEMORYBLOCKKIND_INT,
- PAMEMORYBLOCKKIND_6
-} PAMemoryBlockKind;
-
-struct PAMemoryBlock {
- PAMemoryBlockKind kind;
- union {
- ExtendedParam *ep;
- PALocalVar *localvar;
- PAHeapBlock *heapblock;
- CInt64 intval;
- void *x6;
- } u;
-};
-
-struct LocationSet {
- PAMemoryBlock *block;
- Type *rtype;
- union {
- struct {
- CInt64 field;
- UInt32 stride;
- } known;
- struct {
- PAMemoryBlock *restriction;
- LocationSet *bitfieldOf;
- } unknown;
- } u;
-};
-
-struct LocationSetSet {
- LocationSet *loc;
- LocationSetSet *otherLocs;
- UInt8 count;
-};
-
-struct ParamMapping {
- IROLinear *actual;
- Object *formal;
- ExtendedParam *extended;
-};
-
-struct ParamMappingFunction {
- ParamMapping *mapping;
- ParamMappingFunction *otherMappings;
-};
-
-struct PointsToEntry {
- LocationSet *loc;
- LocationSetSet *locs;
-};
-
-struct PointsToFunction {
- PointsToEntry *pte;
- PointsToFunction *otherPtes;
-};
-
-struct PartialTransferFunction {
- PointsToFunction *initialPointsToFn;
- PointsToFunction *finalPointsToFn;
- LocationSetSet *funcModifies;
- LocationSet *returnLocation;
- Boolean x10;
- struct {
- IROLinear *nd;
- PartialTransferFunction *ptf;
- } context;
-};
-
-struct PTFList {
- PartialTransferFunction *ptf;
- PTFList *otherPTFs;
-};
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// TODO: how many of these are actually in IroPointerAnalysis.c?
-static uint32 stExtendedParamNum;
-static PartialTransferFunction *stUnknownPTF;
-static uint32 stIndentationLevel;
-static UInt8 stTabs[0x2C]; // unused mystery object
-static Stack *stCallingContextStack;
-static ObjectList *stParamObjs;
-static jmp_buf stAbortPointerAnalysis;
-static Object stUnknown;
-static Object *stCurrentProc;
-static ExtendedParamSet *stExtParamSet;
-static PTFList *stPTFList;
-static uint32 stMaxPassCount;
-// TODO: stEvalProcActionParams
-static IRONode *stExceptionFNode;
-
-static PAMemoryBlock stDummyMemoryBlock = {
- PAMEMORYBLOCKKIND_1
-};
-static PAMemoryBlock *stUnknownMb = &stDummyMemoryBlock;
-
-static LocationSet stDummyLocationSet = {
- &stDummyMemoryBlock
-};
-
-static LocationSet *stUnknownLs = &stDummyLocationSet;
-
-// forward decls
-CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr);
-CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList);
-CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList);
-CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src);
-CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls);
-CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss);
-CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src);
-CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf);
-CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src);
-CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc);
-CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src);
-CW_INLINE void PTFList_RemoveAll(PTFList *ptfList);
-
-CW_INLINE StackElement *StackElement_New(void) {
- StackElement *stackElement = IRO_malloc(sizeof(StackElement));
- IRO_ASSERT(103, stackElement != NULL);
-#ifdef IRO_DEBUG
- stackElement->proc = NULL;
- stackElement->ptf = NULL;
- stackElement->map = NULL;
- stackElement->funcCall = NULL;
-#endif
- return stackElement;
-}
-
-CW_INLINE void StackElement_Delete(StackElement *stackElement) {
- IRO_ASSERT(117, stackElement != NULL);
- IRO_ASSERT(118, stackElement->proc == NULL);
- IRO_ASSERT(119, stackElement->ptf == NULL);
- IRO_ASSERT(120, stackElement->map == NULL);
- IRO_ASSERT(121, stackElement->funcCall == NULL);
- IRO_DEBUG_CLEAR(stackElement, sizeof(StackElement));
- IRO_free(stackElement);
-}
-
-CW_INLINE void StackElement_Init(StackElement *stackElement, Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map, IROLinear *funcCall) {
- IRO_ASSERT(131, stackElement != NULL);
- IRO_ASSERT(132, proc != NULL);
- IRO_ASSERT(133, ptf != NULL);
- IRO_ASSERT(134, map != NULL);
- IRO_ASSERT(135, funcCall != NULL);
- stackElement->proc = proc;
- stackElement->ptf = ptf;
- stackElement->map = map;
- stackElement->funcCall = funcCall;
-}
-
-CW_INLINE void StackElement_Copy(StackElement *dest, StackElement *src) {
- IRO_ASSERT(145, dest != NULL);
- IRO_ASSERT(146, src != NULL);
- StackElement_Init(dest, src->proc, src->ptf, src->map, src->funcCall);
-}
-
-CW_INLINE void StackElement_Term(StackElement *stackElement) {
- IRO_ASSERT(156, stackElement != NULL);
-#ifdef IRO_DEBUG
- stackElement->proc = NULL;
- stackElement->ptf = NULL;
- stackElement->map = NULL;
- stackElement->funcCall = NULL;
-#endif
-}
-
-CW_INLINE void *StackElement_sub_48A780(StackElement *stackElement) {
- IRO_ASSERT(213, stackElement != NULL);
- return stackElement->proc;
-}
-
-CW_INLINE Boolean StackRelated_sub_48A760(void *key1, void *key2) {
- IRO_ASSERT(220, key1 != NULL);
- IRO_ASSERT(221, key2 != NULL);
- return key1 == key2;
-}
-
-CW_INLINE Object *StackElement_proc(StackElement *stackElement) {
- IRO_ASSERT(228, stackElement != NULL);
- return stackElement->proc;
-}
-
-CW_INLINE PartialTransferFunction *StackElement_ptf(StackElement *stackElement) {
- IRO_ASSERT(235, stackElement != NULL);
- return stackElement->ptf;
-}
-
-CW_INLINE ParamMappingFunction *StackElement_map(StackElement *stackElement) {
- IRO_ASSERT(242, stackElement != NULL);
- return stackElement->map;
-}
-
-CW_INLINE IROLinear *StackElement_funcCall(StackElement *stackElement) {
- IRO_ASSERT(249, stackElement != NULL);
- return stackElement->funcCall;
-}
-
-CW_INLINE Stack *Stack_New(void) {
- Stack *stack = IRO_malloc(sizeof(Stack));
- IRO_ASSERT(265, stack != NULL);
-#ifdef IRO_DEBUG
- stack->top = NULL;
- stack->next = NULL;
-#endif
- return stack;
-}
-
-CW_INLINE void Stack_Delete(Stack *stack) {
- IRO_ASSERT(277, stack != NULL);
- IRO_ASSERT(278, stack->top == NULL);
- IRO_ASSERT(279, stack->next == NULL);
- IRO_DEBUG_CLEAR(stack, sizeof(Stack));
- IRO_free(stack);
-}
-
-CW_INLINE void Stack_Init(Stack *stack) {
- IRO_ASSERT(289, stack != NULL);
- stack->top = NULL;
- stack->next = NULL;
-}
-
-CW_INLINE void Stack_Term(Stack **stackPtr) {
- StackElement *stackElement;
-
- IRO_ASSERT(299, stackPtr != NULL);
- IRO_ASSERT(300, *stackPtr != NULL);
-
- while ((*stackPtr)->top) {
- stackElement = Stack_sub_48A5B0(stackPtr);
- StackElement_Term(stackElement);
- StackElement_Delete(stackElement);
- }
-}
-
-CW_INLINE void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) {
- StackElement *newElement;
- Stack *newStack;
-
- IRO_ASSERT(315, stackPtr != NULL);
- IRO_ASSERT(316, *stackPtr != NULL);
-
- newElement = StackElement_New();
- StackElement_Copy(newElement, stackElement);
-
- newStack = Stack_New();
- newStack->top = newElement;
- newStack->next = *stackPtr;
- *stackPtr = newStack;
-}
-
-CW_INLINE StackElement *Stack_Top(Stack **stackPtr) {
- IRO_ASSERT(331, stackPtr != NULL);
- IRO_ASSERT(332, *stackPtr != NULL);
-
- return (*stackPtr)->top;
-}
-
-CW_INLINE Stack *Stack_Next(Stack **stackPtr) {
- IRO_ASSERT(343, stackPtr != NULL);
- IRO_ASSERT(344, *stackPtr != NULL);
-
- return (*stackPtr)->next;
-}
-
-CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr) {
- StackElement *stackElement;
-
- IRO_ASSERT(357, stackPtr != NULL);
- IRO_ASSERT(358, *stackPtr != NULL);
-
- stackElement = (*stackPtr)->top;
- if (stackElement) {
- Stack *next = (*stackPtr)->next;
- (*stackPtr)->top = NULL;
- (*stackPtr)->next = NULL;
- Stack_Delete(*stackPtr);
- *stackPtr = next;
- }
-
- return stackElement;
-}
-
-CW_INLINE StackElement *Stack_sub_48A710(Stack **stackPtr, void *key) {
- Stack *stack;
-
- IRO_ASSERT(379, stackPtr != NULL);
- IRO_ASSERT(380, key != NULL);
-
- for (stack = *stackPtr; stack; stack = stack->next) {
- if (stack->top) {
- if (StackRelated_sub_48A760(StackElement_sub_48A780(stack->top), key))
- return stack->top;
- }
- }
-
- return NULL;
-}
-
-CW_INLINE ObjectSet *ObjectSet_New(void) {
- ObjectSet *procList;
-
- procList = IRO_malloc(sizeof(ObjectSet));
- IRO_ASSERT(439, procList != NULL);
-#ifdef IRO_DEBUG
- procList->proc = NULL;
- procList->otherProcs = NULL;
-#endif
- return procList;
-}
-
-CW_INLINE void ObjectSet_Delete(ObjectSet *procList) {
- IRO_ASSERT(451, procList != NULL);
- IRO_ASSERT(452, procList->proc == NULL);
- IRO_ASSERT(453, procList->otherProcs == NULL);
- IRO_DEBUG_CLEAR(procList, sizeof(ObjectSet));
- IRO_free(procList);
-}
-
-CW_INLINE void ObjectSet_Init(ObjectSet *procList) {
- IRO_ASSERT(463, procList != NULL);
- procList->proc = NULL;
- procList->otherProcs = NULL;
-}
-
-CW_INLINE void ObjectSet_Term(ObjectSet *procList) {
- IRO_ASSERT(481, procList != NULL);
- ObjectSet_RemoveAll(procList);
-#ifdef IRO_DEBUG
- procList->proc = NULL;
- procList->otherProcs = NULL;
-#endif
-}
-
-CW_INLINE void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void *), void *refcon) {
- IRO_ASSERT(528, procList != NULL);
- IRO_ASSERT(529, action != NULL);
- IRO_ASSERT(530, refcon == NULL || refcon != NULL);
-
- while (procList && procList->proc) {
- action(procList->proc, refcon);
- procList = procList->otherProcs;
- }
-}
-
-CW_INLINE Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) {
- IRO_ASSERT(540, procList != NULL);
- IRO_ASSERT(541, proc != NULL);
- while (procList && procList->proc) {
- if (procList->proc == proc)
- return procList->proc;
- procList = procList->otherProcs;
- }
- return NULL;
-}
-
-CW_INLINE Object *ObjectSet_FindFirst(ObjectSet *procList) {
- IRO_ASSERT(552, procList != NULL);
- return procList->proc;
-}
-
-CW_INLINE int ObjectSet_Count(ObjectSet *procList) {
- int count;
-
- IRO_ASSERT(561, procList != NULL);
-
- count = 0;
- while (procList && procList->proc) {
- count++;
- procList = procList->otherProcs;
- }
-
- return count;
-}
-
-CW_INLINE void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) {
- ObjectSet *newProcList;
-
- IRO_ASSERT(574, procList != NULL);
- IRO_ASSERT(575, proc != NULL);
-
- if (procList->proc) {
- newProcList = ObjectSet_New();
- ObjectSet_Init(newProcList);
- newProcList->proc = procList->proc;
- newProcList->otherProcs = procList->otherProcs;
- procList->otherProcs = newProcList;
- }
-
- procList->proc = proc;
-}
-
-CW_INLINE void ObjectSet_sub_4867D0(ObjectSet *procList, Object *proc) {
- IRO_ASSERT(592, procList != NULL);
- IRO_ASSERT(593, proc != NULL);
-
- if (!ObjectSet_sub_485020(procList, proc))
- ObjectSet_sub_486800(procList, proc);
-}
-
-CW_INLINE void ObjectSet_Remove(ObjectSet *procList, Object *proc) {
- ObjectSet *prev;
- ObjectSet *tmp;
-
- IRO_ASSERT(605, procList != NULL);
- IRO_ASSERT(606, proc != NULL);
-
- prev = NULL;
- while (procList && procList->proc) {
- if (procList->proc == proc) {
- if (!prev) {
- if (procList->otherProcs == NULL) {
- procList->proc = NULL;
- } else {
- tmp = procList->otherProcs;
- procList->proc = procList->otherProcs->proc;
- procList->otherProcs = procList->otherProcs->otherProcs;
- tmp->proc = NULL;
- tmp->otherProcs = NULL;
- ObjectSet_Term(tmp);
- ObjectSet_Delete(tmp);
- }
- } else {
- prev->otherProcs = procList->otherProcs;
- procList->proc = NULL;
- procList->otherProcs = NULL;
- ObjectSet_Term(procList);
- ObjectSet_Delete(procList);
- }
- return;
- }
- prev = procList;
- procList = procList->otherProcs;
- }
-}
-
-CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList) {
- IRO_ASSERT(645, procList != NULL);
-
- while (procList && procList->proc)
- ObjectSet_Remove(procList, procList->proc);
-}
-
-CW_INLINE void ObjectSet_AddSetAction(Object *proc, void *refcon) {
- IRO_ASSERT(655, proc != NULL);
- IRO_ASSERT(656, refcon != NULL);
-
- ObjectSet_sub_4867D0(refcon, proc);
-}
-
-CW_INLINE void ObjectSet_SimpleAddSetAction(Object *proc, void *refcon) {
- IRO_ASSERT(663, proc != NULL);
- IRO_ASSERT(664, refcon != NULL);
-
- ObjectSet_sub_486800(refcon, proc);
-}
-
-CW_INLINE void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) {
- IRO_ASSERT(671, dest != NULL);
- IRO_ASSERT(672, src != NULL);
-
- if (dest->proc)
- ObjectSet_ForEach(src, ObjectSet_AddSetAction, dest);
- else
- ObjectSet_ForEach(src, ObjectSet_SimpleAddSetAction, dest);
-}
-
-CW_INLINE void ObjectSet_RemoveSetAction(Object *proc, void *refcon) {
- IRO_ASSERT(682, proc != NULL);
- IRO_ASSERT(683, refcon != NULL);
-
- ObjectSet_Remove(refcon, proc);
-}
-
-CW_INLINE void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) {
- IRO_ASSERT(690, dest != NULL);
- IRO_ASSERT(691, src != NULL);
-
- ObjectSet_ForEach(src, ObjectSet_RemoveSetAction, dest);
-}
-
-CW_INLINE Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) {
- ObjectSet *scan;
-
- IRO_ASSERT(700, os1 != NULL);
- IRO_ASSERT(701, os2 != NULL);
-
- if (os1 == os2)
- return 1;
-
- for (scan = os1; scan && scan->proc; scan = scan->otherProcs) {
- if (!ObjectSet_sub_485020(os2, scan->proc))
- return 0;
- }
-
- for (scan = os2; scan && scan->proc; scan = scan->otherProcs) {
- if (!ObjectSet_sub_485020(os1, scan->proc))
- return 0;
- }
-
- return 1;
-}
-
-CW_INLINE ExtendedParam *ExtendedParam_New(void) {
- ExtendedParam *ep = IRO_malloc(sizeof(ExtendedParam));
-
- IRO_ASSERT(755, ep != NULL);
-#ifdef IRO_DEBUG
- ep->objectSet = NULL;
-#endif
- return ep;
-}
-
-CW_INLINE void ExtendedParam_Delete(ExtendedParam *ep) {
- IRO_ASSERT(762, ep != NULL);
- IRO_ASSERT(763, ep->objectSet == NULL);
- IRO_DEBUG_CLEAR(ep, sizeof(ExtendedParam));
- IRO_free(ep);
-}
-
-CW_INLINE void ExtendedParam_Init(ExtendedParam *ep, Object *obj) {
- IRO_ASSERT(777, ep != NULL);
- IRO_ASSERT(778, obj != NULL);
- IRO_ASSERT(779, obj->extParam == NULL);
- IRO_ASSERT(780, stExtendedParamNum < ((uint32) -1) / 2 - 1);
-
- ep->objectSet = ObjectSet_New();
- ObjectSet_Init(ep->objectSet);
- ObjectSet_sub_4867D0(ep->objectSet, obj);
- obj->extParam = ep;
-
- ep->x4 = stExtendedParamNum++;
-}
-
-CW_INLINE void ExtendedParam_TermAction(Object *obj, void *refcon) {
- obj->extParam = NULL;
-}
-
-CW_INLINE void ExtendedParam_Term(ExtendedParam *ep) {
- IRO_ASSERT(800, ep != NULL);
-
- ObjectSet_ForEach(ep->objectSet, ExtendedParam_TermAction, NULL);
- ObjectSet_Term(ep->objectSet);
- ObjectSet_Delete(ep->objectSet);
-#ifdef IRO_DEBUG
- ep->objectSet = NULL;
-#endif
-}
-
-CW_INLINE Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) {
- IRO_ASSERT(841, ep1 != NULL);
- IRO_ASSERT(842, ep2 != NULL);
- IRO_ASSERT(843, ep1->objectSet != NULL);
- IRO_ASSERT(844, ep2->objectSet != NULL);
-
- if (ep1 == ep2)
- return 1;
-
- return ep1->x4 == ep2->x4 && ObjectSet_sub_484FA0(ep1->objectSet, ep2->objectSet);
-}
-
-CW_INLINE ExtendedParam *ExtendedParam_FindByObject(Object *obj) {
- IRO_ASSERT(856, obj != NULL);
-
- return obj->extParam;
-}
-
-CW_INLINE void ExtendedParam_sub_4867B0(ExtendedParam *ep, Object *obj) {
- IRO_ASSERT(863, ep != NULL);
- IRO_ASSERT(864, ep->objectSet != NULL);
- IRO_ASSERT(865, obj != NULL);
-
- ObjectSet_sub_4867D0(ep->objectSet, obj);
- obj->extParam = ep;
-}
-
-CW_INLINE void ExtendedParam_RemoveObjectSetAction(Object *object, void *refcon) {
- object->extParam = NULL;
-}
-
-CW_INLINE void EP_sub_48C850(ExtendedParam *ep, ObjectSet *objSet) {
- IRO_ASSERT(888, ep != NULL);
- IRO_ASSERT(889, ep->objectSet != NULL);
- IRO_ASSERT(890, objSet != NULL);
-
- ObjectSet_removeiter_sub_48C890(ep->objectSet, objSet);
- ObjectSet_ForEach(objSet, ExtendedParam_RemoveObjectSetAction, NULL);
-}
-
-CW_INLINE ObjectSet *ExtendedParam_objectSet(ExtendedParam *ep) {
- IRO_ASSERT(898, ep != NULL);
-
- return ep->objectSet;
-}
-
-CW_INLINE uint32 ExtendedParam_sub_489110(ExtendedParam *ep) {
- IRO_ASSERT(905, ep != NULL);
-
- return ep->x4;
-}
-
-CW_INLINE ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) {
- ExtendedParamSet *epList = IRO_malloc(sizeof(ExtendedParamSet));
-
- IRO_ASSERT(924, epList != NULL);
-#ifdef IRO_DEBUG
- epList->ep = NULL;
- epList->otherEps = NULL;
-#endif
- return epList;
-}
-
-CW_INLINE void FreesExtParamSet_sub_48CAE0(ExtendedParamSet *epList) {
- IRO_ASSERT(936, epList != NULL);
- IRO_ASSERT(937, epList->ep == NULL);
- IRO_ASSERT(938, epList->otherEps == NULL);
- IRO_DEBUG_CLEAR(epList, sizeof(ExtendedParamSet));
- IRO_free(epList);
-}
-
-CW_INLINE void InitsExtParamSet_sub_4876A0(ExtendedParamSet *epList) {
- IRO_ASSERT(948, epList != NULL);
- epList->ep = NULL;
- epList->otherEps = NULL;
-}
-
-CW_INLINE void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) {
- IRO_ASSERT(966, epList != NULL);
- ExtendedParamSet_RemoveAll(epList);
-#ifdef IRO_DEBUG
- epList->ep = NULL;
- epList->otherEps = NULL;
-#endif
-}
-
-CW_INLINE void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*action)(ExtendedParam *, void *), void *refcon) {
- IRO_ASSERT(1010, epList != NULL);
- IRO_ASSERT(1011, action != NULL);
-
- while (epList && epList->ep) {
- action(epList->ep, refcon);
- epList = epList->otherEps;
- }
-}
-
-CW_INLINE ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedParam *ep) {
- IRO_ASSERT(1022, epList != NULL);
- IRO_ASSERT(1023, ep != NULL);
-
- while (epList && epList->ep) {
- if (epList->ep == ep)
- return epList->ep;
- epList = epList->otherEps;
- }
-
- return NULL;
-}
-
-CW_INLINE void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) {
- IRO_ASSERT(1056, epList != NULL);
- IRO_ASSERT(1057, ep != NULL);
-
- if (epList->ep) {
- ExtendedParamSet *newSet = AllocsExtParamSet_sub_4876C0();
- InitsExtParamSet_sub_4876A0(newSet);
- newSet->ep = epList->ep;
- newSet->otherEps = epList->otherEps;
- epList->otherEps = newSet;
- }
-
- epList->ep = ep;
-}
-
-CW_INLINE void ExtParamSet_sub_487630(ExtendedParamSet *epList, ExtendedParam *ep) {
- IRO_ASSERT(1076, epList != NULL);
- IRO_ASSERT(1077, ep != NULL);
-
- if (!ExtParamSet_sub_4876D0(epList, ep))
- ExtParamSet_sub_487660(epList, ep);
-}
-
-CW_INLINE void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) {
- ExtendedParamSet *prev;
- ExtendedParamSet *tmp;
-
- IRO_ASSERT(1089, epList != NULL);
- IRO_ASSERT(1090, ep != NULL);
-
- prev = NULL;
- while (epList && epList->ep) {
- if (epList->ep == ep) {
- if (!prev) {
- if (epList->otherEps == NULL) {
- epList->ep = NULL;
- } else {
- tmp = epList->otherEps;
- epList->ep = epList->otherEps->ep;
- epList->otherEps = epList->otherEps->otherEps;
- tmp->ep = NULL;
- tmp->otherEps = NULL;
- TermsExtParamSet_sub_48CB00(tmp);
- FreesExtParamSet_sub_48CAE0(tmp);
- }
- } else {
- prev->otherEps = epList->otherEps;
- epList->ep = NULL;
- epList->otherEps = NULL;
- TermsExtParamSet_sub_48CB00(epList);
- FreesExtParamSet_sub_48CAE0(epList);
- }
- return;
- }
- prev = epList;
- epList = epList->otherEps;
- }
-}
-
-CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) {
- IRO_ASSERT(1129, epList != NULL);
-
- while (epList && epList->ep)
- ExtendedParamSet_Remove(epList, epList->ep);
-}
-
-CW_INLINE PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) {
- PAHeapBlock *hb = IRO_malloc(sizeof(PAHeapBlock));
-
- IRO_ASSERT(1225, hb != NULL);
-#ifdef IRO_DEBUG
- hb->parent = NULL;
-#endif
- return hb;
-}
-
-CW_INLINE void InitUniqueHeapAlloc_sub_486410(PAHeapBlock *hb, IROLinear *nd) {
- IRO_ASSERT(1247, hb != NULL);
-
- hb->x0 = nd;
-}
-
-CW_INLINE Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) {
- IRO_ASSERT(1296, hb1 != NULL);
- IRO_ASSERT(1297, hb2 != NULL);
-
- return (hb1 == hb2) || (hb1->x0 == hb2->x0);
-}
-
-CW_INLINE PALocalVar *PALocalVar_New(void) {
- PALocalVar *local = IRO_malloc(sizeof(PALocalVar));
-
- IRO_ASSERT(1333, local != NULL);
-#ifdef IRO_DEBUG
- local->parent = NULL;
- local->nextSibling = NULL;
-#endif
- return local;
-}
-
-CW_INLINE void PALocalVar_InitByObject(PALocalVar *local, Object *obj) {
- IRO_ASSERT(1357, local != NULL);
- IRO_ASSERT(1358, obj != NULL);
-
- local->x0 = obj;
- if (obj->name && obj->name->name) {
- local->x4 = IRO_malloc(strlen(obj->name->name) + 1);
- strcpy(local->x4, obj->name->name);
- } else {
- local->x4 = NULL;
- }
-}
-
-CW_INLINE void PALocalVar_InitByName(PALocalVar *local, char *name) {
- IRO_ASSERT(1372, local != NULL);
- IRO_ASSERT(1373, name != NULL);
-
- local->x0 = NULL;
- local->x4 = IRO_malloc(strlen(name) + 1);
- strcpy(local->x4, name);
-}
-
-CW_INLINE Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) {
- IRO_ASSERT(1419, local1 == NULL || local1 != NULL);
- IRO_ASSERT(1420, local2 == NULL || local2 != NULL);
-
- if (local1 == local2)
- return 1;
- if (!local1 || !local2)
- return 0;
-
- if (!local1->x0 || !local2->x0) {
- if (local1->x4)
- return local2->x4 && !strcmp(local1->x4, local2->x4);
- }
-
- return local1->x0 == local2->x0;
-}
-
-CW_INLINE void PALocalVar_SetSth_sub_4847C0(PALocalVar *local, Object *obj) {
- IRO_ASSERT(1436, local != NULL);
- IRO_ASSERT(1437, obj == NULL || obj != NULL);
-
- local->x0 = obj;
-}
-
-CW_INLINE Object *PALocalVar_Get0_sub_4847E0(PALocalVar *local) {
- IRO_ASSERT(1444, local != NULL);
- return local->x0;
-}
-
-CW_INLINE char *PALocalVar_Get4_sub_4847D0(PALocalVar *local) {
- IRO_ASSERT(1451, local != NULL);
- return local->x4;
-}
-
-CW_INLINE PAMemoryBlock *PAMemoryBlock_New(void) {
- PAMemoryBlock *mb = IRO_malloc(sizeof(PAMemoryBlock));
-
- IRO_ASSERT(1491, mb != NULL);
-#ifdef IRO_DEBUG
- mb->kind = PAMEMORYBLOCKKIND_INVALID;
-#endif
- return mb;
-}
-
-CW_INLINE void PAMemoryBlock_Delete(PAMemoryBlock *mb) {
- IRO_ASSERT(1502, mb != NULL);
- IRO_ASSERT(1503, mb->kind == PAMEMORYBLOCKKIND_INVALID);
- IRO_free(mb);
-}
-
-CW_INLINE void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void *thing) {
- IRO_ASSERT(1513, mb != NULL);
- IRO_ASSERT(1514, thing == NULL || thing != NULL);
-
- mb->kind = kind;
- switch (mb->kind) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- mb->u.ep = (ExtendedParam *) thing;
- break;
- case PAMEMORYBLOCKKIND_LOCALVAR:
- mb->u.localvar = (PALocalVar *) thing;
- break;
- case PAMEMORYBLOCKKIND_HEAPBLOCK:
- mb->u.heapblock = (PAHeapBlock *) thing;
- break;
- case PAMEMORYBLOCKKIND_INT:
- mb->u.intval = *((CInt64 *) thing);
- break;
- case PAMEMORYBLOCKKIND_6:
- mb->u.x6 = (void *) thing;
- break;
- default:
- CError_FATAL(1535);
- }
-}
-
-CW_INLINE void PAMemoryBlock_Term(PAMemoryBlock *mb) {
- IRO_ASSERT(1552, mb != NULL);
-
-#ifdef IRO_DEBUG
- mb->kind = PAMEMORYBLOCKKIND_INVALID;
-#endif
-}
-
-CW_INLINE Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) {
- IRO_ASSERT(1657, mb1 == NULL || mb1 != NULL);
- IRO_ASSERT(1658, mb2 == NULL || mb2 != NULL);
-
- if (mb1 == mb2)
- return 1;
-
- if (!mb1 || !mb2 || mb1->kind != mb2->kind)
- return 0;
-
- switch (mb1->kind) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- return ExtendedParams_Equal(mb1->u.ep, mb2->u.ep);
- case PAMEMORYBLOCKKIND_LOCALVAR:
- return PALocalVars_Equal(mb1->u.localvar, mb2->u.localvar);
- case PAMEMORYBLOCKKIND_HEAPBLOCK:
- return PAHeapBlocks_Equal(mb1->u.heapblock, mb2->u.heapblock);
- case PAMEMORYBLOCKKIND_INT:
- return CInt64_Equal(mb1->u.intval, mb2->u.intval);
- case PAMEMORYBLOCKKIND_6:
- return mb1->u.x6 == mb2->u.x6;
- default:
- CError_FATAL(1684);
- return 0;
- }
-}
-
-CW_INLINE PAMemoryBlockKind PAMemoryBlock_kind(PAMemoryBlock *mb) {
- IRO_ASSERT(1692, mb != NULL);
-
- return mb->kind;
-}
-
-CW_INLINE void *PAMemoryBlock_thing(PAMemoryBlock *mb) {
- IRO_ASSERT(1699, mb != NULL);
-
- switch (mb->kind) {
- case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
- return mb->u.ep;
- case PAMEMORYBLOCKKIND_LOCALVAR:
- return mb->u.localvar;
- case PAMEMORYBLOCKKIND_HEAPBLOCK:
- return mb->u.heapblock;
- case PAMEMORYBLOCKKIND_INT:
- return &mb->u.intval;
- case PAMEMORYBLOCKKIND_6:
- return mb->u.x6;
- default:
- CError_FATAL(1719);
- return NULL;
- }
-}
-
-CW_INLINE LocationSet *LocationSet_New(void) {
- LocationSet *ls = IRO_malloc(sizeof(LocationSet));
-
- IRO_ASSERT(1767, ls != NULL);
-#ifdef IRO_DEBUG
- ls->block = NULL;
- ls->rtype = NULL;
- ls->u.known.field = cint64_zero;
- ls->u.known.stride = 0;
-#endif
- return ls;
-}
-
-CW_INLINE void LocationSet_Delete(LocationSet *ls) {
- IRO_ASSERT(1781, ls != NULL);
- IRO_ASSERT(1782, ls != stUnknownLs);
- IRO_ASSERT(1783, ls->block == NULL);
- IRO_ASSERT(1784, CInt64_IsZero(&ls->u.known.field));
- IRO_ASSERT(1785, ls->u.known.stride == 0);
- IRO_ASSERT(1786, ls->rtype == NULL);
- IRO_DEBUG_CLEAR(ls, sizeof(LocationSet));
- IRO_free(ls);
-}
-
-CW_INLINE void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 field, UInt32 stride, Type *rtype) {
- IRO_ASSERT(1796, ls != NULL);
- IRO_ASSERT(1797, ls != stUnknownLs);
- IRO_ASSERT(1798, block != NULL);
- IRO_ASSERT(1799, rtype == NULL || rtype != NULL);
- ls->block = block;
- ls->rtype = rtype;
- ls->u.known.field = field;
- ls->u.known.stride = stride;
-}
-
-CW_INLINE void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
- IRO_ASSERT(1809, ls != NULL);
- IRO_ASSERT(1810, ls != stUnknownLs);
- IRO_ASSERT(1811, rtype == NULL || rtype != NULL);
- IRO_ASSERT(1812, restriction == NULL || restriction != NULL);
- IRO_ASSERT(1813, bitfieldOf == NULL || bitfieldOf != NULL);
-
- LocationSet_Copy(ls, stUnknownLs);
- ls->rtype = rtype;
- ls->u.unknown.restriction = restriction;
- if (bitfieldOf) {
- ls->u.unknown.bitfieldOf = LocationSet_New();
- LocationSet_Copy(ls->u.unknown.bitfieldOf, bitfieldOf);
- } else {
- ls->u.unknown.bitfieldOf = NULL;
- }
-}
-
-CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src) {
- IRO_ASSERT(1829, src != NULL);
- IRO_ASSERT(1830, dest != NULL);
-
- dest->block = src->block;
- dest->rtype = src->rtype;
-
- if (!LocationSet_IsUnknown(src)) {
- dest->u.known.field = src->u.known.field;
- dest->u.known.stride = src->u.known.stride;
- } else {
- dest->u.unknown.restriction = src->u.unknown.restriction;
- if (src->u.unknown.bitfieldOf != NULL) {
- dest->u.unknown.bitfieldOf = LocationSet_New();
- LocationSet_Copy(dest->u.unknown.bitfieldOf, src->u.unknown.bitfieldOf);
- } else {
- dest->u.unknown.bitfieldOf = NULL;
- }
- }
-}
-
-CW_INLINE void LocationSet_Term(LocationSet *ls) {
- IRO_ASSERT(1857, ls != NULL);
- IRO_ASSERT(1858, ls != stUnknownLs);
-
-#ifdef IRO_DEBUG
- if (LocationSet_IsUnknown(ls) && ls->u.unknown.bitfieldOf) {
- LocationSet_Term(ls->u.unknown.bitfieldOf);
- LocationSet_Delete(ls->u.unknown.bitfieldOf);
- }
- ls->block = NULL;
- ls->rtype = NULL;
- ls->u.known.field = cint64_zero;
- ls->u.known.stride = 0;
-#endif
-}
-
-CW_INLINE Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) {
- Boolean isUnknown1, isUnknown2;
- PAMemoryBlock *restriction1, *restriction2;
-
- IRO_ASSERT(1974, ls1 != NULL);
- IRO_ASSERT(1975, rtype1 == NULL || rtype1 != NULL);
- IRO_ASSERT(1976, ls2 != NULL);
- IRO_ASSERT(1977, rtype2 == NULL || rtype2 != NULL);
-
- if (ls1 == ls2)
- return 1;
-
- isUnknown1 = LocationSet_IsUnknown(ls1);
- if (isUnknown1)
- restriction1 = ls1->u.unknown.restriction;
- else
- restriction1 = NULL;
-
- isUnknown2 = LocationSet_IsUnknown(ls2);
- if (isUnknown2)
- restriction2 = ls2->u.unknown.restriction;
- else
- restriction2 = NULL;
-
- if (
- (isUnknown1 && !restriction1) ||
- (isUnknown2 && !restriction2) ||
- (isUnknown1 && isUnknown2 && MemoryBlocks_Equal(restriction1, restriction2))
- )
- return 1;
-
- if (isUnknown1 || isUnknown2)
- return 0;
-
- if (MemoryBlocks_Equal(ls1->block, ls2->block)) {
- UInt32 size1;
- UInt32 size2;
- UInt32 i;
- CInt64 work;
- CInt64 longgcd;
-
- if (rtype1)
- size1 = rtype1->size;
- else
- size1 = -1;
-
- if (rtype2)
- size2 = rtype2->size;
- else
- size2 = -1;
-
- if (ls1->u.known.stride == ls2->u.known.stride) {
- CInt64 longsize1;
- CInt64 longsize2;
- CInt64_SetULong(&longsize1, size1);
- CInt64_SetULong(&longsize2, size2);
-
- return CInt64_Equal(ls1->u.known.field, ls2->u.known.field) ||
- (CInt64_Less(ls1->u.known.field, ls2->u.known.field) && CInt64_Greater(CInt64_Add(ls1->u.known.field, longsize1), ls2->u.known.field)) ||
- (CInt64_Less(ls2->u.known.field, ls1->u.known.field) && CInt64_Greater(CInt64_Add(ls2->u.known.field, longsize2), ls1->u.known.field));
- } else {
- work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field);
- if (CInt64_IsNegative(&work))
- work = CInt64_Neg(work);
-
- CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride));
- if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
- return 1;
-
- if (size1 == -1)
- return 1;
-
- for (i = 1; i < size1; i++) {
- CInt64_SetLong(&work, i);
- work = CInt64_Add(work, ls1->u.known.field);
- work = CInt64_Sub(work, ls2->u.known.field);
- if (CInt64_IsNegative(&work))
- work = CInt64_Neg(work);
- if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
- return 1;
- }
-
- if (size2 == -1)
- return 1;
-
- for (i = 1; i < size2; i++) {
- CInt64_SetLong(&work, i);
- work = CInt64_Add(work, ls2->u.known.field);
- work = CInt64_Sub(work, ls1->u.known.field);
- if (CInt64_IsNegative(&work))
- work = CInt64_Neg(work);
- if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
- return 1;
- }
-
- return 0;
- }
- }
-
- return 0;
-}
-
-CW_INLINE Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) {
- IRO_ASSERT(2080, ls1 != NULL);
- IRO_ASSERT(2081, ls2 != NULL);
-
- return
- (ls1 == ls2) ||
- (
- (LocationSet_IsUnknown(ls1) && LocationSet_IsUnknown(ls2)) &&
- (MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction)) &&
- ((ls1->u.unknown.bitfieldOf == ls2->u.unknown.bitfieldOf) ||
- (ls1->u.unknown.bitfieldOf && ls2->u.unknown.bitfieldOf && LocationSets_Equal(ls1->u.unknown.bitfieldOf, ls2->u.unknown.bitfieldOf))) &&
- ((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size))
- ) ||
- (
- (!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) &&
- (ls1->u.known.stride == ls2->u.known.stride) &&
- ((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) &&
- CInt64_Equal(ls1->u.known.field, ls2->u.known.field) &&
- MemoryBlocks_Equal(ls1->block, ls2->block)
- );
-}
-
-CW_INLINE Boolean LocationSets_LookupCompatible(LocationSet *ls1, LocationSet *ls2) {
- IRO_ASSERT(2119, ls1 != NULL);
- IRO_ASSERT(2120, ls2 != NULL);
-
- if (
- (ls1 == ls2) ||
- (
- LocationSet_IsUnknown(ls1) &&
- LocationSet_IsUnknown(ls2) &&
- MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction) &&
- (ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size))
- ))
- return 1;
-
- if (
- (!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) &&
- (ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) &&
- MemoryBlocks_Equal(ls1->block, ls2->block)
- ) {
- CInt64 work;
- CInt64 longgcd;
-
- if (ls1->u.known.stride == ls2->u.known.stride)
- return CInt64_Equal(ls1->u.known.field, ls2->u.known.field);
-
- work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field);
- if (CInt64_IsNegative(&work))
- work = CInt64_Neg(work);
-
- CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride));
- return CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero);
- }
-
- return 0;
-}
-
-CW_INLINE Boolean LocationSet_Contains(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) {
- Boolean unknown1;
- Boolean unknown2;
- PAMemoryBlock *restriction2;
- PAMemoryBlock *restriction1;
- CInt64 longsize1;
- CInt64 longsize2;
-
- IRO_ASSERT(2168, ls1 != NULL);
- IRO_ASSERT(2169, ls2 != NULL);
- IRO_ASSERT(2170, rtype1 != NULL);
- IRO_ASSERT(2171, rtype2 != NULL);
-
- if (ls1 == ls2)
- return 1;
-
- unknown1 = LocationSet_IsUnknown(ls1);
- if (unknown1)
- restriction1 = ls1->u.unknown.restriction;
- else
- restriction1 = NULL;
-
- unknown2 = LocationSet_IsUnknown(ls2);
- if (unknown2)
- restriction2 = ls2->u.unknown.restriction;
- else
- restriction2 = NULL;
-
- if (unknown1)
- return !restriction1 || (unknown2 && MemoryBlocks_Equal(restriction2, restriction1));
-
- CInt64_SetULong(&longsize1, rtype1->size);
- CInt64_SetULong(&longsize2, rtype2->size);
-
- return
- !LocationSet_IsUnknown(ls2) &&
- (ls1->u.known.stride == 0) &&
- (ls2->u.known.stride == 0) &&
- rtype1->size >= rtype2->size &&
- CInt64_LessEqual(ls1->u.known.field, ls2->u.known.field) &&
- CInt64_GreaterEqual(CInt64_Add(ls1->u.known.field, longsize1), CInt64_Add(ls2->u.known.field, longsize2)) &&
- MemoryBlocks_Equal(ls1->block, ls2->block);
-}
-
-CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls) {
- IRO_ASSERT(2233, ls != NULL);
-
- return (ls == stUnknownLs) || (ls->block == stUnknownMb);
-}
-
-CW_INLINE Boolean LocationSet_sub_48AF30(LocationSet *ls) {
- return
- !LocationSet_IsUnknown(ls) &&
- (ls->u.known.stride == 0) &&
- CInt64_IsZero(&ls->u.known.field) &&
- PAMemoryBlock_kind(ls->block) == PAMEMORYBLOCKKIND_LOCALVAR &&
- !PAMemoryBlock_thing(ls->block);
-}
-
-CW_INLINE void LocationSet_SetRtype(LocationSet *ls, Type *rtype) {
- IRO_ASSERT(2263, ls != NULL);
- IRO_ASSERT(2264, ls != stUnknownLs);
- IRO_ASSERT(2265, rtype != NULL);
-
- ls->rtype = rtype;
-}
-
-CW_INLINE void SetsLocationSetField_sub_4851B0(LocationSet *ls, CInt64 field) {
- IRO_ASSERT(2272, ls != NULL);
- IRO_ASSERT(2273, !LocationSet_IsUnknown(ls));
-
- ls->u.known.field = field;
-}
-
-CW_INLINE void SetsLocationSetStride_sub_4852D0(LocationSet *ls, SInt32 stride) {
- IRO_ASSERT(2280, ls != NULL);
- IRO_ASSERT(2281, !LocationSet_IsUnknown(ls));
-
- ls->u.known.stride = stride;
-}
-
-CW_INLINE PAMemoryBlock *LocationSet_block(LocationSet *ls) {
- IRO_ASSERT(2298, ls != NULL);
-
- return ls->block;
-}
-
-CW_INLINE Type *LocationSet_rtype(LocationSet *ls) {
- IRO_ASSERT(2306, ls != NULL);
- IRO_ASSERT(2307, ls != stUnknownLs);
-
- return ls->rtype;
-}
-
-CW_INLINE CInt64 LocationSet_field(LocationSet *ls) {
- IRO_ASSERT(2314, ls != NULL);
- IRO_ASSERT(2315, !LocationSet_IsUnknown(ls));
-
- return ls->u.known.field;
-}
-
-CW_INLINE UInt32 LocationSet_stride(LocationSet *ls) {
- IRO_ASSERT(2322, ls != NULL);
- IRO_ASSERT(2323, !LocationSet_IsUnknown(ls));
-
- return ls->u.known.stride;
-}
-
-CW_INLINE PAMemoryBlock *LocationSet_restriction(LocationSet *ls) {
- IRO_ASSERT(2330, ls != NULL);
- IRO_ASSERT(2331, LocationSet_IsUnknown(ls));
-
- return ls->u.unknown.restriction;
-}
-
-CW_INLINE LocationSet *LocationSet_bitfieldOf(LocationSet *ls) {
- IRO_ASSERT(2338, ls != NULL);
- IRO_ASSERT(2339, LocationSet_IsUnknown(ls));
-
- return ls->u.unknown.bitfieldOf;
-}
-
-CW_INLINE LocationSetSet *LocationSetSet_New(void) {
- LocationSetSet *lss = IRO_malloc(sizeof(LocationSetSet));
-
- IRO_ASSERT(2356, lss != NULL);
-#ifdef IRO_DEBUG
- lss->loc = NULL;
- lss->otherLocs = NULL;
- lss->count = 0;
-#endif
- return lss;
-}
-
-CW_INLINE void LocationSetSet_Delete(LocationSetSet *lss) {
- IRO_ASSERT(2369, lss != NULL);
- IRO_ASSERT(2370, lss->loc == NULL);
- IRO_ASSERT(2371, lss->otherLocs == NULL);
- IRO_ASSERT(2372, lss->count == 0);
- IRO_DEBUG_CLEAR(lss, sizeof(LocationSetSet));
- IRO_free(lss);
-}
-
-CW_INLINE void LocationSetSet_Init(LocationSetSet *lss) {
- IRO_ASSERT(2382, lss != NULL);
-
- lss->loc = NULL;
- lss->otherLocs = NULL;
- lss->count = 0;
-}
-
-CW_INLINE void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) {
- IRO_ASSERT(2391, dest != NULL);
- IRO_ASSERT(2392, src != NULL);
-
- dest->loc = NULL;
- dest->otherLocs = NULL;
- dest->count = 0;
- LocationSetSet_AddSet(dest, src);
-}
-
-CW_INLINE void LocationSetSet_Term(LocationSetSet *lss) {
- IRO_ASSERT(2402, lss != NULL);
-
- LocationSetSet_RemoveAll(lss);
-
-#ifdef IRO_DEBUG
- lss->loc = NULL;
- lss->otherLocs = NULL;
- lss->count = 0;
-#endif
-}
-
-CW_INLINE void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationSet *, void *), void *refcon) {
- IRO_ASSERT(2446, lss != NULL);
- IRO_ASSERT(2447, action != NULL);
- IRO_ASSERT(2448, refcon == NULL || refcon != NULL);
-
- while (lss && lss->loc) {
- action(lss->loc, refcon);
- lss = lss->otherLocs;
- }
-}
-
-CW_INLINE LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) {
- IRO_ASSERT(2458, lss != NULL);
- IRO_ASSERT(2459, ls != NULL);
-
- while (lss && lss->loc) {
- if (LocationSets_Equal(lss->loc, ls))
- return lss->loc;
- lss = lss->otherLocs;
- }
-
- return NULL;
-}
-
-CW_INLINE LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) {
- IRO_ASSERT(2470, lss != NULL);
-
- if (!lss->loc)
- return stUnknownLs;
-
- while (lss && lss->loc) {
- if (LocationSet_IsUnknown(lss->loc))
- return lss->loc;
- lss = lss->otherLocs;
- }
-
- return NULL;
-}
-
-CW_INLINE LocationSet *LocationSetSet_FindFirst(LocationSetSet *lss) {
- IRO_ASSERT(2498, lss != NULL);
-
- return lss->loc;
-}
-
-CW_INLINE int LocationSetSet_Count(LocationSetSet *lss) {
- IRO_ASSERT(2505, lss != NULL);
-
- return lss->count;
-}
-
-CW_INLINE void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemoryBlock *block) {
- LocationSetSet *first;
- LocationSetSet *prev;
- LocationSetSet *next;
- LocationSetSet *tmp;
-
- IRO_ASSERT(2514, lss != NULL);
- IRO_ASSERT(2515, block != NULL);
-
- first = lss;
- prev = NULL;
- while (lss && lss->loc) {
- next = lss->otherLocs;
- if (MemoryBlocks_Equal(block, lss->loc->block)) {
- if (lss->loc != stUnknownLs) {
- LocationSet_Term(lss->loc);
- LocationSet_Delete(lss->loc);
- }
- if (!prev) {
- if (lss->otherLocs == NULL) {
- lss->loc = NULL;
- prev = lss;
- } else {
- tmp = lss->otherLocs;
- lss->loc = lss->otherLocs->loc;
- lss->otherLocs = lss->otherLocs->otherLocs;
- tmp->loc = NULL;
- tmp->otherLocs = NULL;
- LocationSetSet_Term(tmp);
- LocationSetSet_Delete(tmp);
- prev = NULL;
- next = lss;
- }
- } else {
- prev->otherLocs = lss->otherLocs;
- lss->loc = NULL;
- lss->otherLocs = NULL;
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- prev = lss;
- }
- first->count--;
- }
- lss = next;
- }
-}
-
-CW_INLINE void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) {
- IRO_ASSERT(2572, lss != NULL);
- IRO_ASSERT(2573, ls != NULL);
-
- if (!LocationSet_IsUnknown(ls) && lss->count < 4) {
- LocationSet *ls2;
-
- if (ls == stUnknownLs) {
- ls2 = stUnknownLs;
- } else {
- ls2 = LocationSet_New();
- LocationSet_Copy(ls2, ls);
- }
-
- if (lss->loc) {
- LocationSetSet *lss2 = LocationSetSet_New();
- LocationSetSet_Init(lss2);
- lss2->loc = lss->loc;
- lss2->otherLocs = lss->otherLocs;
- lss->otherLocs = lss2;
- }
-
- lss->loc = ls2;
- lss->count++;
- } else {
- LocationSet *ls2;
-
- LocationSetSet_RemoveAll(lss);
- ls2 = LocationSet_New();
- if (LocationSet_IsUnknown(ls)) {
- LocationSet_Copy(ls2, ls);
- } else {
- LocationSet_Copy(ls2, stUnknownLs);
- if (ls->rtype)
- LocationSet_SetRtype(ls2, ls->rtype);
- }
-
- lss->loc = ls2;
- lss->count = 1;
- }
-}
-
-CW_INLINE void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) {
- IRO_ASSERT(2622, lss != NULL);
- IRO_ASSERT(2623, ls != NULL);
-
- if (!lss->loc || (!LocationSet_IsUnknown(lss->loc) && !LocationSetSet_Find(lss, ls))) {
- if (!LocationSet_IsUnknown(ls) && ls->u.known.stride)
- LocationSetSet_RemoveAllWithMemoryBlock(lss, ls->block);
- LocationSetSet_SimpleAdd(lss, ls);
- }
-}
-
-CW_INLINE void LocationSetSet_AddUnknown(LocationSetSet *lss, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
- LocationSet *ls;
-
- IRO_ASSERT(2643, lss != NULL);
- IRO_ASSERT(2644, rtype == NULL || rtype != NULL);
- IRO_ASSERT(2645, restriction == NULL || restriction != NULL);
- IRO_ASSERT(2646, bitfieldOf == NULL || bitfieldOf != NULL);
-
- ls = LocationSet_New();
- LocationSet_InitUnknown(ls, rtype, restriction, bitfieldOf);
- LocationSetSet_Add(lss, ls);
- LocationSet_Term(ls);
- LocationSet_Delete(ls);
-}
-
-CW_INLINE void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) {
- LocationSetSet *prev;
- LocationSetSet *first;
- LocationSetSet *tmp;
-
- IRO_ASSERT(2659, lss != NULL);
- IRO_ASSERT(2660, ls != NULL);
-
- first = lss;
- prev = NULL;
- while (lss && lss->loc) {
- if (LocationSets_Equal(lss->loc, ls)) {
- if (lss->loc != stUnknownLs) {
- LocationSet_Term(lss->loc);
- LocationSet_Delete(lss->loc);
- }
- if (!prev) {
- if (lss->otherLocs == NULL) {
- lss->loc = NULL;
- } else {
- tmp = lss->otherLocs;
- lss->loc = lss->otherLocs->loc;
- lss->otherLocs = lss->otherLocs->otherLocs;
- tmp->loc = NULL;
- tmp->otherLocs = NULL;
- LocationSetSet_Term(tmp);
- LocationSetSet_Delete(tmp);
- }
- } else {
- prev->otherLocs = lss->otherLocs;
- lss->loc = NULL;
- lss->otherLocs = NULL;
- LocationSetSet_Term(lss);
- LocationSetSet_Delete(lss);
- }
- first->count--;
- return;
- }
-
- prev = lss;
- lss = lss->otherLocs;
- }
-}
-
-CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss) {
- IRO_ASSERT(2707, lss != NULL);
-
- while (lss && lss->loc)
- LocationSetSet_Remove(lss, lss->loc);
-}
-
-CW_INLINE void LocationSetSet_AddSetAction(LocationSet *ls, void *refcon) {
- IRO_ASSERT(2717, ls != NULL);
- IRO_ASSERT(2718, refcon != NULL);
-
- LocationSetSet_Add((LocationSetSet *) refcon, ls);
-}
-
-CW_INLINE void LocationSetSet_SimpleAddSetAction(LocationSet *ls, void *refcon) {
- IRO_ASSERT(2725, ls != NULL);
- IRO_ASSERT(2726, refcon != NULL);
-
- LocationSetSet_SimpleAdd((LocationSetSet *) refcon, ls);
-}
-
-CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) {
- IRO_ASSERT(2733, dest != NULL);
- IRO_ASSERT(2734, src != NULL);
-
- if (dest->count)
- LocationSetSet_ForEach(src, LocationSetSet_AddSetAction, dest);
- else
- LocationSetSet_ForEach(src, LocationSetSet_SimpleAddSetAction, dest);
-}
-
-CW_INLINE void LocationSetSet_RemoveSetAction(LocationSet *ls, void *refcon) {
- IRO_ASSERT(2744, ls != NULL);
- IRO_ASSERT(2745, refcon != NULL);
-
- LocationSetSet_Remove((LocationSetSet *) refcon, ls);
-}
-
-CW_INLINE void LocationSetSet_sub_488700(LocationSetSet *dest, LocationSetSet *src) {
- IRO_ASSERT(2752, dest != NULL);
- IRO_ASSERT(2753, src != NULL);
-
- LocationSetSet_ForEach(src, LocationSetSet_RemoveSetAction, dest);
-}
-
-CW_INLINE Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) {
- IRO_ASSERT(2826, lss1 != NULL);
- IRO_ASSERT(2827, lss2 != NULL);
-
- if (lss1 == lss2)
- return 1;
- if (LocationSetSet_Count(lss1) != LocationSetSet_Count(lss2))
- return 0;
-
- while (lss1 && lss1->loc) {
- if (!LocationSetSet_Find(lss2, lss1->loc))
- return 0;
- lss1 = lss1->otherLocs;
- }
-
- return 1;
-}
-
-CW_INLINE ParamMapping *ParamMapping_New(void) {
- ParamMapping *pm = IRO_malloc(sizeof(ParamMapping));
-
- IRO_ASSERT(2885, pm != NULL);
-#ifdef IRO_DEBUG
- pm->actual = NULL;
- pm->formal = NULL;
- pm->extended = NULL;
-#endif
- return pm;
-}
-
-CW_INLINE void ParamMapping_Delete(ParamMapping *pm) {
- IRO_ASSERT(2898, pm != NULL);
- IRO_ASSERT(2899, pm->actual == NULL);
- IRO_ASSERT(2900, pm->formal == NULL);
- IRO_ASSERT(2901, pm->extended == NULL);
- IRO_DEBUG_CLEAR(pm, sizeof(ParamMapping));
- IRO_free(pm);
-}
-
-CW_INLINE void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Object *formal, ExtendedParam *extended) {
- IRO_ASSERT(2911, pm != NULL);
-
- pm->actual = actual;
- pm->formal = formal;
- pm->extended = extended;
-}
-
-CW_INLINE void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) {
- IRO_ASSERT(2920, src != NULL);
- IRO_ASSERT(2921, dest != NULL);
-
- dest->actual = src->actual;
- dest->formal = src->formal;
- dest->extended = src->extended;
-}
-
-CW_INLINE void ParamMapping_Term(ParamMapping *pm) {
- IRO_ASSERT(2933, pm != NULL);
-
-#ifdef IRO_DEBUG
- pm->actual = NULL;
- pm->formal = NULL;
- pm->extended = NULL;
-#endif
-}
-
-CW_INLINE void ParamMapping_SetExtended(ParamMapping *pm, ExtendedParam *ep) {
- IRO_ASSERT(2992, pm != NULL);
-
- pm->extended = ep;
-}
-
-CW_INLINE IROLinear *ParamMapping_actual(ParamMapping *pm) {
- IRO_ASSERT(2999, pm != NULL);
-
- return pm->actual;
-}
-
-CW_INLINE ExtendedParam *ParamMapping_extended(ParamMapping *pm) {
- IRO_ASSERT(3011, pm != NULL);
-
- return pm->extended;
-}
-
-CW_INLINE ParamMappingFunction *ParamMappingFunction_New(void) {
- ParamMappingFunction *pmf = IRO_malloc(sizeof(ParamMappingFunction));
-
- IRO_ASSERT(3026, pmf != NULL);
-#ifdef IRO_DEBUG
- pmf->mapping = NULL;
- pmf->otherMappings = NULL;
-#endif
- return pmf;
-}
-
-CW_INLINE void ParamMappingFunction_Delete(ParamMappingFunction *pmf) {
- IRO_ASSERT(3039, pmf != NULL);
- IRO_ASSERT(3040, pmf->mapping == NULL);
- IRO_ASSERT(3041, pmf->otherMappings == NULL);
- IRO_DEBUG_CLEAR(pmf, sizeof(ParamMappingFunction));
- IRO_free(pmf);
-}
-
-CW_INLINE void ParamMappingFunction_Init(ParamMappingFunction *pmf) {
- IRO_ASSERT(3050, pmf != NULL);
-
- pmf->mapping = NULL;
- pmf->otherMappings = NULL;
-}
-
-CW_INLINE void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFunction *src) {
- IRO_ASSERT(3058, src != NULL);
- IRO_ASSERT(3059, dest != NULL);
-
- dest->mapping = NULL;
- dest->otherMappings = NULL;
- ParamMappingFunction_AddAllMaybe_sub_487C50(dest, src);
-}
-
-CW_INLINE void ParamMappingFunction_Term(ParamMappingFunction *pmf) {
- IRO_ASSERT(3068, pmf != NULL);
-
- ParamMappingFunction_RemoveAll(pmf);
-
-#ifdef IRO_DEBUG
- pmf->mapping = NULL;
- pmf->otherMappings = NULL;
-#endif
-}
-
-CW_INLINE void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMapping *, void *), void *refcon) {
- IRO_ASSERT(3111, pmf != NULL);
- IRO_ASSERT(3112, action != NULL);
- IRO_ASSERT(3113, refcon == NULL || refcon != NULL);
-
- while (pmf && pmf->mapping) {
- action(pmf->mapping, refcon);
- pmf = pmf->otherMappings;
- }
-}
-
-CW_INLINE ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFunction *pmf, Object *formal) {
- IRO_ASSERT(3123, pmf != NULL);
- IRO_ASSERT(3124, formal != NULL);
-
- while (pmf && pmf->mapping) {
- if (pmf->mapping->formal == formal)
- return pmf->mapping;
- pmf = pmf->otherMappings;
- }
-
- return NULL;
-}
-
-CW_INLINE void Pmf_Add_sub_486610(ParamMappingFunction *pmf, ParamMapping *mapping) {
- ParamMapping *existing;
-
- IRO_ASSERT(3138, pmf != NULL);
- IRO_ASSERT(3139, mapping != NULL);
-
- existing = ParamMappingFunction_FindMappingByFormal(pmf, mapping->formal);
- if (!existing) {
- existing = ParamMapping_New();
- ParamMapping_Copy(existing, mapping);
- if (pmf->mapping) {
- ParamMappingFunction *newPMF = ParamMappingFunction_New();
- ParamMappingFunction_Init(newPMF);
- newPMF->mapping = pmf->mapping;
- newPMF->otherMappings = pmf->otherMappings;
- pmf->otherMappings = newPMF;
- }
- pmf->mapping = existing;
- } else {
- existing->actual = mapping->actual;
- existing->extended = mapping->extended;
- }
-}
-
-CW_INLINE void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping *mapping) {
- ParamMappingFunction *prev;
- ParamMappingFunction *tmp;
-
- IRO_ASSERT(3170, pmf != NULL);
- IRO_ASSERT(3171, mapping != NULL);
-
- prev = NULL;
- while (pmf && pmf->mapping) {
- if (pmf->mapping->formal == mapping->formal) {
- ParamMapping_Term(pmf->mapping);
- ParamMapping_Delete(pmf->mapping);
- if (!prev) {
- if (pmf->otherMappings == NULL) {
- pmf->mapping = NULL;
- } else {
- tmp = pmf->otherMappings;
- pmf->mapping = pmf->otherMappings->mapping;
- pmf->otherMappings = pmf->otherMappings->otherMappings;
- tmp->mapping = NULL;
- tmp->otherMappings = NULL;
- ParamMappingFunction_Term(tmp);
- ParamMappingFunction_Delete(tmp);
- }
- } else {
- prev->otherMappings = pmf->otherMappings;
- pmf->mapping = NULL;
- pmf->otherMappings = NULL;
- ParamMappingFunction_Term(pmf);
- ParamMappingFunction_Delete(pmf);
- }
- return;
- }
-
- prev = pmf;
- pmf = pmf->otherMappings;
- }
-}
-
-CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf) {
- IRO_ASSERT(3213, pmf != NULL);
-
- while (pmf && pmf->mapping)
- ParamMappingFunction_Remove(pmf, pmf->mapping);
-}
-
-CW_INLINE void ParamMappingFunction_AddFunctionAction(ParamMapping *mapping, void *refcon) {
- IRO_ASSERT(3223, mapping != NULL);
- IRO_ASSERT(3224, refcon != NULL);
-
- Pmf_Add_sub_486610((ParamMappingFunction *) refcon, mapping);
-}
-
-CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src) {
- IRO_ASSERT(3231, dest != NULL);
- IRO_ASSERT(3232, src != NULL);
-
- pmf_sub_487C70(src, ParamMappingFunction_AddFunctionAction, dest);
-}
-
-CW_INLINE PointsToEntry *PointsToEntry_New(void) {
- PointsToEntry *pte = IRO_malloc(sizeof(PointsToEntry));
-
- IRO_ASSERT(3288, pte != NULL);
-#ifdef IRO_DEBUG
- pte->loc = NULL;
- pte->locs = NULL;
-#endif
- return pte;
-}
-
-CW_INLINE void PointsToEntry_Delete(PointsToEntry *pte) {
- IRO_ASSERT(3300, pte != NULL);
- IRO_ASSERT(3301, pte->loc == NULL);
- IRO_ASSERT(3302, pte->locs == NULL);
- IRO_DEBUG_CLEAR(pte, sizeof(PointsToEntry));
- IRO_free(pte);
-}
-
-CW_INLINE void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSetSet *locs) {
- IRO_ASSERT(3312, pte != NULL);
- IRO_ASSERT(3313, loc != NULL);
- IRO_ASSERT(3314, !LocationSet_IsUnknown(loc));
- IRO_ASSERT(3315, locs != NULL);
-
- pte->loc = LocationSet_New();
- LocationSet_Copy(pte->loc, loc);
-
- pte->locs = LocationSetSet_New();
- LocationSetSet_Copy(pte->locs, locs);
-}
-
-CW_INLINE void PointsToEntry_Copy(PointsToEntry *dest, PointsToEntry *src) {
- IRO_ASSERT(3325, src != NULL);
- IRO_ASSERT(3326, dest != NULL);
-
- PointsToEntry_Init(dest, src->loc, src->locs);
-}
-
-CW_INLINE void PointsToEntry_Term(PointsToEntry *pte) {
- IRO_ASSERT(3333, pte != NULL);
-
- LocationSet_Term(pte->loc);
- LocationSet_Delete(pte->loc);
- LocationSetSet_Term(pte->locs);
- LocationSetSet_Delete(pte->locs);
-
-#ifdef IRO_DEBUG
- pte->loc = NULL;
- pte->locs = NULL;
-#endif
-}
-
-CW_INLINE Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) {
- IRO_ASSERT(3381, pte1 != NULL);
- IRO_ASSERT(3382, pte2 != NULL);
-
- if (pte1 == pte2)
- return 1;
-
- return LocationSets_Equal(pte1->loc, pte2->loc) && LocationSetSets_Equal(pte1->locs, pte2->locs);
-}
-
-CW_INLINE LocationSet *PointsToEntry_loc(PointsToEntry *pte) {
- IRO_ASSERT(3407, pte != NULL);
-
- return pte->loc;
-}
-
-CW_INLINE LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) {
- IRO_ASSERT(3414, pte != NULL);
-
- return pte->locs;
-}
-
-CW_INLINE PointsToFunction *PointsToFunction_New(void) {
- PointsToFunction *pointsToFunc = IRO_malloc(sizeof(PointsToFunction));
-
- IRO_ASSERT(3430, pointsToFunc != NULL);
-#ifdef IRO_DEBUG
- pointsToFunc->pte = NULL;
- pointsToFunc->otherPtes = NULL;
-#endif
- return pointsToFunc;
-}
-
-CW_INLINE void PointsToFunction_Delete(PointsToFunction *pointsToFunc) {
- IRO_ASSERT(3442, pointsToFunc != NULL);
- IRO_ASSERT(3443, pointsToFunc->pte == NULL);
- IRO_ASSERT(3444, pointsToFunc->otherPtes == NULL);
- IRO_DEBUG_CLEAR(pointsToFunc, sizeof(PointsToFunction));
- IRO_free(pointsToFunc);
-}
-
-CW_INLINE void PointsToFunction_Init(PointsToFunction *pointsToFunc) {
- IRO_ASSERT(3454, pointsToFunc != NULL);
-
- pointsToFunc->pte = NULL;
- pointsToFunc->otherPtes = NULL;
-}
-
-CW_INLINE void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) {
- IRO_ASSERT(3462, src != NULL);
- IRO_ASSERT(3463, dest != NULL);
-
- dest->pte = NULL;
- dest->otherPtes = NULL;
- PointsToFunction_AddAllIGuess_sub_487D80(dest, src);
-}
-
-CW_INLINE void PointsToFunction_Term(PointsToFunction *pointsToFunc) {
- IRO_ASSERT(3472, pointsToFunc != NULL);
-
- PointsToFunction_RemoveAll(pointsToFunc);
-
-#ifdef IRO_DEBUG
- pointsToFunc->pte = NULL;
- pointsToFunc->otherPtes = NULL;
-#endif
-}
-
-CW_INLINE void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*action)(PointsToEntry *, void *), void *refcon) {
- IRO_ASSERT(3515, pointsToFunc != NULL);
- IRO_ASSERT(3516, action != NULL);
- IRO_ASSERT(3517, refcon == NULL || refcon != NULL);
-
- while (pointsToFunc && pointsToFunc->pte) {
- action(pointsToFunc->pte, refcon);
- pointsToFunc = pointsToFunc->otherPtes;
- }
-}
-
-CW_INLINE PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
- IRO_ASSERT(3527, pointsToFunc != NULL);
- IRO_ASSERT(3528, ls != NULL);
-
- while (pointsToFunc && pointsToFunc->pte) {
- if (LocationSets_Equal(pointsToFunc->pte->loc, ls))
- return pointsToFunc->pte;
- pointsToFunc = pointsToFunc->otherPtes;
- }
-
- return NULL;
-}
-
-CW_INLINE PointsToEntry *PointsToFunction_FindFirst(PointsToFunction *pointsToFunc) {
- IRO_ASSERT(3539, pointsToFunc != NULL);
-
- return pointsToFunc->pte;
-}
-
-CW_INLINE PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
- IRO_ASSERT(3546, pointsToFunc != NULL);
- IRO_ASSERT(3547, ls != NULL);
-
- while (pointsToFunc && pointsToFunc->pte) {
- if (ls->u.known.stride) {
- if (LocationSets_Equal(pointsToFunc->pte->loc, ls))
- return pointsToFunc->pte;
- } else if (LocationSets_LookupCompatible(pointsToFunc->pte->loc, ls)) {
- return pointsToFunc->pte;
- }
- pointsToFunc = pointsToFunc->otherPtes;
- }
-
- return NULL;
-}
-
-CW_INLINE PointsToEntry *PointsToFunction_FindContainingLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls, Type *rtype) {
- IRO_ASSERT(3565, pointsToFunc != NULL);
- IRO_ASSERT(3566, ls != NULL);
- IRO_ASSERT(3567, rtype != NULL);
-
- while (pointsToFunc && pointsToFunc->pte) {
- if (pointsToFunc->pte->locs->loc && !LocationSet_IsUnknown(pointsToFunc->pte->locs->loc)) {
- if (!pointsToFunc->pte->locs->otherLocs && LocationSet_Contains(pointsToFunc->pte->loc, pointsToFunc->pte->locs->loc->rtype, ls, rtype))
- return pointsToFunc->pte;
- }
- pointsToFunc = pointsToFunc->otherPtes;
- }
-
- return NULL;
-}
-
-CW_INLINE void PointsToFunction_RemoveOverlappingLocations(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
- Type *rtype1;
- Type *rtype2;
- LocationSet *ls;
- PointsToFunction *prev;
- PointsToFunction *next;
- PointsToFunction *tmp;
-
- IRO_ASSERT(3601, pointsToFunc != NULL);
- IRO_ASSERT(3602, pte != NULL);
- IRO_ASSERT(3603, pte->locs != NULL);
-
- if (pte->locs->loc && pte->locs->loc != stUnknownLs)
- rtype1 = pte->locs->loc->rtype;
- else
- rtype1 = NULL;
- ls = pte->loc;
- IRO_ASSERT(3614, ls != NULL);
-
- prev = NULL;
- while (pointsToFunc && pointsToFunc->pte) {
- next = pointsToFunc->otherPtes;
- if (pointsToFunc->pte->locs->loc && pointsToFunc->pte->locs->loc != stUnknownLs)
- rtype2 = pointsToFunc->pte->locs->loc->rtype;
- else
- rtype2 = NULL;
-
- if (LocationSets_Overlap(ls, rtype1, pointsToFunc->pte->loc, rtype2)) {
- PointsToEntry_Term(pointsToFunc->pte);
- PointsToEntry_Delete(pointsToFunc->pte);
- if (!prev) {
- if (pointsToFunc->otherPtes == NULL) {
- pointsToFunc->pte = NULL;
- prev = pointsToFunc;
- } else {
- tmp = pointsToFunc->otherPtes;
- pointsToFunc->pte = pointsToFunc->otherPtes->pte;
- pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes;
- tmp->pte = NULL;
- tmp->otherPtes = NULL;
- PointsToFunction_Term(tmp);
- PointsToFunction_Delete(tmp);
- prev = NULL;
- next = pointsToFunc;
- }
- } else {
- prev->otherPtes = pointsToFunc->otherPtes;
- pointsToFunc->pte = NULL;
- pointsToFunc->otherPtes = NULL;
- PointsToFunction_Term(pointsToFunc);
- PointsToFunction_Delete(pointsToFunc);
- prev = pointsToFunc;
- }
- }
-
- pointsToFunc = next;
- }
-}
-
-CW_INLINE Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
- Boolean flag;
- Boolean isKnown;
- SInt32 stride;
- PointsToFunction *next;
- LocationSet *loc;
- LocationSet *loc2;
- Type *rtype1;
- Type *rtype2;
- LocationSetSet *locs2;
- LocationSet *tmp;
- LocationSet *unknown;
- Boolean flag2;
- Boolean flag3;
-
- IRO_ASSERT(3675, pointsToFunc != NULL);
- IRO_ASSERT(3676, pte != NULL);
- IRO_ASSERT(3677, pte->locs != NULL);
- IRO_ASSERT(3678, PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc) == NULL);
- IRO_ASSERT(3679, (unknown = LocationSetSet_FindFirst(pte->locs)) != NULL);
- IRO_ASSERT(3680, LocationSet_IsUnknown(unknown));
- IRO_ASSERT(3681, LocationSet_bitfieldOf(unknown) == NULL);
- IRO_ASSERT(3682, LocationSet_restriction(unknown) == NULL);
-
- if (pte->locs->loc && pte->locs->loc != stUnknownLs)
- rtype1 = pte->locs->loc->rtype;
- else
- rtype1 = NULL;
-
- loc = pte->loc;
- IRO_ASSERT(3693, loc != NULL);
-
- isKnown = !LocationSet_IsUnknown(loc);
- if (isKnown)
- stride = LocationSet_stride(loc);
-
- flag = 0;
- while (pointsToFunc && pointsToFunc->pte) {
- next = pointsToFunc->otherPtes;
-
- locs2 = pointsToFunc->pte->locs;
-
- if (locs2->loc && locs2->loc != stUnknownLs)
- rtype2 = locs2->loc->rtype;
- else
- rtype2 = NULL;
-
- loc2 = pointsToFunc->pte->loc;
-
- flag2 = !(tmp = LocationSetSet_FindFirst(locs2)) ||
- !LocationSet_IsUnknown(tmp) ||
- LocationSet_bitfieldOf(tmp) ||
- LocationSet_restriction(tmp);
-
- flag3 = LocationSets_Overlap(loc, rtype1, loc2, rtype2);
-
- if (!flag && flag3)
- flag = 1;
-
- if (flag3 && (flag2 || (isKnown && stride && LocationSet_stride(loc2) == 0)))
- return 1;
-
- pointsToFunc = next;
- }
-
- return !flag;
-}
-
-CW_INLINE Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
- PointsToEntry *newPTE;
-
- IRO_ASSERT(3741, pointsToFunc != NULL);
- IRO_ASSERT(3742, pte != NULL);
-
- newPTE = PointsToEntry_New();
- PointsToEntry_Copy(newPTE, pte);
- if (pointsToFunc->pte) {
- PointsToFunction *newPointsToFunc = PointsToFunction_New();
- PointsToFunction_Init(newPointsToFunc);
- newPointsToFunc->pte = pointsToFunc->pte;
- newPointsToFunc->otherPtes = pointsToFunc->otherPtes;
- pointsToFunc->otherPtes = newPointsToFunc;
- }
- pointsToFunc->pte = newPTE;
- return 1;
-}
-
-CW_INLINE Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
- IRO_ASSERT(3766, pointsToFunc != NULL);
- IRO_ASSERT(3767, pte != NULL);
-
- if (!PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc)) {
- LocationSet *ls;
- if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) ||
- LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) {
- PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte);
- if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype)
- PointsToFunction_SimpleAdd(pointsToFunc, pte);
- return 1;
- }
- }
-
- return 0;
-}
-
-CW_INLINE Boolean PointsToFunction_AddWithoutChecking(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
- LocationSet *ls;
-
- IRO_ASSERT(3793, pointsToFunc != NULL);
- IRO_ASSERT(3794, pte != NULL);
-
- if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) ||
- LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) {
- PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte);
- if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype)
- PointsToFunction_SimpleAdd(pointsToFunc, pte);
- return 1;
- }
-
- return 0;
-}
-
-CW_INLINE void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
- PointsToFunction *prev;
- PointsToFunction *tmp;
-
- IRO_ASSERT(3818, pointsToFunc != NULL);
- IRO_ASSERT(3819, ls != NULL);
- IRO_ASSERT(3820, !LocationSet_IsUnknown(ls));
-
- prev = NULL;
- while (pointsToFunc && pointsToFunc->pte) {
- if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) {
- PointsToEntry_Term(pointsToFunc->pte);
- PointsToEntry_Delete(pointsToFunc->pte);
- if (!prev) {
- if (pointsToFunc->otherPtes == NULL) {
- pointsToFunc->pte = NULL;
- } else {
- tmp = pointsToFunc->otherPtes;
- pointsToFunc->pte = pointsToFunc->otherPtes->pte;
- pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes;
- tmp->pte = NULL;
- tmp->otherPtes = NULL;
- PointsToFunction_Term(tmp);
- PointsToFunction_Delete(tmp);
- }
- } else {
- prev->otherPtes = pointsToFunc->otherPtes;
- pointsToFunc->pte = NULL;
- pointsToFunc->otherPtes = NULL;
- PointsToFunction_Term(pointsToFunc);
- PointsToFunction_Delete(pointsToFunc);
- }
- return;
- }
-
- prev = pointsToFunc;
- pointsToFunc = pointsToFunc->otherPtes;
- }
-}
-
-CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc) {
- IRO_ASSERT(3862, pointsToFunc != NULL);
-
- while (pointsToFunc && pointsToFunc->pte)
- PointsToFunction_RemoveByLocationSet(pointsToFunc, pointsToFunc->pte->loc);
-}
-
-CW_INLINE void PointsToFunction_AddFunctionAction(PointsToEntry *pte, void *refcon) {
- IRO_ASSERT(3872, pte != NULL);
- IRO_ASSERT(3873, refcon != NULL);
-
- PointsToFunction_Add((PointsToFunction *) refcon, pte);
-}
-
-CW_INLINE void PointsToFunction_SimpleAddFunctionAction(PointsToEntry *pte, void *refcon) {
- IRO_ASSERT(3880, pte != NULL);
- IRO_ASSERT(3881, refcon != NULL);
-
- PointsToFunction_SimpleAdd((PointsToFunction *) refcon, pte);
-}
-
-CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src) {
- IRO_ASSERT(3888, dest != NULL);
- IRO_ASSERT(3889, src != NULL);
-
- if (dest->pte)
- PointsToFunction_ForEach(src, PointsToFunction_AddFunctionAction, dest);
- else
- PointsToFunction_ForEach(src, PointsToFunction_SimpleAddFunctionAction, dest);
-}
-
-CW_INLINE void PointsToFunction_SortByExtendedParamNum(PointsToFunction *pointsToFunc) {
- UInt32 value1;
- UInt32 value2;
- PointsToFunction *scan;
-
- while (pointsToFunc && pointsToFunc->pte) {
- value1 = 0;
- if (pointsToFunc->pte->loc && pointsToFunc->pte->loc->block) {
- PAMemoryBlock *block = pointsToFunc->pte->loc->block;
- if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) {
- value1 = 2 * (block->u.ep->x4) + 1;
- } else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) {
- if (block->u.localvar->x0 && block->u.localvar->x0->extParam)
- value1 = 2 * block->u.localvar->x0->extParam->x4;
- }
- }
-
- for (scan = pointsToFunc->otherPtes; scan && scan->pte; scan = scan->otherPtes) {
- value2 = 0;
- if (scan->pte->loc && scan->pte->loc->block) {
- PAMemoryBlock *block = scan->pte->loc->block;
- if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) {
- value2 = 2 * (block->u.ep->x4) + 1;
- } else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) {
- if (block->u.localvar->x0 && block->u.localvar->x0->extParam)
- value2 = 2 * block->u.localvar->x0->extParam->x4;
- }
- }
-
- if (value2 < value1) {
- LocationSet *saveloc;
- LocationSetSet *savelocs;
- saveloc = pointsToFunc->pte->loc;
- savelocs = pointsToFunc->pte->locs;
- pointsToFunc->pte->loc = scan->pte->loc;
- pointsToFunc->pte->locs = scan->pte->locs;
- scan->pte->loc = saveloc;
- scan->pte->locs = savelocs;
- }
- }
-
- pointsToFunc = pointsToFunc->otherPtes;
- }
-}
-
-CW_INLINE Boolean PointsToFunctions_Equal(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
- PointsToFunction *scan;
- PointsToEntry *pte;
-
- IRO_ASSERT(3968, pointsToFunc1 != NULL);
- IRO_ASSERT(3969, pointsToFunc2 != NULL);
-
- if (pointsToFunc1 == pointsToFunc2)
- return 1;
-
- for (scan = pointsToFunc1; scan && scan->pte; scan = scan->otherPtes) {
- pte = PointsToFunction_FindByLocationSet(pointsToFunc2, scan->pte->loc);
- if (!pte || !PointsToEntries_Equal(pte, scan->pte))
- return 0;
- }
-
- for (scan = pointsToFunc2; scan && scan->pte; scan = scan->otherPtes) {
- pte = PointsToFunction_FindByLocationSet(pointsToFunc1, scan->pte->loc);
- if (!pte || !PointsToEntries_Equal(pte, scan->pte))
- return 0;
- }
-
- return 1;
-}
-
-CW_INLINE Boolean PointsToFunctions_Match(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
- return 1;
-}
-
-CW_INLINE PartialTransferFunction *PartialTransferFunction_New(void) {
- PartialTransferFunction *ptf = IRO_malloc(sizeof(PartialTransferFunction));
-
- IRO_ASSERT(4110, ptf != NULL);
-#ifdef IRO_DEBUG
- ptf->initialPointsToFn = NULL;
- ptf->finalPointsToFn = NULL;
- ptf->funcModifies = NULL;
- ptf->context.nd = NULL;
- ptf->context.ptf = NULL;
- ptf->returnLocation = NULL;
-#endif
- return ptf;
-}
-
-CW_INLINE void PartialTransferFunction_Delete(PartialTransferFunction *ptf) {
- IRO_ASSERT(4126, ptf != NULL);
- IRO_ASSERT(4127, ptf->initialPointsToFn == NULL);
- IRO_ASSERT(4128, ptf->finalPointsToFn == NULL);
- IRO_ASSERT(4129, ptf->funcModifies == NULL);
- IRO_ASSERT(4130, ptf->context.nd == NULL);
- IRO_ASSERT(4131, ptf->context.ptf == NULL);
- IRO_ASSERT(4132, ptf->returnLocation == NULL);
- IRO_DEBUG_CLEAR(ptf, sizeof(PartialTransferFunction));
- IRO_free(ptf);
-}
-
-CW_INLINE void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear *contextNd, PartialTransferFunction *contextPTF) {
- IRO_ASSERT(4142, ptf != NULL);
- IRO_ASSERT(4143, contextNd != NULL);
- IRO_ASSERT(4144, contextPTF != NULL);
-
- ptf->initialPointsToFn = PointsToFunction_New();
- PointsToFunction_Init(ptf->initialPointsToFn);
- ptf->finalPointsToFn = PointsToFunction_New();
- PointsToFunction_Init(ptf->finalPointsToFn);
-
- ptf->funcModifies = LocationSetSet_New();
- LocationSetSet_Init(ptf->funcModifies);
- LocationSetSet_AddUnknown(ptf->funcModifies, NULL, NULL, NULL);
-
- ptf->returnLocation = NULL;
- ptf->x10 = 0;
-
- ptf->context.nd = contextNd;
- ptf->context.ptf = contextPTF;
-}
-
-CW_INLINE void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialTransferFunction *src) {
- IRO_ASSERT(4164, src != NULL);
- IRO_ASSERT(4165, dest != NULL);
-
- dest->initialPointsToFn = PointsToFunction_New();
- PointsToFunction_Copy(dest->initialPointsToFn, src->initialPointsToFn);
- dest->finalPointsToFn = PointsToFunction_New();
- PointsToFunction_Copy(dest->finalPointsToFn, src->finalPointsToFn);
-
- dest->funcModifies = LocationSetSet_New();
- LocationSetSet_Copy(dest->funcModifies, src->funcModifies);
-
- if (src->returnLocation) {
- dest->returnLocation = LocationSet_New();
- LocationSet_Copy(dest->returnLocation, src->returnLocation);
- } else {
- dest->returnLocation = NULL;
- }
-
- dest->x10 = src->x10;
- dest->context = src->context;
-}
-
-CW_INLINE void PartialTransferFunction_Term(PartialTransferFunction *ptf) {
- IRO_ASSERT(4190, ptf != NULL);
-
- PointsToFunction_Term(ptf->initialPointsToFn);
- PointsToFunction_Delete(ptf->initialPointsToFn);
- PointsToFunction_Term(ptf->finalPointsToFn);
- PointsToFunction_Delete(ptf->finalPointsToFn);
- LocationSetSet_Term(ptf->funcModifies);
- LocationSetSet_Delete(ptf->funcModifies);
-
- if (ptf->returnLocation) {
- PAMemoryBlock_Term(ptf->returnLocation->block);
- PAMemoryBlock_Delete(ptf->returnLocation->block);
- LocationSet_Term(ptf->returnLocation);
- LocationSet_Delete(ptf->returnLocation);
- ptf->returnLocation = NULL;
- }
-
-#ifdef IRO_DEBUG
- ptf->initialPointsToFn = NULL;
- ptf->finalPointsToFn = NULL;
- ptf->funcModifies = NULL;
- ptf->context.nd = NULL;
- ptf->context.ptf = NULL;
-#endif
-}
-
-CW_INLINE PointsToFunction *PartialTransferFunction_initialPointsToFn(PartialTransferFunction *ptf) {
- IRO_ASSERT(4221, ptf != NULL);
-
- return ptf->initialPointsToFn;
-}
-
-CW_INLINE PointsToFunction *PartialTransferFunction_finalPointsToFn(PartialTransferFunction *ptf) {
- IRO_ASSERT(4227, ptf != NULL);
-
- return ptf->finalPointsToFn;
-}
-
-CW_INLINE LocationSetSet *PTF_sub_48D750(PartialTransferFunction *ptf) {
- IRO_ASSERT(4233, ptf != NULL);
-
- return ptf->funcModifies;
-}
-
-CW_INLINE LocationSet *PartialTransferFunction_returnLocation(PartialTransferFunction *ptf) {
- IRO_ASSERT(4249, ptf != NULL);
-
- if (!ptf->returnLocation) {
- PAMemoryBlock *block;
- LocationSet *ls;
-
- block = PAMemoryBlock_New();
- PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_LOCALVAR, NULL);
- ls = LocationSet_New();
- LocationSet_InitKnown(ls, block, cint64_zero, 0, TYPE(&void_ptr));
- ptf->returnLocation = ls;
- }
-
- return ptf->returnLocation;
-}
-
-CW_INLINE IROLinear *PTF_sub_48B980(PartialTransferFunction *ptf) {
- IRO_ASSERT(4265, ptf != NULL);
-
- return ptf->context.nd;
-}
-
-CW_INLINE PartialTransferFunction *PTF_sub_48B970(PartialTransferFunction *ptf) {
- IRO_ASSERT(4271, ptf != NULL);
-
- return ptf->context.ptf;
-}
-
-CW_INLINE void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boolean value) {
- IRO_ASSERT(4298, ptf != NULL);
-
- ptf->x10 = (value != 0) ? 1 : 0;
-}
-
-CW_INLINE PTFList *PTFList_New(void) {
- PTFList *ptfList = IRO_malloc(sizeof(PTFList));
-
- IRO_ASSERT(4393, ptfList != NULL);
-#ifdef IRO_DEBUG
- ptfList->ptf = NULL;
- ptfList->otherPTFs = NULL;
-#endif
- return ptfList;
-}
-
-CW_INLINE void PTFList_Delete(PTFList *ptfList) {
- IRO_ASSERT(4405, ptfList != NULL);
- IRO_ASSERT(4406, ptfList->ptf == NULL);
- IRO_ASSERT(4407, ptfList->otherPTFs == NULL);
- IRO_DEBUG_CLEAR(ptfList, sizeof(PTFList));
- IRO_free(ptfList);
-}
-
-CW_INLINE void PTFList_Init(PTFList *ptfList) {
- IRO_ASSERT(4417, ptfList != NULL);
-
- ptfList->ptf = NULL;
- ptfList->otherPTFs = NULL;
-}
-
-CW_INLINE void PTFList_Term(PTFList *ptfList) {
- IRO_ASSERT(4435, ptfList != NULL);
-
- PTFList_RemoveAll(ptfList);
-
-#ifdef IRO_DEBUG
- ptfList->ptf = NULL;
- ptfList->otherPTFs = NULL;
-#endif
-}
-
-CW_INLINE void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunction *, void *), void *refcon) {
- IRO_ASSERT(4478, ptfList != NULL);
- IRO_ASSERT(4479, action != NULL);
- IRO_ASSERT(4480, refcon == NULL || refcon != NULL);
-
- while (ptfList && ptfList->ptf) {
- action(ptfList->ptf, refcon);
- ptfList = ptfList->otherPTFs;
- }
-}
-
-CW_INLINE PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTransferFunction *ptf) {
- IRO_ASSERT(4490, ptfList != NULL);
- IRO_ASSERT(4491, ptf != NULL);
-
- while (ptfList && ptfList->ptf) {
- if (ptfList->ptf == ptf)
- return ptfList->ptf;
-
- ptfList = ptfList->otherPTFs;
- }
-
- return NULL;
-}
-
-CW_INLINE PartialTransferFunction *PTFList_FindFirst(PTFList *ptfList) {
- IRO_ASSERT(4502, ptfList != NULL);
-
- return ptfList->ptf;
-}
-
-CW_INLINE void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) {
- IRO_ASSERT(4511, ptfList != NULL);
- IRO_ASSERT(4512, ptf != NULL);
-
- if (ptfList->ptf) {
- PTFList *newList = PTFList_New();
- PTFList_Init(newList);
- newList->ptf = ptfList->ptf;
- newList->otherPTFs = ptfList->otherPTFs;
- ptfList->otherPTFs = newList;
- }
-
- ptfList->ptf = ptf;
-}
-
-CW_INLINE void PTFList_sub_48A050(PTFList *ptfList, PartialTransferFunction *ptf) {
- IRO_ASSERT(4529, ptfList != NULL);
- IRO_ASSERT(4530, ptf != NULL);
-
- if (!PTFList_sub_48A0F0(ptfList, ptf))
- PTFList_sub_48A080(ptfList, ptf);
-}
-
-CW_INLINE void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) {
- PTFList *prev;
- PTFList *tmp;
-
- IRO_ASSERT(4542, ptfList != NULL);
- IRO_ASSERT(4543, ptf != NULL);
-
- prev = NULL;
- while (ptfList && ptfList->ptf) {
- if (ptfList->ptf == ptf) {
- if (!prev) {
- if (ptfList->otherPTFs == NULL) {
- ptfList->ptf = NULL;
- } else {
- tmp = ptfList->otherPTFs;
- ptfList->ptf = ptfList->otherPTFs->ptf;
- ptfList->otherPTFs = ptfList->otherPTFs->otherPTFs;
- tmp->ptf = NULL;
- tmp->otherPTFs = NULL;
- PTFList_Term(tmp);
- PTFList_Delete(tmp);
- }
- } else {
- prev->otherPTFs = ptfList->otherPTFs;
- ptfList->ptf = NULL;
- ptfList->otherPTFs = NULL;
- PTFList_Term(ptfList);
- PTFList_Delete(ptfList);
- }
- return;
- }
-
- prev = ptfList;
- ptfList = ptfList->otherPTFs;
- }
-}
-
-CW_INLINE void PTFList_RemoveAll(PTFList *ptfList) {
- IRO_ASSERT(4582, ptfList != NULL);
-
- while (ptfList && ptfList->ptf)
- PTFList_Remove(ptfList, ptfList->ptf);
-}
diff --git a/compiler_and_linker/unsorted/IroPropagate.c b/compiler_and_linker/unsorted/IroPropagate.c
deleted file mode 100644
index 401250c..0000000
--- a/compiler_and_linker/unsorted/IroPropagate.c
+++ /dev/null
@@ -1,593 +0,0 @@
-#include "compiler/IroPropagate.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroEval.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/objects.h"
-#include "compiler/CExpr.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CParser.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmPPC.h"
-
-IROAssign *IRO_FirstAssign;
-IROAssign *IRO_LastAssign;
-SInt32 IRO_NumAssign;
-
-static Boolean VarIsUsedInOtherFNodes(VarRecord *var, IRONode *node) {
- if (var->defs && var->uses) {
- IROUse *use;
- IRODef *def = NULL;
- for (use = var->uses; use; use = use->varnext) {
- if (!def && use->node == node && use->linear && !(use->linear->flags & IROLF_Assigned)) {
- for (def = var->defs; def; def = def->varnext) {
- if (Bv_IsBitSet(def->index, use->x18))
- break;
- }
- }
- }
-
- if (def) {
- for (use = var->uses; use; use = use->varnext) {
- if (use->node != node && use->linear && !(use->linear->flags & IROLF_Assigned)) {
- if (Bv_IsBitSet(def->index, use->x18))
- return 1;
- }
- }
- }
- } else {
- IROLinear *linear;
- IRONode *scan;
- for (scan = IRO_FirstNode; scan; scan = scan->nextnode) {
- if (scan != node) {
- linear = scan->first;
- while (1) {
- if (!linear)
- break;
-
- if (IRO_IsVariable(linear) && !(linear->flags & IROLF_Assigned)) {
- if (IRO_FindVar(linear->u.diadic.left->u.node->data.objref, 0, 1) == var)
- return 1;
- }
-
- if (linear == scan->last)
- break;
- linear = linear->next;
- }
- }
- }
- IRO_CheckForUserBreak();
- }
-
- return 0;
-}
-
-static void GetExprUses(IROLinear *linear, Boolean isFirst) {
- if (isFirst && IS_LINEAR_ENODE(linear, EOBJREF)) {
- Object *obj = linear->u.node->data.objref;
- if ((linear->flags & IROLF_Ind) && (!(linear->flags & IROLF_Assigned) || (linear->flags & IROLF_Used))) {
- VarRecord *var = IRO_FindVar(obj, 0, 1);
- if (var)
- Bv_SetBit(var->index, IRO_VarKills);
- }
- }
-}
-
-static void GetExprKills(IROLinear *linear, Boolean isFirst) {
- if (isFirst)
- IRO_GetKills(linear);
-}
-
-static void CheckUnorderedRegionForDefs(IROLinear *linear, BitVector *a, BitVector *b, Boolean *flag) {
- Bv_Clear(a);
- Bv_Clear(IRO_VarKills);
- IRO_WalkTree(linear, GetExprKills);
- Bv_Or(IRO_VarKills, a);
- if (Bv_BitsInCommon(a, b))
- *flag = 1;
-}
-
-static void CheckUnorderedRegionsForDefs(IROLinear *linear1, IROLinear *linear2, BitVector *a, BitVector *b, Boolean *flag) {
- int i;
-
- switch (linear1->type) {
- case IROLinearOp2Arg:
- if (linear1->nodetype == ELAND) break;
- if (linear1->nodetype == ELOR) break;
- if (linear1->nodetype == ECOMMA) break;
- if (linear1->u.diadic.left != linear2)
- CheckUnorderedRegionForDefs(linear1->u.diadic.left, a, b, flag);
- if (linear1->u.diadic.right != linear2)
- CheckUnorderedRegionForDefs(linear1->u.diadic.right, a, b, flag);
- break;
- case IROLinearFunccall:
- if (linear1->u.funccall.linear8 != linear2)
- CheckUnorderedRegionForDefs(linear1->u.funccall.linear8, a, b, flag);
- for (i = 0; !*flag && i < linear1->u.funccall.argCount; i++) {
- if (linear1->u.funccall.args[i] != linear2)
- CheckUnorderedRegionForDefs(linear1->u.funccall.args[i], a, b, flag);
- }
- break;
- }
-}
-
-static Boolean PropagationHasDefsInUnorderedRegions(IROLinear *a, IROLinear *b) {
- Boolean flag;
- IROLinear *father;
- BitVector *bv1;
- BitVector *bv2;
- VarRecord *var;
-
- flag = 0;
- if ((father = IRO_LocateFather(a))) {
- Bv_AllocVector(&bv1, IRO_NumVars + 1);
- Bv_AllocVector(&bv2, IRO_NumVars + 1);
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- IRO_WalkTree(b, GetExprUses);
- Bv_Or(IRO_VarKills, bv2);
- var = IRO_FindVar(a->u.diadic.left->u.node->data.objref, 0, 1);
- Bv_SetBit(var->index, bv2);
- while (father && !flag) {
- CheckUnorderedRegionsForDefs(father, a, bv1, bv2, &flag);
- a = father;
- father = IRO_LocateFather(father);
- }
- }
-
- return flag;
-}
-
-int IRO_IsRegable(Object *obj) {
- if (obj->datatype == DLOCAL && obj->u.var.info)
- return obj->u.var.info->noregister == 0;
- return 0;
-}
-
-static Boolean IsPropagatable(IROLinear *linear) {
- Object *obj;
- Object *obj2;
-
- if (IS_LINEAR_DIADIC(linear, EASS) && (obj = IRO_IsVariable(linear->u.diadic.left)) && obj->type == linear->rtype && !is_volatile_object(obj)) {
- if (linear->u.diadic.left->flags & IROLF_BitfieldIndirect) {
- if (!IRO_IsConstant(linear->u.diadic.right))
- return 0;
- else
- return 1;
- }
-
- if (IRO_IsConstant(linear->u.diadic.right))
- return 1;
-
- if ((obj2 = IRO_IsVariable(linear->u.diadic.right)) && !is_volatile_object(obj2) && IRO_TypesEqual(obj->type, linear->rtype)) {
- if (!Inline_IsObjectData(linear->u.diadic.right->u.monadic->u.node->data.objref)) {
- if (IRO_IsRegable(obj) && !IRO_IsRegable(obj2))
- return 0;
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static Boolean IsIntGenKillCandidate(IROLinear *linear) {
- if (linear->type == IROLinearFunccall)
- return 1;
-
- if (IRO_IsAssignOp[linear->nodetype] && (linear->type == IROLinearOp1Arg || linear->type == IROLinearOp2Arg))
- return 1;
-
- if (linear->type == IROLinearAsm)
- return 1;
-
- return 0;
-}
-
-static Boolean IsPropagatableExpr(IROLinear *linear, IROList *list) {
- Object *obj;
- if (IS_LINEAR_DIADIC(linear, EASS) && !(linear->flags & IROLF_Reffed)) {
- if ((obj = IRO_IsVariable(linear->u.diadic.left)) && !is_volatile_object(obj) && !(linear->u.diadic.left->flags & IROLF_BitfieldIndirect)) {
- if (!IRO_IsRegable(obj))
- return 0;
- if (IS_LINEAR_ENODE(linear->u.diadic.right, ESTRINGCONST))
- return 0;
-
- IRO_FindDepends(linear->u.diadic.right);
- if (!IRO_NotSubable)
- return 1;
- }
- }
-
- return 0;
-}
-
-static void ClearAvailibilityOnNode(IRONode *node, UInt32 bit) {
- IRONode *scan;
-
- for (scan = node->nextnode; scan; scan = scan->nextnode)
- Bv_ClearBit(bit, scan->x16);
-}
-
-Boolean IRO_CopyAndConstantPropagation(void) {
- IROAssign *ass2;
- IROAssign *ass;
- IROLinear *linear;
- IRONode *node;
- VarRecord *var;
- BitVector *bv;
- Boolean flag;
- Boolean result;
-
- IRO_FirstAssign = NULL;
- IRO_NumAssign = 0;
- result = 0;
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- linear = node->first;
- while (1) {
- if (!linear)
- break;
-
- if (IsPropagatable(linear) && (var = IRO_FindAssigned(linear))) {
- IROAssign *newass;
- IRO_Dump("Found propagatable assignment at: %d\n", linear->index);
- newass = oalloc(sizeof(IROAssign));
- newass->linear = linear;
- newass->next = NULL;
- newass->index = ++IRO_NumAssign;
- newass->varIndex = var->index;
- newass->linear2 = linear->u.diadic.right;
- newass->var = NULL;
- newass->varObj = IRO_IsVariable(linear->u.diadic.right);
- newass->node = node;
- if (newass->varObj)
- newass->var = IRO_FindVar(newass->varObj, 0, 1);
- if (!IRO_FirstAssign)
- IRO_FirstAssign = newass;
- else
- IRO_LastAssign->next = newass;
- IRO_LastAssign = newass;
- }
-
- if (linear == node->last)
- break;
- linear = linear->next;
- }
- }
-
- IRO_CheckForUserBreak();
-
- node = IRO_FirstNode;
- ass = IRO_FirstAssign;
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
- while (node) {
- Bv_AllocVector(&node->x16, IRO_NumAssign);
- if (node != IRO_FirstNode)
- Bv_Set(node->x16);
- Bv_AllocVector(&node->x22, IRO_NumAssign);
- Bv_AllocVector(&node->x1E, IRO_NumAssign);
- Bv_AllocVector(&node->x2A, IRO_NumAssign);
- node->x1A = NULL;
-
- linear = node->first;
- while (1) {
- if (!linear)
- break;
-
- if (IsIntGenKillCandidate(linear)) {
- //IROAssign *ass2;
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(linear);
-
- for (ass2 = IRO_FirstAssign; ass2; ass2 = ass2->next) {
- if (Bv_IsBitSet(ass2->varIndex, IRO_VarKills)) {
- Bv_SetBit(ass2->index, node->x22);
- Bv_ClearBit(ass2->index, node->x1E);
- }
- if (ass2->var && Bv_IsBitSet(ass2->var->index, IRO_VarKills)) {
- Bv_SetBit(ass2->index, node->x22);
- Bv_ClearBit(ass2->index, node->x1E);
- }
- }
- }
-
- while (ass && ass->linear == linear) {
- Bv_SetBit(ass->index, node->x1E);
- ass = ass->next;
- }
-
- if (linear == node->last)
- break;
- linear = linear->next;
- }
-
- Bv_Copy(node->x16, node->x2A);
- Bv_Minus(node->x22, node->x2A);
- Bv_Or(node->x1E, node->x2A);
- node = node->nextnode;
- }
-
- IRO_CheckForUserBreak();
-
- Bv_AllocVector(&bv, IRO_NumAssign);
- do {
- flag = 0;
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node == IRO_FirstNode) {
- Bv_Clear(bv);
- } else {
- UInt16 i;
- Bv_Set(bv);
- for (i = 0; i < node->numpred; i++)
- Bv_And(IRO_NodeTable[node->pred[i]]->x2A, bv);
- }
-
- if (!Bv_Compare(bv, node->x16)) {
- flag = 1;
- Bv_Copy(bv, node->x16);
- }
-
- Bv_Copy(node->x16, node->x2A);
- Bv_Minus(node->x22, node->x2A);
- Bv_Or(node->x1E, node->x2A);
- }
- } while (flag);
-
- IRO_CheckForUserBreak();
-
- node = IRO_FirstNode;
- ass = IRO_FirstAssign;
- while (node) {
- IRO_Avail = node->x16;
- linear = node->first;
- while (1) {
- if (!linear)
- break;
-
- if (IRO_IsVariable(linear) && !(linear->flags & IROLF_Assigned)) {
- if ((var = IRO_FindVar(linear->u.diadic.left->u.node->data.objref, 0, 1))) {
- //IROAssign *ass2;
- for (ass2 = IRO_FirstAssign; ass2; ass2 = ass2->next) {
- if (
- ass2->varIndex == var->index &&
- Bv_IsBitSet(ass2->index, IRO_Avail) &&
- (IRO_IsConstant(ass2->linear2) || node->loopdepth <= ass2->node->loopdepth) &&
- !PropagationHasDefsInUnorderedRegions(linear, ass2->linear2)
- ) {
- if (ass2->linear2->type == IROLinearOperand && IRO_is_CPtypeequal(linear->rtype, ass2->linear->u.diadic.left->rtype)) {
- ENode *enode = IRO_NewENode(ass2->linear2->u.node->type);
- *enode = *ass2->linear2->u.node;
- if (enode->type == EINTCONST) {
- if (linear->flags & IROLF_BitfieldIndirect) {
- IRO_TruncateBitfieldValueToType(&enode->data.intval, linear->rtype, var->x1A);
- enode->rtype = linear->rtype;
- result = 1;
- } else {
- IRO_TruncateValueToType(&enode->data.intval, linear->rtype);
- enode->rtype = linear->rtype;
- }
- }
- linear->u.monadic->type = IROLinearNop;
- linear->type = IROLinearOperand;
- linear->u.node = enode;
- } else if (ass2->varObj && IRO_is_CPtypeequal(linear->rtype, ass2->linear->rtype)) {
- linear->u.diadic.left->u.node = create_objectrefnode(ass2->varObj);
- if (ass2->linear2->flags & IROLF_BitfieldIndirect)
- linear->flags |= IROLF_BitfieldIndirect;
- }
- IRO_Dump("Found propagation at %d from %d\n", linear->index, ass2->linear->index);
- break;
- }
- }
- }
- } else if (linear->type == IROLinearAsm) {
- IAEffects effects;
- int i;
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
-
- for (i = 0; i < effects.numoperands; i++) {
- if (effects.operands[i].type == IAEffect_0 && effects.operands[i].offset == 0 && effects.operands[i].object->type->size == effects.operands[i].size) {
- if ((var = IRO_FindVar(effects.operands[i].object, 0, 1))) {
- //IROAssign *ass2;
- for (ass2 = IRO_FirstAssign; ass2; ass2 = ass2->next) {
- if (ass2->varIndex == var->index && Bv_IsBitSet(ass2->index, IRO_Avail) && ass2->linear->rtype->size == effects.operands[i].size) {
- ENode *enode;
- if (ass2->varObj)
- enode = create_objectrefnode(ass2->varObj);
- else if (ass2->linear2->type == IROLinearOperand)
- enode = ass2->linear2->u.node;
- else
- CError_FATAL(768);
- CodeGen_PropagateIntoAsm(linear->u.asm_stmt, effects.operands[i].object, enode);
- break;
- }
- }
- }
- }
- }
- }
-
- if (IsIntGenKillCandidate(linear)) {
- //IROAssign *ass2;
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(linear);
-
- for (ass2 = IRO_FirstAssign; ass2; ass2 = ass2->next) {
- if (Bv_IsBitSet(ass2->varIndex, IRO_VarKills)) {
- Bv_ClearBit(ass2->index, IRO_Avail);
- }
- if (ass2->var && Bv_IsBitSet(ass2->var->index, IRO_VarKills)) {
- Bv_ClearBit(ass2->index, IRO_Avail);
- }
- }
-
- while (ass && ass->linear == linear) {
- Bv_SetBit(ass->index, IRO_Avail);
- ass = ass->next;
- }
- }
-
- if (linear == node->last)
- break;
- linear = linear->next;
- }
- node = node->nextnode;
- }
-
- IRO_CheckForUserBreak();
-
- return result;
-}
-
-void IRO_ExpressionPropagation(void) {
- IRONode *node;
- IROLinear *linear;
- Object *obj;
- VarRecord *var;
- IROAssign *ass;
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- IRO_FirstAssign = NULL;
- IRO_LastAssign = NULL;
- IRO_NumAssign = 0;
-
- linear = node->first;
- while (1) {
- IROList list;
- if (!linear)
- break;
-
- IRO_InitList(&list);
- if (IsPropagatableExpr(linear, &list)) {
- if ((var = IRO_FindAssigned(linear))) {
- IRO_Dump("Found propagatable expression assignment at: %d\n", linear->index);
- ass = oalloc(sizeof(IROAssign));
- ass->linear = linear;
- ass->next = NULL;
- ass->index = ++IRO_NumAssign;
- ass->varIndex = var->index;
- ass->linear2 = linear->u.diadic.right;
- ass->x20 = 0;
- ass->node = node;
- IRO_FindDepends(linear->u.diadic.right);
- ass->depends = IRO_Depends;
- if (!IRO_FirstAssign) {
- IRO_FirstAssign = ass;
- ass->prev = NULL;
- } else {
- IRO_LastAssign->next = ass;
- ass->prev = IRO_LastAssign;
- }
- IRO_LastAssign = ass;
- }
- }
-
- if (IRO_IsVariable(linear) && !(linear->flags & IROLF_Assigned)) {
- if ((var = IRO_FindVar(linear->u.monadic->u.node->data.objref, 0, 1))) {
- for (ass = IRO_LastAssign; ass; ass = ass->prev) {
- if (ass->varIndex == var->index)
- ass->x20++;
- }
- }
- }
-
- if (linear == node->last)
- break;
- linear = linear->next;
- }
-
- Bv_AllocVector(&IRO_Avail, IRO_NumAssign);
-
- linear = node->first;
- while (1) {
- if (!linear)
- break;
-
- if (IRO_IsVariable(linear) && !(linear->flags & IROLF_Assigned)) {
- if ((var = IRO_FindVar(linear->u.monadic->u.node->data.objref, 0, 1))) {
- for (ass = IRO_FirstAssign; ass; ass = ass->next) {
- if (ass->varIndex == var->index && Bv_IsBitSet(ass->index, IRO_Avail) && !PropagationHasDefsInUnorderedRegions(linear, ass->linear2)) {
- if (ass->linear2->type == IROLinearOperand && IRO_is_CPtypeequal(linear->rtype, ass->linear->u.diadic.left->rtype)) {
- ENode *enode = IRO_NewENode(ass->linear2->u.node->type);
- *enode = *ass->linear2->u.node;
- if (enode->type == EINTCONST) {
- IRO_TruncateValueToType(&enode->data.intval, linear->rtype);
- enode->rtype = linear->rtype;
- } else if (enode->type == EOBJREF) {
- IROLinear *tmp = IRO_LocateFather(linear);
- if (tmp && (tmp->flags & IROLF_Assigned))
- linear->flags |= IROLF_Assigned;
- }
- linear->u.monadic->type = IROLinearNop;
- linear->type = IROLinearOperand;
- linear->u.node = enode;
- } else if (IRO_IsVariable(ass->linear2) && IRO_is_CPtypeequal(linear->rtype, ass->linear->rtype)) {
- linear->u.monadic->u.node = create_objectrefnode(ass->linear2->u.monadic->u.node->data.objref);
- if (ass->linear2->flags & IROLF_BitfieldIndirect)
- linear->flags |= IROLF_BitfieldIndirect;
- } else if (IRO_is_CPtypeequal(linear->rtype, ass->linear->rtype) && ass->x20 == 1 && !VarIsUsedInOtherFNodes(var, node)) {
- IROList list;
- IRO_InitList(&list);
- IRO_DuplicateExpr(ass->linear->u.diadic.right, &list);
- if (IS_TYPE_FLOAT(ass->linear->rtype)) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg);
- tmp->index = ++IRO_NumLinear;
- tmp->rtype = ass->linear->rtype;
- tmp->nodetype = ETYPCON;
- tmp->nodeflags = ENODE_FLAG_80;
- tmp->u.monadic = list.tail;
- IRO_AddToList(tmp, &list);
- }
- IRO_PasteAfter(list.head, list.tail, linear);
- IRO_LocateFather_Cut_And_Paste(linear, list.tail);
- linear = list.tail;
- }
- IRO_Dump("Found expression propagation at %d from %d\n", linear->index, ass->linear->index);
- break;
- }
- }
- }
- }
-
- if (linear->type != IROLinearNop && IsIntGenKillCandidate(linear)) {
- Bv_Clear(IRO_VarKills);
- IRO_GetKills(linear);
- for (ass = IRO_FirstAssign; ass; ass = ass->next) {
- if (Bv_IsBitSet(ass->varIndex, IRO_VarKills))
- Bv_ClearBit(ass->index, IRO_Avail);
- if ((obj = IRO_IsVariable(ass->linear->u.diadic.right))) {
- if ((var = IRO_FindVar(obj, 0, 1))) {
- if (Bv_IsBitSet(var->index, IRO_VarKills))
- Bv_ClearBit(ass->index, IRO_Avail);
- }
- } else {
- IROList list;
- IRO_InitList(&list);
- IRO_Depends = ass->depends;
- IRO_FindDepends_NoAlloc(ass->linear->u.diadic.right);
- if (Bv_BitsInCommon(IRO_VarKills, ass->depends))
- Bv_ClearBit(ass->index, IRO_Avail);
- }
- }
-
- for (ass = IRO_FirstAssign; ass; ass = ass->next) {
- IRO_Depends = ass->depends;
- IRO_FindDepends_NoAlloc(ass->linear->u.diadic.right);
- if (ass->linear == linear && !Bv_IsBitSet(ass->varIndex, ass->depends))
- Bv_SetBit(ass->index, IRO_Avail);
- }
- }
-
- if (linear == node->last)
- break;
- linear = linear->next;
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
diff --git a/compiler_and_linker/unsorted/IroRangePropagation.c b/compiler_and_linker/unsorted/IroRangePropagation.c
deleted file mode 100644
index d15ef86..0000000
--- a/compiler_and_linker/unsorted/IroRangePropagation.c
+++ /dev/null
@@ -1,774 +0,0 @@
-#include "compiler/IroRangePropagation.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CInt64.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef enum ERangeType {
- ERangeType0,
- ERangeType1,
- ERangeType2,
- ERangeType3
-} ERangeType;
-
-typedef struct ERange {
- ERangeType type;
- CInt64 upper;
- CInt64 lower;
-} ERange;
-
-typedef struct ERecord {
- Object *object;
- ERange *range;
- struct ERecord *next;
-} ERecord;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static ERecord *ERangeFirst;
-static ERecord *ERangeLast;
-
-static ERange *ERnewERange(ERangeType type) {
- ERange *range;
-
- range = oalloc(sizeof(ERange));
- range->type = type;
- return range;
-}
-
-static ERecord *ERnewRecord(Object *object, ERange *range) {
- ERecord *record;
-
- record = oalloc(sizeof(ERecord));
- record->object = object;
- record->range = range;
- record->next = ERangeFirst;
- ERangeFirst = record;
- if (!ERangeLast)
- ERangeLast = record;
- return record;
-}
-
-static ERecord *ERecordFound(Object *obj) {
- ERecord *scan;
-
- scan = ERangeFirst;
- while (scan && obj != scan->object)
- scan = scan->next;
-
- return scan;
-}
-
-static Boolean EREandHasNoUse(ERange *range, CInt64 val) {
- UInt16 i;
- CInt64 v11;
- CInt64 work;
-
- i = 0;
- work = range->upper;
- while (CInt64_NotEqual(work = CInt64_ShrU(work, cint64_one), cint64_zero))
- i++;
-
- if (CInt64_NotEqual(range->upper, cint64_zero))
- i++;
-
- CInt64_SetULong(&work, i);
- v11 = CInt64_Sub(CInt64_Shl(cint64_one, work), cint64_one);
- if (CInt64_NotEqual(cint64_zero, CInt64_And(CInt64_Inv(val), v11)))
- return 0;
- else
- return 1;
-}
-
-static void ERcheckOverflow(ERange *range, Type *type) {
- CInt64 typeSize;
- CInt64 work;
- CInt64 work2;
- CInt64 value3;
-
- if (!range)
- return;
-
- if (!IS_TYPE_INT(type)) {
- range->type = ERangeType3;
- return;
- }
-
- CInt64_SetLong(&typeSize, type->size);
- CInt64_SetLong(&value3, 3);
-
- if (IRO_IsUnsignedType(type)) {
- if (type->size < 8) {
- work = CInt64_Sub(CInt64_Shl(cint64_one, CInt64_Shl(typeSize, value3)), cint64_one);
- if (CInt64_GreaterU(range->upper, work))
- range->type = ERangeType3;
- } else {
- range->type = ERangeType3;
- }
- } else {
- if (type->size < 8) {
- work = CInt64_Sub(CInt64_Shl(cint64_one, CInt64_Sub(CInt64_Shl(typeSize, value3), cint64_one)), cint64_one);
- work2 = CInt64_Shl(cint64_negone, CInt64_Sub(CInt64_Shl(typeSize, value3), cint64_one));
- if (CInt64_Greater(range->upper, work) || CInt64_Less(range->lower, work2))
- range->type = ERangeType3;
- } else {
- range->type = ERangeType3;
- }
- }
-}
-
-static void ERinvalidAll(void) {
- ERecord *record;
-
- for (record = ERangeFirst; record; record = record->next)
- record->range->type = ERangeType3;
-}
-
-static void SetRangesForKillsByIndirectAssignment(IROLinear *nd) {
- IROListNode *list;
- IROListNode *scan;
- IROLinear *inner;
- Boolean failed;
- IROListNode *resultList;
- IROLinear *scannd;
- Boolean foundObjRef;
- ERecord *record;
- ERange *range;
- IROListNode *next;
- Object *obj;
- IROLinear *analysend;
- Object *proc;
-
- failed = 0;
- if (nd->type == IROLinearOp2Arg)
- inner = nd->u.diadic.left;
- else
- inner = nd->u.monadic;
-
- if (
- inner &&
- inner->type == IROLinearOp1Arg &&
- inner->nodetype == EINDIRECT &&
- (analysend = inner->u.monadic) &&
- copts.opt_pointer_analysis &&
- analysend->pointsToFunction &&
- (proc = FunctionName)
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(proc, analysend, &resultList);
-
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- failed = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- break;
- }
- }
-
- if (!foundObjRef) {
- failed = 1;
- break;
- }
- }
-
- if (!failed) {
- for (; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- CError_ASSERT(302, obj != NULL);
-
- range = nd->x16;
- if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
- range = inner->x16;
-
- record = ERecordFound(obj);
- if (!record)
- ERnewRecord(obj, range);
- else
- record->range = range;
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- failed = 1;
- }
- } else {
- failed = 1;
- }
-
- if (failed) {
- ERinvalidAll();
- nd->x16 = ERnewERange(ERangeType3);
- }
-}
-
-static void InvalidateRangesForKillsByFunctionCall(IROLinear *nd) {
- IROListNode *scan;
- IROLinear *scannd;
- Boolean failed;
- Boolean foundObjRef;
- IROListNode *list;
- IROListNode *resultList;
- ERecord *record;
- IROListNode *next;
- Object *obj;
- IROLinear *analysend;
- Object *proc;
- ObjectList *olist;
- ObjectList *killList;
-
- failed = 0;
-
- if (
- (analysend = nd->u.funccall.linear8) &&
- copts.opt_pointer_analysis &&
- analysend->pointsToFunction &&
- (proc = FunctionName)
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(proc, analysend, &resultList);
-
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- failed = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = scannd->u.node->data.objref;
- CError_ASSERT(385, obj != NULL);
-
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, nd, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- if (!olist->object) {
- failed = 1;
- break;
- }
- }
-
- while (killList) {
- olist = killList->next;
- IRO_free(killList);
- killList = olist;
- }
-
- if (failed)
- break;
- }
- }
-
- if (!foundObjRef)
- failed = 1;
- if (failed)
- break;
- }
-
- if (!failed) {
- for (list = resultList; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, nd, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- if ((record = ERecordFound(olist->object)))
- record->range->type = ERangeType3;
- }
-
- while (killList) {
- olist = killList->next;
- IRO_free(killList);
- killList = olist;
- }
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- failed = 1;
- }
- } else {
- failed = 1;
- }
-
- if (failed)
- ERinvalidAll();
-}
-
-static void ERfoldOperand(IROLinear *nd) {
- switch (nd->u.node->type) {
- case EOBJREF:
- nd->x16 = NULL;
- break;
- case EINTCONST:
- nd->x16 = ERnewERange(ERangeType0);
- nd->x16->upper = nd->x16->lower = nd->u.node->data.intval;
- break;
- case EFLOATCONST:
- case ESTRINGCONST:
- nd->x16 = ERnewERange(ERangeType0);
- break;
- }
-}
-
-static Boolean ERfoldExpr(IROLinear *nd) {
- ERecord *record;
- ERange *range;
- IROLinear *tmp;
- IROLinear *inner;
- Object *obj;
-
- switch (nd->nodetype) {
- case EINDIRECT:
- inner = nd->u.monadic;
- if (IS_TYPE_INT(nd->rtype)) {
- if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF) {
- if (!inner->x16 && (obj = inner->u.node->data.objref)) {
- if ((record = ERecordFound(obj))) {
- inner->x16 = ERnewERange(ERangeType3);
- *inner->x16 = *record->range;
- } else {
- inner->x16 = ERnewERange(ERangeType3);
- inner->x16->upper = cint64_max;
- inner->x16->lower = cint64_min;
- ERnewRecord(obj, inner->x16);
- }
- }
- nd->x16 = inner->x16;
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF && !inner->x16)
- inner->x16 = ERnewERange(ERangeType3);
- nd->x16 = ERnewERange(ERangeType3);
- }
- break;
- case EAND:
- case EANDASS:
- if (IRO_IsIntConstant(nd->u.diadic.right)) {
- CInt64 val = nd->u.diadic.right->u.node->data.intval;
- nd->x16 = ERnewERange(ERangeType1);
- nd->x16->upper = val;
- nd->x16->lower = cint64_zero;
- if (
- (range = nd->u.diadic.left->x16) &&
- range->type != ERangeType3 &&
- CInt64_LessEqualU(range->upper, val) &&
- CInt64_LessEqualU(range->lower, val) &&
- EREandHasNoUse(range, val) &&
- !IRO_HasSideEffect(nd->u.diadic.left)
- ) {
- IRO_Dump("eliminating redundant EAND %" PRId32 "; upperBound==0x%x, lowerBound==0x%x, Constant==0x%x\n",
- nd->index,
- CInt64_GetULong(&range->upper),
- CInt64_GetULong(&range->upper),
- CInt64_GetULong(&val)
- );
- IRO_NopOut(nd->u.diadic.right);
- nd->type = IROLinearNop;
- nd->expr = NULL;
- tmp = nd->u.diadic.left;
- nd->u.diadic.left = nd->u.diadic.right;
- if (!IRO_LocateFather_Cut_And_Paste(nd, tmp)) {
- tmp->flags &= ~IROLF_Reffed;
- if (IRO_IsVariable(tmp))
- IRO_NopOut(tmp);
- }
- }
- } else {
- if (nd->u.diadic.right->x16) {
- nd->x16 = ERnewERange(ERangeType3);
- *nd->x16 = *nd->u.diadic.right->x16;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ELOGNOT:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case ELAND:
- case ELOR:
- nd->x16 = ERnewERange(ERangeType1);
- nd->x16->upper = cint64_one;
- nd->x16->lower = cint64_zero;
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EBINNOT:
- case EFORCELOAD:
- case EXOR:
- case EOR:
- case EXORASS:
- case EORASS:
- case ECOMMA:
- case ETYPCON:
- case EBITFIELD:
- case ECOND:
- case ENULLCHECK:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- case EASS:
- if (IS_TYPE_INT(nd->rtype))
- nd->x16 = nd->u.diadic.right->x16;
- break;
- case EMUL:
- case EMULV:
- case EMULASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_MulU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_MulU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16->upper = CInt64_Mul(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Mul(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EDIV:
- case EDIVASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (!CInt64_IsZero(&nd->u.diadic.right->x16->lower) && !CInt64_IsZero(&nd->u.diadic.right->x16->upper)) {
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_DivU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_DivU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Div(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Div(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EMODULO:
- case EMODASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (!CInt64_IsZero(&nd->u.diadic.right->x16->lower) && !CInt64_IsZero(&nd->u.diadic.right->x16->upper)) {
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_ModU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_ModU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Mod(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Mod(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EADDV:
- case EADD:
- case EADDASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Add(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Add(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESUBV:
- case ESUB:
- case ESUBASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Sub(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Sub(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESHL:
- case ESHLASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Shl(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Shl(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESHR:
- case ESHRASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_ShrU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_ShrU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Shr(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Shr(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPOSTINC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- *nd->x16 = *range;
- range->upper = CInt64_Add(range->upper, cint64_one);
- range->lower = CInt64_Add(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPOSTDEC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- *nd->x16 = *range;
- range->upper = CInt64_Sub(range->upper, cint64_one);
- range->lower = CInt64_Sub(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPREINC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- nd->x16->upper = CInt64_Add(range->upper, cint64_one);
- nd->x16->lower = CInt64_Add(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPREDEC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- nd->x16->upper = CInt64_Sub(range->upper, cint64_one);
- nd->x16->lower = CInt64_Sub(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EMONMIN:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- case EPMODULO:
- case EROTL:
- case EROTR:
- case EBCLR:
- case EBTST:
- case EBSET:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- default:
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- }
-
- if (
- (nd->type == IROLinearOp1Arg || nd->type == IROLinearOp2Arg) &&
- IRO_IsAssignOp[nd->nodetype] &&
- nd->x16 &&
- IS_TYPE_INT(nd->rtype)
- ) {
- IROLinear *x = NULL;
- if (nd->type == IROLinearOp2Arg)
- x = nd->u.diadic.left;
- else if (nd->type == IROLinearOp1Arg)
- x = nd->u.monadic;
-
- if (x->type == IROLinearOp1Arg &&
- x->nodetype == EINDIRECT &&
- (x->u.monadic->nodetype == EINDIRECT || x->u.monadic->nodetype == EADD)) {
- SetRangesForKillsByIndirectAssignment(nd);
- } else {
- obj = NULL;
- if (x)
- obj = IRO_IsVariable(x);
- if (!obj)
- return 0;
-
- range = nd->x16;
- if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
- range = x->x16;
-
- record = ERecordFound(obj);
- if (!record)
- ERnewRecord(obj, range);
- else
- record->range = range;
- }
- }
-
- return nd->x16 != NULL;
-}
-
-static Boolean ERfoldLinear(IROLinear *nd) {
- nd->x16 = 0;
-
- switch (nd->type) {
- case IROLinearNop:
- case IROLinearEnd:
- break;
- case IROLinearOperand:
- ERfoldOperand(nd);
- break;
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- ERfoldExpr(nd);
- break;
- case IROLinearFunccall:
- InvalidateRangesForKillsByFunctionCall(nd);
- break;
- case IROLinearAsm:
- ERinvalidAll();
- break;
- }
-
- return 0;
-}
-
-Boolean IRO_RangePropagateInFNode(void) {
- IRONode *fnode;
- IROLinear *nd;
- Boolean result;
-
- result = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- ERangeFirst = ERangeLast = NULL;
- for (nd = fnode->first; nd != fnode->last; nd = nd->next)
- ERfoldLinear(nd);
- if (ERfoldLinear(nd))
- result = 1;
- }
-
- if (result) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
-
- IRO_CheckForUserBreak();
- return result;
-}
diff --git a/compiler_and_linker/unsorted/IroSubable.c b/compiler_and_linker/unsorted/IroSubable.c
deleted file mode 100644
index 6b8daf0..0000000
--- a/compiler_and_linker/unsorted/IroSubable.c
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "compiler/IroSubable.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroPropagate.h"
-#include "compiler/IroUtil.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-static Boolean IsSubableOp[MAXEXPR];
-
-void IRO_InitializeIsSubableOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- IsSubableOp[i] = 0;
-
- IsSubableOp[EPOSTINC] = 0;
- IsSubableOp[EPOSTDEC] = 0;
- IsSubableOp[EPREINC] = 0;
- IsSubableOp[EPREDEC] = 0;
- IsSubableOp[EINDIRECT] = 0;
- IsSubableOp[EMONMIN] = 1;
- IsSubableOp[EBINNOT] = 1;
- IsSubableOp[ELOGNOT] = 1;
- IsSubableOp[EFORCELOAD] = 0;
- IsSubableOp[EMUL] = 1;
- IsSubableOp[EMULV] = 1;
- IsSubableOp[EDIV] = 1;
- IsSubableOp[EMODULO] = 1;
- IsSubableOp[EADDV] = 1;
- IsSubableOp[ESUBV] = 1;
- IsSubableOp[EADD] = 1;
- IsSubableOp[ESUB] = 1;
- IsSubableOp[ESHL] = 1;
- IsSubableOp[ESHR] = 1;
- IsSubableOp[ELESS] = 0;
- IsSubableOp[EGREATER] = 0;
- IsSubableOp[ELESSEQU] = 0;
- IsSubableOp[EGREATEREQU] = 0;
- IsSubableOp[EEQU] = 0;
- IsSubableOp[ENOTEQU] = 0;
- IsSubableOp[EAND] = 1;
- IsSubableOp[EXOR] = 1;
- IsSubableOp[EOR] = 1;
- IsSubableOp[ELAND] = 0;
- IsSubableOp[ELOR] = 0;
- IsSubableOp[EASS] = 0;
- IsSubableOp[EMULASS] = 0;
- IsSubableOp[EDIVASS] = 0;
- IsSubableOp[EMODASS] = 0;
- IsSubableOp[EADDASS] = 0;
- IsSubableOp[ESUBASS] = 0;
- IsSubableOp[ESHLASS] = 0;
- IsSubableOp[ESHRASS] = 0;
- IsSubableOp[EANDASS] = 0;
- IsSubableOp[EXORASS] = 0;
- IsSubableOp[EORASS] = 0;
- IsSubableOp[ECOMMA] = 0;
- IsSubableOp[EPMODULO] = 0;
- IsSubableOp[EROTL] = 0;
- IsSubableOp[EROTR] = 0;
- IsSubableOp[EBCLR] = 0;
- IsSubableOp[EBTST] = 0;
- IsSubableOp[EBSET] = 0;
- IsSubableOp[ETYPCON] = 0;
- IsSubableOp[EBITFIELD] = 0;
- IsSubableOp[EINTCONST] = 0;
- IsSubableOp[EFLOATCONST] = 0;
- IsSubableOp[ESTRINGCONST] = 0;
- IsSubableOp[ECOND] = 0;
- IsSubableOp[EFUNCCALL] = 0;
- IsSubableOp[EFUNCCALLP] = 0;
- IsSubableOp[EOBJREF] = 0;
- IsSubableOp[EMFPOINTER] = 0;
- IsSubableOp[ENULLCHECK] = 0;
- IsSubableOp[EPRECOMP] = 0;
- IsSubableOp[ETEMP] = 0;
- IsSubableOp[EARGOBJ] = 0;
- IsSubableOp[ELOCOBJ] = 0;
- IsSubableOp[ELABEL] = 0;
- IsSubableOp[ESETCONST] = 0;
- IsSubableOp[ENEWEXCEPTION] = 0;
- IsSubableOp[ENEWEXCEPTIONARRAY] = 0;
- IsSubableOp[EOBJLIST] = 0;
- IsSubableOp[EMEMBER] = 0;
- IsSubableOp[ETEMPLDEP] = 0;
- IsSubableOp[EINSTRUCTION] = 0;
- IsSubableOp[EDEFINE] = 0;
- IsSubableOp[EREUSE] = 0;
- IsSubableOp[EASSBLK] = 0;
- IsSubableOp[EVECTOR128CONST] = 0;
- IsSubableOp[ECONDASS] = 0;
-}
-
-static int IsSubscript(IROLinear *nd) {
- return 0;
-}
-
-Boolean IRO_IsSubableExpression(IROLinear *nd) {
- Object *varobj;
- Boolean result;
-
- switch (nd->type) {
- case IROLinearOp2Arg:
- if (nd->nodetype == EADD || nd->nodetype == ESUB) {
- if (
- IRO_IsConstant(nd->u.diadic.right) &&
- (varobj = IRO_IsVariable(nd->u.diadic.left)) &&
- varobj->datatype == DLOCAL &&
- varobj->u.var.info &&
- !varobj->u.var.info->noregister)
- return 0;
-
- }
- result = IsSubableOp[nd->nodetype] && !IsSubscript(nd);
- return result;
- case IROLinearOp1Arg:
- if (IsSubableOp[nd->nodetype] && !IsSubscript(nd))
- return 1;
-
- if (nd->nodetype == EINDIRECT && !(nd->flags & IROLF_Assigned)) {
- if (nd->flags & IROLF_Ind) {
- nd = nd->u.monadic;
- if (nd->type == IROLinearOperand &&
- nd->u.node->type == EOBJREF &&
- nd->u.node->data.objref->datatype == DLOCAL &&
- nd->u.node->data.objref->u.var.info &&
- !nd->u.node->data.objref->u.var.info->noregister
- )
- return 0;
- return 1;
- }
-
- if (IRO_IsVariable(nd) && IRO_IsRegable(nd->u.monadic->u.node->data.objref))
- return 0;
- return 1;
- } else if (nd->nodetype == ETYPCON && IS_TYPE_INT(nd->rtype) && nd->rtype->size >= nd->u.monadic->rtype->size) {
- return 1;
- } else {
- return 0;
- }
- case IROLinearOperand:
- default:
- return 0;
- }
-}
-
-Boolean IRO_IsVectorTempCandidate(IROLinear *nd) {
- return
- (
- nd->type == IROLinearOp1Arg ||
- nd->type == IROLinearOp2Arg ||
- nd->type == IROLinearOp3Arg ||
- nd->type == IROLinearOperand ||
- nd->type == IROLinearFunccall
- ) && (
- (nd->flags & IROLF_LoopInvariant) &&
- !(nd->flags & IROLF_Ind)
- );
-}
diff --git a/compiler_and_linker/unsorted/IroTransform.c b/compiler_and_linker/unsorted/IroTransform.c
deleted file mode 100644
index 54f3302..0000000
--- a/compiler_and_linker/unsorted/IroTransform.c
+++ /dev/null
@@ -1,2794 +0,0 @@
-#include "compiler/IroTransform.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CIRTransform.h"
-#include "compiler/CMachine.h"
-#include "compiler/CPrep.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/enode.h"
-#include "compiler/types.h"
-
-ENodeType ExprType;
-ENode *IndirectRef;
-Boolean FirstTime;
-CInt64 OperandConst;
-Object *OperandObject;
-ENodeList *FirstAddend;
-ENodeList *LastAddend;
-static ENodeType AssignmentOp[MAXEXPR];
-static ENodeType ComplementaryOpLogical[MAXEXPR];
-static ENodeType ComplementaryOp[MAXEXPR];
-
-// forward decls
-static void DoDiadic(IROLinear *nd);
-
-static int GetTypeSize(Type *type) {
- if (type->size == 1)
- return 0;
- if (type->size == 2)
- return 1;
- if (type->size == 4)
- return 2;
- if (type->size == 8)
- return 3;
- return -1;
-}
-
-void IRO_InitializeAssignmentOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- AssignmentOp[i] = MAXEXPR;
-
- AssignmentOp[EPOSTINC] = MAXEXPR;
- AssignmentOp[EPOSTDEC] = MAXEXPR;
- AssignmentOp[EPREINC] = MAXEXPR;
- AssignmentOp[EPREDEC] = MAXEXPR;
- AssignmentOp[EINDIRECT] = MAXEXPR;
- AssignmentOp[EMONMIN] = MAXEXPR;
- AssignmentOp[EBINNOT] = MAXEXPR;
- AssignmentOp[ELOGNOT] = MAXEXPR;
- AssignmentOp[EFORCELOAD] = MAXEXPR;
- AssignmentOp[EMUL] = EMULASS;
- AssignmentOp[EMULV] = MAXEXPR;
- AssignmentOp[EDIV] = EDIVASS;
- AssignmentOp[EMODULO] = EMODASS;
- AssignmentOp[EADDV] = MAXEXPR;
- AssignmentOp[ESUBV] = MAXEXPR;
- AssignmentOp[EADD] = EADDASS;
- AssignmentOp[ESUB] = ESUBASS;
- AssignmentOp[ESHL] = ESHLASS;
- AssignmentOp[ESHR] = ESHRASS;
- AssignmentOp[ELESS] = MAXEXPR;
- AssignmentOp[EGREATER] = MAXEXPR;
- AssignmentOp[ELESSEQU] = MAXEXPR;
- AssignmentOp[EGREATEREQU] = MAXEXPR;
- AssignmentOp[EEQU] = MAXEXPR;
- AssignmentOp[ENOTEQU] = MAXEXPR;
- AssignmentOp[EAND] = EANDASS;
- AssignmentOp[EXOR] = EXORASS;
- AssignmentOp[EOR] = EORASS;
- AssignmentOp[ELAND] = MAXEXPR;
- AssignmentOp[ELOR] = MAXEXPR;
- AssignmentOp[EASS] = MAXEXPR;
- AssignmentOp[EMULASS] = MAXEXPR;
- AssignmentOp[EDIVASS] = MAXEXPR;
- AssignmentOp[EMODASS] = MAXEXPR;
- AssignmentOp[EADDASS] = MAXEXPR;
- AssignmentOp[ESUBASS] = MAXEXPR;
- AssignmentOp[ESHLASS] = MAXEXPR;
- AssignmentOp[ESHRASS] = MAXEXPR;
- AssignmentOp[EANDASS] = MAXEXPR;
- AssignmentOp[EXORASS] = MAXEXPR;
- AssignmentOp[EORASS] = MAXEXPR;
- AssignmentOp[ECOMMA] = MAXEXPR;
- AssignmentOp[EPMODULO] = MAXEXPR;
- AssignmentOp[EROTL] = MAXEXPR;
- AssignmentOp[EROTR] = MAXEXPR;
- AssignmentOp[EBCLR] = MAXEXPR;
- AssignmentOp[EBTST] = MAXEXPR;
- AssignmentOp[EBSET] = MAXEXPR;
- AssignmentOp[ETYPCON] = MAXEXPR;
- AssignmentOp[EBITFIELD] = MAXEXPR;
- AssignmentOp[EINTCONST] = MAXEXPR;
- AssignmentOp[EFLOATCONST] = MAXEXPR;
- AssignmentOp[ESTRINGCONST] = MAXEXPR;
- AssignmentOp[ECOND] = MAXEXPR;
- AssignmentOp[EFUNCCALL] = MAXEXPR;
- AssignmentOp[EFUNCCALLP] = MAXEXPR;
- AssignmentOp[EOBJREF] = MAXEXPR;
- AssignmentOp[EMFPOINTER] = MAXEXPR;
- AssignmentOp[ENULLCHECK] = MAXEXPR;
- AssignmentOp[EPRECOMP] = MAXEXPR;
- AssignmentOp[ETEMP] = MAXEXPR;
- AssignmentOp[EARGOBJ] = MAXEXPR;
- AssignmentOp[ELOCOBJ] = MAXEXPR;
- AssignmentOp[ELABEL] = MAXEXPR;
- AssignmentOp[ESETCONST] = MAXEXPR;
- AssignmentOp[ENEWEXCEPTION] = MAXEXPR;
- AssignmentOp[ENEWEXCEPTIONARRAY] = MAXEXPR;
- AssignmentOp[EOBJLIST] = MAXEXPR;
- AssignmentOp[EMEMBER] = MAXEXPR;
- AssignmentOp[ETEMPLDEP] = MAXEXPR;
- AssignmentOp[EINSTRUCTION] = MAXEXPR;
- AssignmentOp[EDEFINE] = MAXEXPR;
- AssignmentOp[EREUSE] = MAXEXPR;
- AssignmentOp[EASSBLK] = MAXEXPR;
- AssignmentOp[EVECTOR128CONST] = MAXEXPR;
- AssignmentOp[ECONDASS] = MAXEXPR;
-}
-
-void IRO_InitializeComplementaryOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- ComplementaryOp[i] = MAXEXPR;
-
- ComplementaryOp[EPOSTINC] = EPOSTDEC;
- ComplementaryOp[EPOSTDEC] = EPOSTINC;
- ComplementaryOp[EPREINC] = EPREDEC;
- ComplementaryOp[EPREDEC] = EPREINC;
- ComplementaryOp[EINDIRECT] = MAXEXPR;
- ComplementaryOp[EMONMIN] = EMONMIN;
- ComplementaryOp[EBINNOT] = EBINNOT;
- ComplementaryOp[ELOGNOT] = ELOGNOT;
- ComplementaryOp[EFORCELOAD] = MAXEXPR;
- ComplementaryOp[EMUL] = EDIV;
- ComplementaryOp[EMULV] = MAXEXPR;
- ComplementaryOp[EDIV] = EMUL;
- ComplementaryOp[EMODULO] = MAXEXPR;
- ComplementaryOp[EADDV] = ESUBV;
- ComplementaryOp[ESUBV] = EADDV;
- ComplementaryOp[EADD] = ESUB;
- ComplementaryOp[ESUB] = EADD;
- ComplementaryOp[ESHL] = ESHR;
- ComplementaryOp[ESHR] = ESHL;
- ComplementaryOp[ELESS] = EGREATER;
- ComplementaryOp[EGREATER] = ELESS;
- ComplementaryOp[ELESSEQU] = EGREATEREQU;
- ComplementaryOp[EGREATEREQU] = ELESSEQU;
- ComplementaryOp[EEQU] = ENOTEQU;
- ComplementaryOp[ENOTEQU] = EEQU;
- ComplementaryOp[EAND] = EOR;
- ComplementaryOp[EXOR] = MAXEXPR;
- ComplementaryOp[EOR] = EAND;
- ComplementaryOp[ELAND] = ELOR;
- ComplementaryOp[ELOR] = ELAND;
- ComplementaryOp[EASS] = MAXEXPR;
- ComplementaryOp[EMULASS] = EDIVASS;
- ComplementaryOp[EDIVASS] = EMULASS;
- ComplementaryOp[EMODASS] = MAXEXPR;
- ComplementaryOp[EADDASS] = ESUBASS;
- ComplementaryOp[ESUBASS] = EADDASS;
- ComplementaryOp[ESHLASS] = ESHRASS;
- ComplementaryOp[ESHRASS] = ESHLASS;
- ComplementaryOp[EANDASS] = EORASS;
- ComplementaryOp[EXORASS] = MAXEXPR;
- ComplementaryOp[EORASS] = EANDASS;
- ComplementaryOp[ECOMMA] = MAXEXPR;
- ComplementaryOp[EPMODULO] = MAXEXPR;
- ComplementaryOp[EROTL] = EROTR;
- ComplementaryOp[EROTR] = EROTL;
- ComplementaryOp[EBCLR] = MAXEXPR;
- ComplementaryOp[EBTST] = MAXEXPR;
- ComplementaryOp[EBSET] = MAXEXPR;
- ComplementaryOp[ETYPCON] = MAXEXPR;
- ComplementaryOp[EBITFIELD] = MAXEXPR;
- ComplementaryOp[EINTCONST] = MAXEXPR;
- ComplementaryOp[EFLOATCONST] = MAXEXPR;
- ComplementaryOp[ESTRINGCONST] = MAXEXPR;
- ComplementaryOp[ECOND] = MAXEXPR;
- ComplementaryOp[EFUNCCALL] = MAXEXPR;
- ComplementaryOp[EFUNCCALLP] = MAXEXPR;
- ComplementaryOp[EOBJREF] = MAXEXPR;
- ComplementaryOp[EMFPOINTER] = MAXEXPR;
- ComplementaryOp[ENULLCHECK] = MAXEXPR;
- ComplementaryOp[EPRECOMP] = MAXEXPR;
- ComplementaryOp[ETEMP] = MAXEXPR;
- ComplementaryOp[EARGOBJ] = MAXEXPR;
- ComplementaryOp[ELOCOBJ] = MAXEXPR;
- ComplementaryOp[ELABEL] = MAXEXPR;
- ComplementaryOp[ESETCONST] = MAXEXPR;
- ComplementaryOp[ENEWEXCEPTION] = MAXEXPR;
- ComplementaryOp[ENEWEXCEPTIONARRAY] = MAXEXPR;
- ComplementaryOp[EOBJLIST] = MAXEXPR;
- ComplementaryOp[EMEMBER] = MAXEXPR;
- ComplementaryOp[ETEMPLDEP] = MAXEXPR;
- ComplementaryOp[EINSTRUCTION] = MAXEXPR;
- ComplementaryOp[EDEFINE] = MAXEXPR;
- ComplementaryOp[EREUSE] = MAXEXPR;
- ComplementaryOp[EASSBLK] = MAXEXPR;
- ComplementaryOp[EVECTOR128CONST] = MAXEXPR;
- ComplementaryOp[ECONDASS] = MAXEXPR;
-}
-
-void IRO_InitializeComplementaryOpLogicalArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- ComplementaryOpLogical[i] = MAXEXPR;
-
- ComplementaryOpLogical[EPOSTINC] = MAXEXPR;
- ComplementaryOpLogical[EPOSTDEC] = MAXEXPR;
- ComplementaryOpLogical[EPREINC] = MAXEXPR;
- ComplementaryOpLogical[EPREDEC] = MAXEXPR;
- ComplementaryOpLogical[EINDIRECT] = MAXEXPR;
- ComplementaryOpLogical[EMONMIN] = MAXEXPR;
- ComplementaryOpLogical[EBINNOT] = MAXEXPR;
- ComplementaryOpLogical[ELOGNOT] = ELOGNOT;
- ComplementaryOpLogical[EFORCELOAD] = MAXEXPR;
- ComplementaryOpLogical[EMUL] = MAXEXPR;
- ComplementaryOpLogical[EMULV] = MAXEXPR;
- ComplementaryOpLogical[EDIV] = MAXEXPR;
- ComplementaryOpLogical[EMODULO] = MAXEXPR;
- ComplementaryOpLogical[EADDV] = MAXEXPR;
- ComplementaryOpLogical[ESUBV] = MAXEXPR;
- ComplementaryOpLogical[EADD] = MAXEXPR;
- ComplementaryOpLogical[ESUB] = MAXEXPR;
- ComplementaryOpLogical[ESHL] = MAXEXPR;
- ComplementaryOpLogical[ESHR] = MAXEXPR;
- ComplementaryOpLogical[ELESS] = EGREATEREQU;
- ComplementaryOpLogical[EGREATER] = ELESSEQU;
- ComplementaryOpLogical[ELESSEQU] = EGREATER;
- ComplementaryOpLogical[EGREATEREQU] = ELESS;
- ComplementaryOpLogical[EEQU] = ENOTEQU;
- ComplementaryOpLogical[ENOTEQU] = EEQU;
- ComplementaryOpLogical[EAND] = MAXEXPR;
- ComplementaryOpLogical[EXOR] = MAXEXPR;
- ComplementaryOpLogical[EOR] = MAXEXPR;
- ComplementaryOpLogical[ELAND] = ELOR;
- ComplementaryOpLogical[ELOR] = ELAND;
- ComplementaryOpLogical[EASS] = MAXEXPR;
- ComplementaryOpLogical[EMULASS] = MAXEXPR;
- ComplementaryOpLogical[EDIVASS] = MAXEXPR;
- ComplementaryOpLogical[EMODASS] = MAXEXPR;
- ComplementaryOpLogical[EADDASS] = MAXEXPR;
- ComplementaryOpLogical[ESUBASS] = MAXEXPR;
- ComplementaryOpLogical[ESHLASS] = MAXEXPR;
- ComplementaryOpLogical[ESHRASS] = MAXEXPR;
- ComplementaryOpLogical[EANDASS] = MAXEXPR;
- ComplementaryOpLogical[EXORASS] = MAXEXPR;
- ComplementaryOpLogical[EORASS] = MAXEXPR;
- ComplementaryOpLogical[ECOMMA] = MAXEXPR;
- ComplementaryOpLogical[EPMODULO] = MAXEXPR;
- ComplementaryOpLogical[EROTL] = MAXEXPR;
- ComplementaryOpLogical[EROTR] = MAXEXPR;
- ComplementaryOpLogical[EBCLR] = MAXEXPR;
- ComplementaryOpLogical[EBTST] = MAXEXPR;
- ComplementaryOpLogical[EBSET] = MAXEXPR;
- ComplementaryOpLogical[ETYPCON] = MAXEXPR;
- ComplementaryOpLogical[EBITFIELD] = MAXEXPR;
- ComplementaryOpLogical[EINTCONST] = MAXEXPR;
- ComplementaryOpLogical[EFLOATCONST] = MAXEXPR;
- ComplementaryOpLogical[ESTRINGCONST] = MAXEXPR;
- ComplementaryOpLogical[ECOND] = MAXEXPR;
- ComplementaryOpLogical[EFUNCCALL] = MAXEXPR;
- ComplementaryOpLogical[EFUNCCALLP] = MAXEXPR;
- ComplementaryOpLogical[EOBJREF] = MAXEXPR;
- ComplementaryOpLogical[EMFPOINTER] = MAXEXPR;
- ComplementaryOpLogical[ENULLCHECK] = MAXEXPR;
- ComplementaryOpLogical[EPRECOMP] = MAXEXPR;
- ComplementaryOpLogical[ETEMP] = MAXEXPR;
- ComplementaryOpLogical[EARGOBJ] = MAXEXPR;
- ComplementaryOpLogical[ELOCOBJ] = MAXEXPR;
- ComplementaryOpLogical[ELABEL] = MAXEXPR;
- ComplementaryOpLogical[ESETCONST] = MAXEXPR;
- ComplementaryOpLogical[ENEWEXCEPTION] = MAXEXPR;
- ComplementaryOpLogical[ENEWEXCEPTIONARRAY] = MAXEXPR;
- ComplementaryOpLogical[EOBJLIST] = MAXEXPR;
- ComplementaryOpLogical[EMEMBER] = MAXEXPR;
- ComplementaryOpLogical[ETEMPLDEP] = MAXEXPR;
- ComplementaryOpLogical[EINSTRUCTION] = MAXEXPR;
- ComplementaryOpLogical[EDEFINE] = MAXEXPR;
- ComplementaryOpLogical[EREUSE] = MAXEXPR;
- ComplementaryOpLogical[EASSBLK] = MAXEXPR;
- ComplementaryOpLogical[EVECTOR128CONST] = MAXEXPR;
- ComplementaryOpLogical[ECONDASS] = MAXEXPR;
-}
-
-static void DoTransformations(IROLinear *nd) {
- IROLinear *nd2;
- IROLinear *nd3;
- IROLinear *nd4;
- IROLinear *nd5;
- Type *newtype;
- SInt32 value;
-
- if (nd->type == IROLinearOp2Arg) {
- switch (nd->nodetype) {
- case EASS:
- nd2 = nd->u.diadic.right;
- if (
- nd2->type == IROLinearOp2Arg &&
- AssignmentOp[nd2->nodetype] < MAXEXPR &&
- IRO_TypesEqual(nd->rtype, nd2->rtype) &&
- IRO_IsVariable(nd3 = nd->u.diadic.left) &&
- !(nd3->flags & IROLF_BitfieldIndirect) &&
- IRO_ExprsSame(nd3, nd2->u.diadic.left)
- )
- {
- nd->nodetype = AssignmentOp[nd2->nodetype];
- nd->u.diadic.right = nd2->u.diadic.right;
- IRO_NopOut(nd2->u.diadic.left);
- nd2->type = IROLinearNop;
-
- nd3->flags |= IROLF_Used;
- nd3->u.diadic.left->flags |= IROLF_Used;
- }
- break;
-
- case EMUL:
- if (
- IS_TYPE_INT(nd->rtype) &&
- IRO_IsPow2(nd->u.diadic.right, &value)
- )
- {
- nd->nodetype = ESHL;
- CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value);
- }
- break;
-
- case EDIV:
- if (
- IS_TYPE_INT(nd->rtype) &&
- IRO_IsPow2(nd->u.diadic.right, &value)
- )
- {
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->nodetype = ESHR;
- CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value);
- } else if (
- !IRO_IsUnsignedType(nd->rtype) &&
- TYPE_INTEGRAL(nd->rtype)->integral != IT_BOOL &&
- nd->u.diadic.left->nodetype == ETYPCON &&
- IS_TYPE_INT(nd->u.diadic.left->u.monadic->rtype) &&
- IRO_IsUnsignedType(nd->u.diadic.left->u.monadic->rtype) &&
- nd->u.diadic.left->u.monadic->rtype->size < nd->u.diadic.left->rtype->size
- )
- {
- nd->nodetype = ESHR;
- CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value);
- if (nd->flags & IROLF_Reffed) {
- IROLinear *copy = IRO_NewLinear(IROLinearOp1Arg);
- memcpy(copy, nd, sizeof(IROLinear));
- copy->type = IROLinearOp1Arg;
- copy->nodetype = ETYPCON;
- copy->index = IRO_NumLinear++;
- copy->rtype = nd->rtype;
- IRO_PasteAfter(copy, copy, nd);
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, copy);
- copy->u.monadic = nd;
- nd->flags |= IROLF_Reffed;
- }
- nd->rtype = IRO_UnsignedType(nd->rtype);
- newtype = IRO_UnsignedType(nd->u.diadic.right->rtype);
- nd->u.diadic.right->u.node->rtype = newtype;
- nd->u.diadic.right->rtype = newtype;
- nd->u.diadic.left->rtype = IRO_UnsignedType(nd->u.diadic.left->rtype);
- }
- }
- break;
-
- case EMODULO:
- if (
- IS_TYPE_INT(nd->rtype) &&
- IRO_IsUnsignedType(nd->rtype) &&
- IRO_IsPow2(nd->u.diadic.right, &value)
- )
- {
- nd->nodetype = EAND;
- nd->u.diadic.right->u.node->data.intval = CInt64_Sub(nd->u.diadic.right->u.node->data.intval, cint64_one);
- }
- break;
-
- case EEQU:
- if (
- (nd2 = IRO_LocateFather(nd)) &&
- nd2->nodetype == ETYPCON &&
- IS_TYPE_INT(nd2->rtype) &&
- (nd3 = IRO_LocateFather(nd2)) &&
- nd3->nodetype == ELOGNOT &&
- (nd4 = IRO_LocateFather(nd3)) &&
- nd4->nodetype == ETYPCON &&
- IS_TYPE_INT(nd4->rtype) &&
- (
- ((nd5 = IRO_LocateFather(nd4)) && nd5->type == IROLinearIf) ||
- nd5->type == IROLinearIfNot
- )
- )
- {
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd4, nd);
- nd->nodetype = ENOTEQU;
- nd2->type = IROLinearNop;
- nd3->type = IROLinearNop;
- nd4->type = IROLinearNop;
- }
- break;
- }
- }
-}
-
-static void IRO_SwitchChildren(IROLinear *nd) {
- IROLinear *tmp = nd->u.diadic.left;
- nd->u.diadic.left = nd->u.diadic.right;
- nd->u.diadic.right = tmp;
-}
-
-static void ReplaceExprWithConst(IROLinear *nd, CInt64 val) {
- IRO_NopOut(nd);
- nd->type = IROLinearOperand;
- nd->nodetype = EINTCONST;
- nd->u.node = IRO_NewENode(EINTCONST);
- nd->u.node->data.intval = val;
- nd->u.node->flags = nd->nodeflags;
- nd->u.node->rtype = nd->rtype;
-
- if (IS_TYPE_FLOAT(nd->rtype)) {
- nd->u.node->type = EFLOATCONST;
- nd->nodetype = EFLOATCONST;
- nd->u.node->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), val);
- }
-}
-
-static void ReplaceExprWithLeftChild(IROLinear *nd) {
- IROLinear *left = nd->u.diadic.left;
- IROLinear *right = nd->u.diadic.right;
-
- if (left->rtype == nd->rtype) {
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, left);
- left->flags = nd->flags;
- left->nodeflags = nd->nodeflags;
- nd->type = IROLinearNop;
- IRO_NopOut(right);
- } else {
- nd->type = IROLinearOp1Arg;
- nd->nodetype = ETYPCON;
- nd->u.monadic = left;
- IRO_NopOut(right);
- }
-}
-
-static void ReplaceExprWithRightChild(IROLinear *nd) {
- IROLinear *left = nd->u.diadic.left;
- IROLinear *right = nd->u.diadic.right;
-
- if (right->rtype == nd->rtype) {
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, right);
- right->flags = nd->flags;
- right->nodeflags = nd->nodeflags;
- nd->type = IROLinearNop;
- IRO_NopOut(left);
- } else {
- nd->type = IROLinearOp1Arg;
- nd->nodetype = ETYPCON;
- nd->u.monadic = right;
- IRO_NopOut(left);
- }
-}
-
-static void ReplaceExprWithMonaminRight(IROLinear *nd) {
- IROLinear *left = nd->u.diadic.left;
- IROLinear *right = nd->u.diadic.right;
-
- if (right->rtype == nd->rtype) {
- nd->type = IROLinearOp1Arg;
- nd->nodetype = EMONMIN;
- nd->u.monadic = right;
- IRO_NopOut(left);
- } else {
- IRO_NopOut(left);
- left->type = IROLinearOp1Arg;
- left->nodetype = ETYPCON;
- left->expr = right->expr;
- left->rtype = nd->rtype;
- left->u.monadic = right;
- nd->type = IROLinearOp1Arg;
- nd->nodetype = EMONMIN;
- nd->u.monadic = left;
- }
-}
-
-static void ReplaceExprWithMonaminLeft(IROLinear *nd) {
- IROLinear *left = nd->u.diadic.left;
- IROLinear *right = nd->u.diadic.right;
-
- if (left->rtype == nd->rtype) {
- nd->type = IROLinearOp1Arg;
- nd->nodetype = EMONMIN;
- nd->u.monadic = left;
- IRO_NopOut(right);
- } else {
- IRO_NopOut(right);
- right->type = IROLinearOp1Arg;
- right->nodetype = ETYPCON;
- right->expr = left->expr;
- right->rtype = nd->rtype;
- right->u.monadic = left;
- nd->type = IROLinearOp1Arg;
- nd->nodetype = EMONMIN;
- nd->u.monadic = right;
- }
-}
-
-static void switchFatherLeftMonadic(IROLinear *nd) {
- IROLinear *inner = nd->u.monadic;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, inner);
- nd->u.monadic = inner->u.monadic;
- inner->u.monadic = nd;
- inner->rtype = nd->rtype;
- inner->flags = nd->flags;
- inner->nodeflags = nd->nodeflags;
- IRO_CutAndPasteAfter(inner, inner, nd);
-}
-
-static void switchFatherLeft(IROLinear *nd, int isRight) {
- IROLinear *a;
- IROLinear *b;
-
- a = nd->u.diadic.left;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, a);
-
- if (isRight) {
- nd->u.diadic.left = a->u.diadic.left;
- a->u.diadic.left = nd;
- b = a->u.diadic.right;
- } else {
- nd->u.diadic.left = a->u.diadic.right;
- a->u.diadic.right = nd;
- b = a->u.diadic.left;
- }
-
- a->rtype = nd->rtype;
- a->flags = nd->flags;
- a->nodeflags = nd->nodeflags;
- IRO_CutAndPasteAfter(a, a, nd);
- IRO_CutAndPasteAfter(IRO_FindFirst(b), b, nd);
-}
-
-static void PickCommonsubAtLeftLeft(IROLinear *nd) {
- switchFatherLeft(nd, 0);
- ReplaceExprWithRightChild(nd->u.diadic.right);
-}
-
-static void PickCommonsubAtRightLeft(IROLinear *nd) {
- switchFatherLeft(nd, 1);
- ReplaceExprWithRightChild(nd->u.diadic.right);
-}
-
-static void PickCommonsubAtLeftRight(IROLinear *nd) {
- switchFatherLeft(nd, 0);
- ReplaceExprWithLeftChild(nd->u.diadic.right);
-}
-
-static void PickCommonsubAtRightRight(IROLinear *nd) {
- switchFatherLeft(nd, 1);
- ReplaceExprWithLeftChild(nd->u.diadic.right);
-}
-
-static void DoTransformations11(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- int changed;
- int compare;
- Type *type;
- SInt32 tmp1;
- SInt32 tmp2;
- CInt64 val;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype))
- return;
-
- changed = 0;
- if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) {
- if (IRO_IsIntConstant(right) || IRO_IsFloatConstant(right)) {
- if (IRO_IsConstantZero(right)) {
- switch (nd->nodetype) {
- case EADDV:
- case ESUBV:
- case EADD:
- case ESUB:
- case ESHL:
- case ESHR:
- case EXOR:
- case EOR:
- case ELOR:
- case EADDASS:
- case ESUBASS:
- case ESHLASS:
- case ESHRASS:
- case EXORASS:
- case EORASS:
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- break;
- case EMUL:
- case EAND:
- case ELAND:
- ReplaceExprWithConst(nd, cint64_zero);
- changed = 1;
- break;
- case EMULASS:
- case EANDASS:
- nd->nodetype = EASS;
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- changed = 1;
- break;
- case EDIV:
- case EMODULO:
- case EDIVASS:
- case EMODASS:
- if (nd->stmt->sourceoffset) {
- TStreamElement *token = CPrep_CurStreamElement();
- token->tokenoffset = nd->stmt->sourceoffset;
- CError_SetErrorToken(token);
- }
- CError_Warning(CErrorStr139);
- break;
- }
- } else if (nd->nodetype == ELAND) {
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- } else if (nd->nodetype == ELOR) {
- ReplaceExprWithConst(nd, cint64_one);
- changed = 1;
- } else if (nd->nodetype == ESHL || nd->nodetype == ESHR || nd->nodetype == ESHLASS || nd->nodetype == ESHRASS) {
- type = nd->rtype;
- tmp1 = type->size * 8;
- if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON) {
- type = left->u.monadic->rtype;
- if (
- left->u.monadic->type == IROLinearOp1Arg &&
- left->u.monadic->nodetype == EINDIRECT &&
- left->u.monadic->u.monadic->type == IROLinearOp1Arg &&
- left->u.monadic->u.monadic->nodetype == EBITFIELD &&
- IS_TYPE_BITFIELD(left->u.monadic->u.monadic->rtype)
- )
- tmp2 = TYPE_BITFIELD(left->u.monadic->u.monadic->rtype)->bitlength;
- else
- tmp2 = type->size * 8;
- } else {
- tmp2 = tmp1;
- }
-
- switch (nd->nodetype) {
- case ESHL:
- case ESHLASS:
- CInt64_SetLong(&val, tmp1);
- if (IRO_IsUnsignedType(type))
- compare = CInt64_GreaterEqualU(right->u.node->data.intval, val);
- else
- compare = CInt64_GreaterEqual(right->u.node->data.intval, val);
- break;
- case ESHR:
- case ESHRASS:
- CInt64_SetLong(&val, tmp2);
- compare = IRO_IsUnsignedType(type) && CInt64_GreaterEqualU(right->u.node->data.intval, val);
- break;
- }
-
- if (compare) {
- switch (nd->nodetype) {
- case ESHL:
- case ESHR:
- ReplaceExprWithConst(nd, cint64_zero);
- break;
- case ESHLASS:
- case ESHRASS:
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- break;
- }
- changed = 1;
- }
- } else if (IRO_IsConstantOne(right)) {
- switch (nd->nodetype) {
- case EMUL:
- case EMULV:
- case EDIV:
- case EMULASS:
- case EDIVASS:
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- break;
- case EMODULO:
- ReplaceExprWithConst(nd, cint64_zero);
- changed = 1;
- break;
- case EMODASS:
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- changed = 1;
- break;
- }
- } else if (IRO_IsConstantNegativeOne(right)) {
- switch (nd->nodetype) {
- case EMUL:
- case EMULV:
- case EDIV:
- ReplaceExprWithMonaminLeft(nd);
- changed = 1;
- break;
- case EMODULO:
- ReplaceExprWithConst(nd, cint64_zero);
- changed = 1;
- break;
- case EMODASS:
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- changed = 1;
- break;
- }
- }
- }
-
- if (!changed && (IRO_IsIntConstant(left) || IRO_IsFloatConstant(left))) {
- if (IRO_IsConstantZero(left)) {
- switch (nd->nodetype) {
- case EADDV:
- case EADD:
- case EXOR:
- case EOR:
- case ELOR:
- ReplaceExprWithRightChild(nd);
- break;
- case EMUL:
- case ESHL:
- case ESHR:
- case EAND:
- case ELAND:
- ReplaceExprWithConst(nd, cint64_zero);
- break;
- case ESUBV:
- case ESUB:
- ReplaceExprWithMonaminRight(nd);
- break;
- }
- } else if (nd->nodetype == ELAND) {
- ReplaceExprWithRightChild(nd);
- } else if (nd->nodetype == ELOR) {
- ReplaceExprWithConst(nd, cint64_one);
- } else if (IRO_IsConstantOne(left)) {
- switch (nd->nodetype) {
- case EMUL:
- case EMULV:
- ReplaceExprWithRightChild(nd);
- break;
- }
- } else if (IRO_IsConstantNegativeOne(left)) {
- switch (nd->nodetype) {
- case EMUL:
- case EMULV:
- ReplaceExprWithMonaminRight(nd);
- break;
- }
- }
- }
- }
- }
-}
-
-static void DoTransformations12(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype))
- return;
-
- if (IRO_ExprsSameSemantically(left, right) && !IRO_HasSideEffect(left)) {
- switch (nd->nodetype) {
- case ESUBV:
- case ESUB:
- case ELESS:
- case EGREATER:
- case ENOTEQU:
- case EXOR:
- ReplaceExprWithConst(nd, cint64_zero);
- break;
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- ReplaceExprWithConst(nd, cint64_one);
- break;
- case EAND:
- case EOR:
- case ELAND:
- case ELOR:
- case EASS:
- case EANDASS:
- case EORASS:
- ReplaceExprWithLeftChild(nd);
- break;
- case ESUBASS:
- case EXORASS:
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- break;
- }
- }
- }
-}
-
-static void DoTransformations13(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- IROLinear *left2;
- IROLinear *right2;
- IROListNode *tmp;
- IROListNode *leftlist;
- IROListNode *rightlist;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
-
- if (
- !IRO_HasSideEffect(left) &&
- !IRO_HasSideEffect(right) &&
- (nd->nodetype == EEQU || nd->nodetype == ENOTEQU) &&
- PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, left) &&
- PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, right)
- )
- {
- leftlist = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, left, &leftlist);
- if (leftlist) {
- if (leftlist->list.head && leftlist->list.tail && !leftlist->nextList) {
- rightlist = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, right, &rightlist);
- if (rightlist) {
- if (rightlist->list.head && rightlist->list.tail && !rightlist->nextList) {
- left2 = leftlist->list.tail;
- right2 = rightlist->list.tail;
- if (IRO_ExprsSameSemantically(left2, right2)) {
- ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_one : cint64_zero);
- } else if (left2->type == right2->type && IRO_TypesEqual(left2->rtype, right2->rtype)) {
- ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_zero : cint64_one);
- }
- }
-
- while (rightlist) {
- tmp = rightlist->nextList;
- IRO_free(rightlist);
- rightlist = tmp;
- }
- }
- }
-
- while (leftlist) {
- tmp = leftlist->nextList;
- IRO_free(leftlist);
- leftlist = tmp;
- }
- }
- }
- }
-}
-
-static void DoTransformations21(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- Boolean changed;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
-
- if (left->type == IROLinearOp1Arg && right->type == IROLinearOp1Arg && left->nodetype == right->nodetype) {
- switch (left->nodetype) {
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- changed = 0;
- switch (nd->nodetype) {
- case EXOR:
- if (left->nodetype == EBINNOT)
- goto collapse;
- break;
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- if (left->nodetype == EMONMIN) {
- nd->nodetype = ComplementaryOp[nd->nodetype];
- goto collapse;
- }
- break;
- case EMUL:
- case EDIV:
- if (left->nodetype == EMONMIN)
- goto collapse;
- break;
- case EEQU:
- case ENOTEQU:
- if (left->nodetype != ELOGNOT) {
- collapse:
- nd->u.diadic.left = left->u.monadic;
- nd->u.diadic.right = right->u.monadic;
- left->type = right->type = IROLinearNop;
- changed = 1;
- }
- break;
- case ELAND:
- case ELOR:
- if (left->nodetype == ELOGNOT) {
- nd->nodetype = ComplementaryOp[nd->nodetype];
- goto switchfather;
- }
- break;
- case EAND:
- case EOR:
- if (
- !IS_TYPE_FLOAT(nd->rtype) &&
- !IS_TYPE_FLOAT(left->rtype) &&
- !IS_TYPE_FLOAT(right->rtype) &&
- left->nodetype != EMONMIN
- )
- {
- nd->nodetype = ComplementaryOp[nd->nodetype];
- goto switchfather;
- }
- break;
- case EADD:
- case ESUB:
- if (
- !IS_TYPE_FLOAT(nd->rtype) &&
- !IS_TYPE_FLOAT(left->rtype) &&
- !IS_TYPE_FLOAT(right->rtype) &&
- left->nodetype == EMONMIN
- )
- {
- switchfather:
- switchFatherLeftMonadic(nd);
- nd->u.diadic.right = right->u.monadic;
- right->type = IROLinearNop;
- changed = 1;
- }
- break;
- }
-
- if (changed) {
- DoTransformations(nd);
- DoTransformations11(nd);
- DoTransformations12(nd);
- DoTransformations13(nd);
- }
- break;
- }
- }
- }
-}
-
-static void DoTransformations22(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- IROLinear *ndtmp;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype))
- return;
-
- if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) {
- if (left->type == IROLinearOp1Arg && left->nodetype == EMONMIN) {
- switch (nd->nodetype) {
- case ESUB:
- case ESUBV:
- nd->nodetype = ComplementaryOp[nd->nodetype];
- switchFatherLeftMonadic(nd);
- break;
-
- case EADD:
- case EADDV:
- nd->nodetype = ComplementaryOp[nd->nodetype];
- nd->u.diadic.left = right;
- nd->u.diadic.right = left->u.monadic;
- left->type = IROLinearNop;
- DoTransformations(nd);
- DoTransformations12(nd);
- DoTransformations21(nd);
- break;
-
- case EDIV:
- if (IRO_ExprsSameSemantically(left->u.monadic, right))
- ReplaceExprWithConst(nd, cint64_negone);
- break;
- }
- } else {
- ndtmp = NULL;
- if (left->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left->u.monadic, right))
- ndtmp = left;
- else if (right->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left, right->u.monadic))
- ndtmp = right;
-
- if (ndtmp) {
- switch (nd->nodetype) {
- case EAND:
- if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT)
- ReplaceExprWithConst(nd, cint64_zero);
- break;
-
- case EANDASS:
- if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) {
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- }
- break;
-
- case EXOR:
- case EOR:
- if (ndtmp->nodetype == EBINNOT) {
- ReplaceExprWithConst(nd, cint64_zero);
- nd->u.node->data.intval = CInt64_Inv(nd->u.node->data.intval);
- }
- break;
-
- case EXORASS:
- case EORASS:
- if (ndtmp->nodetype == EBINNOT) {
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_zero);
- right->u.node->data.intval = CInt64_Inv(right->u.node->data.intval);
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- }
- break;
-
- case ELOR:
- if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT)
- ReplaceExprWithConst(nd, cint64_one);
- break;
-
- case ELAND:
- if (ndtmp->nodetype == ELOGNOT)
- ReplaceExprWithConst(nd, cint64_zero);
- break;
-
- case EDIV:
- if (ndtmp->nodetype == EMONMIN)
- ReplaceExprWithConst(nd, cint64_negone);
- break;
-
- case EDIVASS:
- if (ndtmp->nodetype == EMONMIN) {
- nd->nodetype = EASS;
- ReplaceExprWithConst(right, cint64_negone);
- nd->u.diadic.right->rtype = nd->rtype;
- nd->u.diadic.right->u.node->rtype = nd->rtype;
- }
- break;
- }
- }
- }
- }
- }
-}
-
-static void DoTransformations23(IROLinear *nd) {
- Boolean changed;
- Boolean isCompare;
- UInt8 which;
- IROLinear *left;
- IROLinear *right;
- CInt64 size;
- CInt64 val;
-
- if (nd->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype))
- return;
-
- isCompare = 0;
- changed = 0;
- which = 0;
-
- switch (nd->nodetype) {
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- isCompare = 1;
- case EADDV:
- case EADD:
- case EEQU:
- case ENOTEQU:
- case EAND:
- case EOR:
- if (left->type == IROLinearOp2Arg) {
- if (IRO_ExprsSameSemantically(right, left->u.diadic.left))
- which = 1;
- else if (IRO_ExprsSameSemantically(right, left->u.diadic.right))
- which = 2;
-
- if (which) {
- if (isCompare)
- nd->nodetype = ComplementaryOp[nd->nodetype];
- IRO_SwitchChildren(nd);
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- break;
- }
- }
- case ESUBV:
- case ESUB:
- case EADDASS:
- case ESUBASS:
- case EANDASS:
- case EORASS:
- if (right->type == IROLinearOp2Arg) {
- if (IRO_ExprsSameSemantically(left, right->u.diadic.left))
- which = 1;
- else if (IRO_ExprsSameSemantically(left, right->u.diadic.right))
- which = 2;
- }
- break;
-
- default:
- goto done;
- }
-
- if (which) {
- switch (right->nodetype) {
- case EAND:
- case EOR:
- if (which == 2)
- IRO_SwitchChildren(right);
-
- if (
- nd->nodetype == right->nodetype ||
- (nd->nodetype == EANDASS && right->nodetype == EAND) ||
- (nd->nodetype == EORASS && right->nodetype == EOR)
- )
- {
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- else if (
- nd->nodetype == ComplementaryOp[right->nodetype] ||
- (nd->nodetype == EANDASS && right->nodetype == EOR) ||
- (nd->nodetype == EORASS && right->nodetype == EAND)
- )
- {
- ReplaceExprWithLeftChild(nd);
- }
- break;
-
- case EADD:
- if (which == 2)
- IRO_SwitchChildren(right);
-
- switch (nd->nodetype) {
- case EEQU:
- case ENOTEQU:
- ReplaceExprWithConst(left, cint64_zero);
- ReplaceExprWithRightChild(right);
- IRO_SwitchChildren(nd);
- if (isCompare)
- nd->nodetype = ComplementaryOp[nd->nodetype];
- changed = 1;
- break;
-
- case ESUB:
- case ESUBV:
- ReplaceExprWithRightChild(right);
- ReplaceExprWithMonaminRight(nd);
- changed = 1;
- break;
-
- case ESUBASS:
- ReplaceExprWithRightChild(right);
- changed = 1;
- break;
- }
- break;
-
- case ESUB:
- switch (nd->nodetype) {
- case EEQU:
- case ENOTEQU:
- if (which == 1) {
- ReplaceExprWithConst(left, cint64_zero);
- ReplaceExprWithRightChild(right);
- IRO_SwitchChildren(nd);
- }
- break;
- case EADD:
- case EADDV:
- if (which == 2) {
- ReplaceExprWithLeftChild(right);
- ReplaceExprWithRightChild(nd);
- }
- break;
- case ESUB:
- case ESUBV:
- if (which == 1) {
- ReplaceExprWithRightChild(right);
- ReplaceExprWithRightChild(nd);
- }
- break;
- case EADDASS:
- if (which == 2) {
- nd->nodetype = EASS;
- ReplaceExprWithLeftChild(right);
- changed = 1;
- }
- break;
- case ESUBASS:
- if (which == 1) {
- nd->nodetype = EASS;
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
- }
- break;
- }
- }
-
- done:
- if (!changed) {
- switch (nd->nodetype) {
- case ESUB:
- case ESUBV:
- which = 0;
- if (left->type == IROLinearOp2Arg) {
- if (IRO_ExprsSameSemantically(right, left->u.diadic.left))
- which = 1;
- else if (IRO_ExprsSameSemantically(right, left->u.diadic.right))
- which = 2;
- }
-
- if (which == 1) {
- if (left->nodetype == ESUB) {
- ReplaceExprWithMonaminRight(left);
- ReplaceExprWithLeftChild(nd);
- } else if (left->nodetype == EADD) {
- ReplaceExprWithRightChild(left);
- ReplaceExprWithLeftChild(nd);
- }
- } else if (which == 2) {
- if (left->nodetype == EADD) {
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithLeftChild(nd);
- }
- }
- break;
- }
-
- switch (nd->nodetype) {
- case ESHL:
- case ESHR:
- case ESHLASS:
- case ESHRASS:
- which = 0;
- if (left->type == IROLinearOp2Arg) {
- if (left->nodetype == ComplementaryOp[nd->nodetype] || left->nodetype == AssignmentOp[ComplementaryOp[nd->nodetype]]) {
- if (IRO_IsIntConstant(right) && IRO_ExprsSameSemantically(right, left->u.diadic.right))
- which = 2;
- }
- }
-
- if (which == 2) {
- val = right->u.node->data.intval;
- if (left->nodetype == ESHR || left->nodetype == ESHRASS) {
- ReplaceExprWithLeftChild(left);
- nd->nodetype = (nd->nodetype == ESHL) ? EAND : EANDASS;
- right->u.node->data.intval = CInt64_Shl(cint64_negone, val);
- changed = 1;
- } else if (IRO_IsUnsignedType(nd->rtype)) {
- ReplaceExprWithLeftChild(left);
- nd->nodetype = (nd->nodetype == ESHR) ? EAND : EANDASS;
- if (nd->rtype->size < 8) {
- CInt64_SetLong(&size, 64 - 8 * nd->rtype->size);
- val = CInt64_Add(val, size);
- }
- right->u.node->data.intval = CInt64_ShrU(cint64_negone, val);
- changed = 1;
- }
- }
- break;
- }
- }
-
- if (changed) {
- DoTransformations(nd);
- DoTransformations11(nd);
- DoTransformations12(nd);
- DoTransformations13(nd);
- DoTransformations21(nd);
- DoTransformations22(nd);
- DoTransformations23(nd);
- }
- }
-}
-
-static void DoTransformations24(IROLinear *nd) {
- IROLinear *left;
- IROLinear *right;
- UInt8 changed;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype))
- return;
-
- if (left->type == IROLinearOp2Arg && right->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) {
- changed = 0;
-
- if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.left)) {
- if (left->nodetype == right->nodetype) {
- switch (left->nodetype) {
- case EADD:
- if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- ReplaceExprWithRightChild(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
- case ESUB:
- if (nd->nodetype == ESUB || nd->nodetype == ESUBV) {
- ReplaceExprWithRightChild(left);
- ReplaceExprWithRightChild(right);
- IRO_SwitchChildren(nd);
- changed = 1;
- }
- break;
- case EMUL:
- switch (nd->nodetype) {
- case EADD:
- case ESUB:
- PickCommonsubAtLeftLeft(nd);
- changed = 3;
- break;
- }
- break;
- case EAND:
- if (nd->nodetype == EXOR) {
- PickCommonsubAtLeftLeft(nd);
- changed = 3;
- break;
- }
- case EOR:
- if (nd->nodetype == left->nodetype) {
- ReplaceExprWithRightChild(left);
- changed = 1;
- } else if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- PickCommonsubAtLeftLeft(nd);
- changed = 3;
- }
- break;
- }
- } else if (left->nodetype == ComplementaryOp[right->nodetype]) {
- switch (nd->nodetype) {
- case ESUB:
- case ESUBV:
- switch (left->nodetype) {
- case EADD:
- nd->nodetype = ComplementaryOp[nd->nodetype];
- ReplaceExprWithRightChild(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- break;
- case ESUB:
- ReplaceExprWithMonaminRight(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- break;
- }
- break;
-
- case EAND:
- case EOR:
- if (left->nodetype == nd->nodetype)
- ReplaceExprWithLeftChild(nd);
- else if (right->nodetype == nd->nodetype)
- ReplaceExprWithRightChild(nd);
- break;
- }
- }
- } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.left)) {
- if (left->nodetype == right->nodetype) {
- switch (left->nodetype) {
- case EADD:
- if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
- case EMUL:
- switch (nd->nodetype) {
- case EADD:
- case ESUB:
- PickCommonsubAtRightLeft(nd);
- changed = 3;
- break;
- }
- break;
- case EAND:
- if (nd->nodetype == EXOR) {
- PickCommonsubAtRightLeft(nd);
- changed = 3;
- break;
- }
- case EOR:
- if (nd->nodetype == left->nodetype) {
- ReplaceExprWithLeftChild(left);
- changed = 1;
- } else if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- PickCommonsubAtRightLeft(nd);
- changed = 3;
- }
- break;
- }
- } else if (left->nodetype == ComplementaryOp[right->nodetype]) {
- switch (nd->nodetype) {
- case ESUB:
- case ESUBV:
- if (left->nodetype == EADD) {
- nd->nodetype = ComplementaryOp[nd->nodetype];
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
-
- case EADD:
- case EADDV:
- if (left->nodetype == ESUB) {
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
-
- case EAND:
- case EOR:
- if (left->nodetype == nd->nodetype)
- ReplaceExprWithLeftChild(nd);
- else if (right->nodetype == nd->nodetype)
- ReplaceExprWithRightChild(nd);
- break;
- }
- }
- } else if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.right)) {
- if (left->nodetype == right->nodetype) {
- switch (left->nodetype) {
- case EADD:
- if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- ReplaceExprWithRightChild(left);
- ReplaceExprWithLeftChild(right);
- changed = 1;
- }
- break;
- case ESUB:
- switch (nd->nodetype) {
- case EADDV:
- case EADD:
- nd->nodetype = ComplementaryOp[nd->nodetype];
- ReplaceExprWithRightChild(left);
- ReplaceExprWithLeftChild(right);
- IRO_SwitchChildren(nd);
- changed = 1;
- break;
- }
- break;
- case EMUL:
- switch (nd->nodetype) {
- case EADD:
- case ESUB:
- PickCommonsubAtLeftRight(nd);
- changed = 2;
- break;
- }
- break;
- case EAND:
- if (nd->nodetype == EXOR) {
- PickCommonsubAtLeftRight(nd);
- changed = 2;
- break;
- }
- case EOR:
- if (nd->nodetype == left->nodetype) {
- ReplaceExprWithRightChild(left);
- changed = 1;
- } else if (nd->nodetype == ComplementaryOp[left->nodetype]) {
- PickCommonsubAtLeftRight(nd);
- changed = 2;
- }
- break;
- }
- } else if (left->nodetype == ComplementaryOp[right->nodetype]) {
- switch (nd->nodetype) {
- case EADD:
- case EADDV:
- if (left->nodetype == EADD) {
- ReplaceExprWithRightChild(left);
- ReplaceExprWithLeftChild(right);
- changed = 1;
- }
- break;
-
- case ESUB:
- case ESUBV:
- if (left->nodetype == ESUB) {
- ReplaceExprWithMonaminRight(left);
- ReplaceExprWithRightChild(right);
- changed = 1;
- }
- break;
-
- case EAND:
- case EOR:
- if (left->nodetype == nd->nodetype)
- ReplaceExprWithLeftChild(nd);
- else if (right->nodetype == nd->nodetype)
- ReplaceExprWithRightChild(nd);
- break;
- }
- }
- } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.right)) {
- if (left->nodetype == right->nodetype) {
- switch (nd->nodetype) {
- case ESUB:
- switch (left->nodetype) {
- case EADD:
- case ESUB:
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithLeftChild(right);
- changed = 1;
- }
- case EADD:
- switch (left->nodetype) {
- case EMUL:
- case ESHL:
- PickCommonsubAtRightRight(nd);
- changed = 2;
- break;
- }
- break;
- case EXOR:
- switch (left->nodetype) {
- case ESHL:
- case ESHR:
- case EAND:
- PickCommonsubAtRightRight(nd);
- changed = 2;
- break;
- }
- break;
- case EAND:
- case EOR:
- if (left->nodetype == nd->nodetype) {
- ReplaceExprWithLeftChild(right);
- changed = 1;
- } else if (
- left->nodetype == ComplementaryOp[nd->nodetype] ||
- left->nodetype == ESHR ||
- left->nodetype == ESHL
- )
- {
- PickCommonsubAtRightRight(nd);
- changed = 2;
- }
- break;
- }
- } else if (left->nodetype == ComplementaryOp[right->nodetype]) {
- switch (nd->nodetype) {
- case EADD:
- case EADDV:
- switch (left->nodetype) {
- case EADD:
- case ESUB:
- ReplaceExprWithLeftChild(left);
- ReplaceExprWithLeftChild(right);
- changed = 1;
- break;
- }
- break;
-
- case EAND:
- case EOR:
- if (left->nodetype == nd->nodetype)
- ReplaceExprWithLeftChild(nd);
- else if (right->nodetype == nd->nodetype)
- ReplaceExprWithRightChild(nd);
- break;
- }
- }
- }
-
- if (changed) {
- DoDiadic(nd);
- if (changed == 2)
- DoDiadic(nd->u.diadic.left);
- else if (changed == 3)
- DoDiadic(nd->u.diadic.right);
- IRO_Dump("remove common op at: %d\n", nd->index);
- }
- }
- }
-}
-
-static void DoTransformations25(IROLinear *nd) {
- int changed = 0;
- IROLinear *left;
- IROLinear *right;
-
- if (nd->type == IROLinearOp2Arg) {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
-
- if (
- (left->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(left->u.diadic.left->rtype) || IS_TYPE_FLOAT(left->u.diadic.right->rtype))) ||
- (right->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(right->u.diadic.left->rtype) || IS_TYPE_FLOAT(right->u.diadic.right->rtype)))
- )
- return;
-
- switch (left->nodetype) {
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- switch (nd->nodetype) {
- case EEQU:
- if (IRO_IsConstantOne(right)) {
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- } else if (IRO_IsConstantZero(right)) {
- left->nodetype = ComplementaryOpLogical[left->nodetype];
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- }
- break;
- case ENOTEQU:
- if (IRO_IsConstantOne(right)) {
- left->nodetype = ComplementaryOpLogical[left->nodetype];
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- } else if (IRO_IsConstantZero(right)) {
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- }
- break;
- }
- break;
- case ELAND:
- case ELOR:
- switch (nd->nodetype) {
- case EEQU:
- if (IRO_IsConstantOne(right)) {
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- }
- break;
- case ENOTEQU:
- if (IRO_IsConstantZero(right)) {
- ReplaceExprWithLeftChild(nd);
- changed = 1;
- }
- break;
- }
- break;
- }
-
- if (!changed) {
- switch (right->nodetype) {
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- switch (nd->nodetype) {
- case EEQU:
- if (IRO_IsConstantOne(left)) {
- ReplaceExprWithRightChild(nd);
- } else if (IRO_IsConstantZero(left)) {
- right->nodetype = ComplementaryOpLogical[right->nodetype];
- ReplaceExprWithRightChild(nd);
- }
- break;
- case ENOTEQU:
- if (IRO_IsConstantOne(left)) {
- right->nodetype = ComplementaryOpLogical[right->nodetype];
- ReplaceExprWithRightChild(nd);
- } else if (IRO_IsConstantZero(left)) {
- ReplaceExprWithRightChild(nd);
- }
- break;
- }
- break;
- case ELAND:
- case ELOR:
- switch (nd->nodetype) {
- case EEQU:
- if (IRO_IsConstantOne(left)) {
- ReplaceExprWithRightChild(nd);
- }
- break;
- case ENOTEQU:
- if (IRO_IsConstantZero(left)) {
- ReplaceExprWithRightChild(nd);
- }
- break;
- }
- break;
- }
- }
- }
-}
-
-static Boolean isOrderingOperator(ENodeType op) {
- switch (op) {
- case ELAND:
- case ELOR:
- case ECOMMA:
- case ECOND:
- case ECONDASS:
- return 1;
- default:
- return 0;
- }
-}
-
-static void RemoveUnreffed(IROLinear *nd) {
- if (!(nd->flags & IROLF_Reffed)) {
- switch (nd->type) {
- case IROLinearOperand:
- IRO_NopNonSideEffects(nd, 0);
- break;
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- case IROLinearOp3Arg:
- case IROLinearFunccall:
- if (!isOrderingOperator(nd->nodetype))
- IRO_NopNonSideEffects(nd, 0);
- break;
- }
- }
-}
-
-static void RemoveRedundantMonadicOp(IROLinear *nd) {
- IROLinear *nd2;
- IROLinear *nd3;
-
- if (nd->type == IROLinearOp1Arg && (nd2 = IRO_LocateFather(nd)) && nd2->nodetype == nd->nodetype) {
- switch (nd->nodetype) {
- case ELOGNOT:
- if ((nd3 = IRO_LocateFather(nd2))) {
- if (
- nd3->rtype &&
- TYPE_INTEGRAL(nd3->rtype)->integral == IT_BOOL &&
- nd->u.monadic->rtype &&
- TYPE_INTEGRAL(nd->u.monadic->rtype)->integral == IT_BOOL
- )
- goto remove;
-
- if (nd3->type == IROLinearIf)
- goto remove;
- if (nd3->type == IROLinearIfNot)
- goto remove;
- if (nd3->type == IROLinearOp3Arg && nd == nd3->u.args3.a)
- goto remove;
-
- switch (nd3->nodetype) {
- case ELOGNOT:
- case ELAND:
- case ELOR:
- goto remove;
- }
- }
-
- if (nd->u.monadic->type == IROLinearOp1Arg || nd->u.monadic->type == IROLinearOp2Arg) {
- switch (nd->u.monadic->nodetype) {
- case ELOGNOT:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case ELAND:
- case ELOR:
- goto remove;
- }
- }
- break;
-
- case EMONMIN:
- case EBINNOT:
- remove:
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd2, nd->u.monadic);
- nd2->type = IROLinearNop;
- nd->type = IROLinearNop;
- break;
-
- case ETYPCON:
- if (TYPE_INTEGRAL(nd->rtype)->integral == IT_FLOAT) {
- switch (TYPE_INTEGRAL(nd2->rtype)->integral) {
- case IT_DOUBLE:
- case IT_LONGDOUBLE:
- switch (TYPE_INTEGRAL(nd->u.monadic->rtype)->integral) {
- case IT_BOOL:
- case IT_CHAR:
- case IT_SCHAR:
- case IT_UCHAR:
- case IT_SHORT:
- case IT_USHORT:
- nd->type = IROLinearNop;
- nd2->u.monadic = nd->u.monadic;
- break;
- }
- break;
- }
- }
- break;
- }
- }
-}
-
-static void ReverseOpForMonmin(IROLinear *nd) {
- IROLinear *father;
-
- if (
- nd->type == IROLinearOp1Arg &&
- nd->nodetype == EMONMIN &&
- (father = IRO_LocateFather(nd)) &&
- father->type == IROLinearOp2Arg &&
- father->u.diadic.right == nd
- )
- {
- switch (father->nodetype) {
- case EADDV:
- case ESUBV:
- case EADD:
- case ESUB:
- case EADDASS:
- case ESUBASS:
- father->nodetype = ComplementaryOp[father->nodetype];
- nd->type = IROLinearNop;
- father->u.diadic.right = nd->u.monadic;
- break;
- }
- }
-}
-
-static void DoDiadic(IROLinear *nd) {
- RemoveUnreffed(nd);
- DoTransformations(nd);
- DoTransformations11(nd);
- DoTransformations12(nd);
- DoTransformations13(nd);
- DoTransformations21(nd);
- DoTransformations22(nd);
- DoTransformations23(nd);
- DoTransformations24(nd);
- DoTransformations25(nd);
-}
-
-void IRO_DoTransformations(void) {
- IROLinear *nd;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- switch (nd->type) {
- case IROLinearOp2Arg:
- DoDiadic(nd);
- break;
- case IROLinearOp1Arg:
- RemoveUnreffed(nd);
- RemoveRedundantMonadicOp(nd);
- ReverseOpForMonmin(nd);
- break;
- case IROLinearOperand:
- RemoveUnreffed(nd);
- break;
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean ReconcileAssignments(IROLinear *nd1, IROLinear *nd2, IROList *list) {
- IROLinear *copy;
- Boolean result = 0;
- int argCount;
- int i;
- IROLinear *tmp;
-
- if (
- (nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) &&
- !(nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) &&
- ReconcileAssignments(nd1, nd2->u.monadic, list)
- )
- {
- result = 1;
- }
-
- if (
- (nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) &&
- !(nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) &&
- ReconcileAssignments(nd1->u.monadic, nd2, list)
- )
- {
- copy = IRO_NewLinear(IROLinearOp1Arg);
- *copy = *nd2;
- copy->index = IRO_NumLinear++;
- copy->type = IROLinearOp1Arg;
- copy->nodetype = ETYPCON;
- copy->rtype = nd1->rtype;
- copy->next = NULL;
- copy->u.monadic = list->tail;
- IRO_AddToList(copy, list);
- result = 1;
- }
-
- if (nd1->type == nd2->type && nd1->nodetype == nd2->nodetype) {
- copy = IRO_NewLinear(IROLinearNop);
- *copy = *nd2;
- copy->index = IRO_NumLinear++;
- copy->rtype = nd1->rtype;
- copy->next = NULL;
- switch (nd1->type) {
- case IROLinearOperand:
- if (nd1->u.node->type == nd2->u.node->type) {
- if (!(nd1->u.node->type == EOBJREF && nd1->u.node->data.objref != nd2->u.node->data.objref))
- result = 1;
- }
- break;
-
- case IROLinearOp1Arg:
- if (ReconcileAssignments(nd1->u.monadic, nd2->u.monadic, list)) {
- copy->u.monadic = list->tail;
- result = 1;
- }
- break;
-
- case IROLinearOp2Arg:
- tmp = list->tail;
- if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.left, list)) {
- copy->u.diadic.left = list->tail;
- if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.right, list)) {
- copy->u.diadic.right = list->tail;
- result = 1;
- }
- }
-
- if (!result && !IRO_HasSideEffect(nd1) && !IRO_HasSideEffect(nd2)) {
- if (nd1->nodetype == EMUL || nd1->nodetype == EADD || nd1->nodetype == EAND || nd1->nodetype == EXOR || nd1->nodetype == EOR) {
- list->tail = tmp;
- if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.right, list)) {
- copy->u.diadic.right = list->tail;
- if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.left, list)) {
- copy->u.diadic.left = list->tail;
- result = 1;
- }
- }
- }
- }
- break;
-
- case IROLinearOp3Arg:
- if (ReconcileAssignments(nd1->u.args3.c, nd2->u.args3.c, list)) {
- copy->u.args3.c = list->tail;
- if (ReconcileAssignments(nd1->u.args3.b, nd2->u.args3.b, list)) {
- copy->u.args3.b = list->tail;
- if (ReconcileAssignments(nd1->u.args3.a, nd2->u.args3.a, list)) {
- copy->u.args3.a = list->tail;
- result = 1;
- }
- }
- }
- break;
-
- case IROLinearFunccall:
- argCount = nd1->u.funccall.argCount;
- if (argCount == nd2->u.funccall.argCount) {
- result = 1;
- copy->u.funccall.args = oalloc(sizeof(IROLinear *) * argCount);
- for (i = argCount - 1; i >= 0; i--) {
- if (!ReconcileAssignments(nd1->u.funccall.args[i], nd2->u.funccall.args[i], list)) {
- result = 0;
- break;
- }
- copy->u.funccall.args[i] = list->tail;
- }
-
- if (result) {
- if (!ReconcileAssignments(nd1->u.funccall.linear8, nd2->u.funccall.linear8, list)) {
- result = 0;
- break;
- }
- copy->u.funccall.linear8 = list->tail;
- }
- }
- break;
- }
-
- if (result)
- IRO_AddToList(copy, list);
- }
-
- return result;
-}
-
-static IROLinear *FrontendTransformSelfAssignmentToAssignment(IROLinear *nd) {
- Statement *stmt;
- IROList list;
- IROLinearIRSave save;
-
- IRO_SaveLinearIR(&save);
-
- IRO_InitList(&list);
- IRO_DuplicateExpr(nd, &list);
-
- stmt = IRO_Delinearize(NULL, list.head);
- CError_ASSERT(3550, stmt);
- CError_ASSERT(3552, stmt->expr);
- stmt->expr = CIRTrans_TransformOpAss(stmt->expr);
- CError_ASSERT(3557, stmt->expr);
-
- if (DoLinearize)
- IRO_PreLinearize(stmt);
- IRO_Linearize(stmt);
-
- IRO_InitList(&list);
- list.head = IRO_FirstLinear;
- list.tail = IRO_LastLinear;
-
- IRO_RestoreLinearIR(&save);
-
- for (nd = list.head; nd; nd = nd->next) {
- if (!(nd->flags & IROLF_Reffed) && IRO_IsAssignment(nd))
- break;
- }
-
- return nd;
-}
-
-static Type *PromotedIntegralType(Type *type) {
- CError_ASSERT(3586, IS_TYPE_ENUM(type) || IS_TYPE_INT(type));
-
- if (IS_TYPE_ENUM(type))
- type = TYPE_ENUM(type)->enumtype;
-
- if (TYPE_INTEGRAL(type)->integral < IT_INT) {
- if (IRO_IsUnsignedType(type))
- return TYPE(&stunsignedint);
- else
- return TYPE(&stsignedint);
- } else {
- return type;
- }
-}
-
-static Boolean TransformMonadicSelfAssignmentToDiadicSelfAssignment(IROLinear *nd) {
- ENodeType t;
- ENodeType newtype;
- IROLinear *incExpr;
- IROLinear *varExpr;
-
- t = nd->nodetype;
-
- if (IRO_IsAssignment(nd) && IRO_IsModifyOp[t]) {
- incExpr = NULL;
- varExpr = NULL;
- newtype = MAXEXPR;
-
- if (
- nd->type == IROLinearOp1Arg &&
- (t == EPOSTINC || t == EPOSTDEC || t == EPREINC || t == EPREDEC) &&
- (!(nd->flags & IROLF_Reffed) || t == EPREINC || t == EPREDEC)
- )
- {
- Type *type = nd->rtype;
- TypeType typetype = type->type;
- varExpr = nd->u.monadic;
- if (typetype == TYPEINT || typetype == TYPEENUM) {
- incExpr = IRO_NewIntConst(cint64_one, PromotedIntegralType(type));
- } else if (typetype == TYPEPOINTER || typetype == TYPEARRAY || typetype == TYPEMEMBERPOINTER) {
- Type *inner = NULL;
- CInt64 val = cint64_zero;
-
- if (typetype == TYPEPOINTER || typetype == TYPEARRAY)
- inner = TPTR_TARGET(type);
- else if (typetype == TYPEMEMBERPOINTER)
- inner = TYPE_MEMBER_POINTER(type)->ty1;
-
- if (inner)
- CInt64_SetLong(&val, inner->size);
-
- if (!CInt64_IsZero(&val)) {
- incExpr = IRO_NewIntConst(val, TYPE(&stsignedlong));
- } else {
- return 0;
- }
- } else if (typetype == TYPEFLOAT) {
- Float fval;
- fval = CMach_CalcFloatConvertFromInt(type, cint64_one);
- incExpr = IRO_NewFloatConst(fval, nd->rtype);
- } else {
- return 0;
- }
-
- if (t == EPOSTINC || t == EPREINC)
- newtype = EADDASS;
- else
- newtype = ESUBASS;
- }
-
- if (
- varExpr &&
- incExpr &&
- newtype != MAXEXPR &&
- varExpr->u.diadic.left &&
- varExpr->u.diadic.left->type == IROLinearOperand &&
- varExpr->u.diadic.left->u.node &&
- varExpr->u.diadic.left->u.node->type == EOBJREF &&
- !IRO_HasSideEffect(varExpr)
- )
- {
- incExpr->flags |= IROLF_Reffed;
- nd->nodetype = newtype;
- nd->u.diadic.right = incExpr;
- nd->type = IROLinearOp2Arg;
- IRO_Paste(incExpr, incExpr, nd);
- return 1;
- }
- }
-
- return 0;
-}
-
-Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *nd) {
- ENodeType nonAssOp;
- IROLinear *left;
- IROLinear *right;
- ENodeType nodetype;
- IROLinear *nonAss;
- IROLinear *dupLeft;
- IROLinear *last;
- IROList list1;
- IROList list2;
-
- nodetype = nd->nodetype;
- if (
- IRO_IsAssignment(nd) &&
- IRO_IsModifyOp[nodetype] &&
- nd->type == IROLinearOp1Arg &&
- TransformMonadicSelfAssignmentToDiadicSelfAssignment(nd)
- )
- nodetype = nd->nodetype;
-
- if (
- IRO_IsAssignment(nd) &&
- IRO_IsModifyOp[nodetype] &&
- nd->type == IROLinearOp2Arg &&
- IRO_NonAssignmentOp[nodetype] != MAXEXPR
- )
- {
- left = nd->u.diadic.left;
- right = nd->u.diadic.right;
- nonAssOp = IRO_NonAssignmentOp[nodetype];
- if (
- left &&
- right &&
- nonAssOp != MAXEXPR &&
- left->u.monadic &&
- left->u.monadic->type == IROLinearOperand &&
- left->u.monadic->u.node &&
- left->u.monadic->u.node->type == EOBJREF &&
- !IRO_HasSideEffect(left)
- )
- {
- IRO_InitList(&list1);
- dupLeft = IRO_DuplicateExpr(left, &list1);
-
- if (left->rtype != right->rtype) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg);
- tmp->nodetype = ETYPCON;
- tmp->flags |= IROLF_Reffed;
- tmp->rtype = right->rtype;
- tmp->index = ++IRO_NumLinear;
- tmp->u.monadic = dupLeft;
- IRO_AddToList(tmp, &list1);
- dupLeft = tmp;
- }
-
- nonAss = IRO_NewLinear(IROLinearOp2Arg);
- nonAss->nodetype = nonAssOp;
- nonAss->flags |= IROLF_Reffed;
- nonAss->rtype = dupLeft->rtype;
- nonAss->index = ++IRO_NumLinear;
- nonAss->u.diadic.left = dupLeft;
- nonAss->u.diadic.right = right;
- IRO_AddToList(nonAss, &list1);
-
- if (left->rtype != right->rtype) {
- IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg);
- tmp->nodetype = ETYPCON;
- tmp->flags |= IROLF_Reffed;
- tmp->rtype = left->rtype;
- tmp->index = ++IRO_NumLinear;
- tmp->u.monadic = nonAss;
- IRO_AddToList(tmp, &list1);
- nonAss = tmp;
- }
-
- IRO_InitList(&list2);
- last = FrontendTransformSelfAssignmentToAssignment(nd);
- if (
- last &&
- last->type == IROLinearOp2Arg &&
- ReconcileAssignments(last->u.diadic.right, nonAss, &list2)
- )
- {
- IRO_NopOut(nd->u.diadic.right);
- nd->nodetype = EASS;
- nd->u.diadic.right = list2.tail;
- nd->type = IROLinearOp2Arg;
- IRO_Paste(list2.head, list2.tail, nd);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static void AddAddend(ENode *expr) {
- if (expr->type == EADD) {
- AddAddend(expr->data.diadic.left);
- AddAddend(expr->data.diadic.right);
- } else {
- ENodeList *list = oalloc(sizeof(ENodeList));
- list->node = expr;
- list->next = NULL;
-
- if (FirstAddend)
- LastAddend->next = list;
- else
- FirstAddend = list;
- LastAddend = list;
- }
-}
-
-static ENode *CombineConstants(ENode *expr) {
- ENode *addend;
- ENodeList *el;
- ENode *result;
- ENode *var;
- Type *type;
- ENode *tmp;
- ENodeList *prev;
- CInt64 val;
-
- FirstAddend = LastAddend = NULL;
- AddAddend(expr->data.diadic.left);
- AddAddend(expr->data.diadic.right);
-
- // these variable names are courtesy of the resource fork in abort_exit.c
- el = FirstAddend;
- prev = NULL;
- var = NULL;
- while (el) {
- addend = el->node;
- if (addend->type == EOBJREF) {
- var = addend;
- if (prev)
- prev->next = el->next;
- else
- FirstAddend = el->next;
- break;
- }
- prev = el;
- el = el->next;
- }
-
- if (!var) {
- el = FirstAddend;
- prev = NULL;
- while (el) {
- addend = el->node;
- if (addend->type == EINDIRECT) {
- var = addend;
- if (prev)
- prev->next = el->next;
- else
- FirstAddend = el->next;
- break;
- }
- prev = el;
- el = el->next;
- }
- }
-
- prev = NULL;
- CInt64_SetLong(&val, 0);
- type = NULL;
-
- for (el = FirstAddend; el; el = el->next) {
- addend = el->node;
- if (addend->type == EINTCONST && addend->rtype) {
- if (!type || type->size < addend->rtype->size)
- type = addend->rtype;
- val = CInt64_Add(val, addend->data.intval);
- if (prev)
- prev->next = el->next;
- else
- FirstAddend = el->next;
- } else if (addend->type == EMUL && addend->data.diadic.right->type == EINTCONST && addend->rtype) {
- if (!type || type->size < addend->rtype->size)
- type = addend->rtype;
-
- tmp = addend->data.diadic.left;
- if (tmp->type == EADD && tmp->data.diadic.right->type == EINTCONST) {
- val = CInt64_Add(val, CInt64_MulU(tmp->data.diadic.right->data.intval, addend->data.diadic.right->data.intval));
- addend->data.diadic.left = tmp->data.diadic.left;
- }
- prev = el;
- } else {
- prev = el;
- }
- }
-
- result = NULL;
- if (var) {
- result = var;
- if (!CInt64_IsZero(&val)) {
- result = IRO_NewENode(EADD);
- result->data.diadic.left = var;
- result->data.diadic.right = IRO_NewENode(EINTCONST);
- result->data.diadic.right->data.intval = val;
- result->data.diadic.right->rtype = type;
- result->rtype = var->rtype;
- result->cost = 1;
- CInt64_SetLong(&val, 0);
- }
- }
-
- for (el = FirstAddend; el; el = el->next) {
- addend = el->node;
- if (result) {
- tmp = IRO_NewENode(EADD);
- tmp->data.diadic.left = result;
- tmp->data.diadic.right = addend;
- tmp->cost = result->cost + 1;
- tmp->rtype = result->rtype;
- result = tmp;
- } else {
- result = addend;
- }
- }
-
- if (!CInt64_IsZero(&val)) {
- tmp = IRO_NewENode(EADD);
- tmp->data.diadic.left = result;
- tmp->data.diadic.right = IRO_NewENode(EINTCONST);
- tmp->data.diadic.right->data.intval = val;
- tmp->data.diadic.right->rtype = type;
- tmp->cost = result->cost + 1;
- tmp->rtype = result->rtype;
- result = tmp;
- }
-
- return result;
-}
-
-static ENode *TransformExprNode(ENode *expr) {
- ENode *left;
- ENode *right;
-
- switch (expr->type) {
- case EINDIRECT:
- if (ENODE_IS(expr->data.monadic, EADD))
- expr->data.monadic = CombineConstants(expr->data.monadic);
- break;
-
- case EMUL:
- case EADD:
- case EAND:
- case EXOR:
- case EOR:
- if (
- IS_TYPE_INT(expr->rtype) &&
- !ENODE_IS(right = expr->data.diadic.right, EINTCONST) &&
- ENODE_IS(left = expr->data.diadic.left, EINTCONST)
- )
- {
- expr->data.diadic.left = right;
- expr->data.diadic.right = left;
- }
- break;
-
- case EEQU:
- case ENOTEQU:
- if (
- IS_TYPE_INT(expr->rtype) &&
- !ENODE_IS(left = expr->data.diadic.right, EINTCONST) &&
- ENODE_IS(right = expr->data.diadic.left, EINTCONST)
- )
- {
- expr->data.diadic.left = left;
- expr->data.diadic.right = right;
- }
-
- if (
- ENODE_IS(expr->data.diadic.right, EINTCONST) &&
- ENODE_IS(left = expr->data.diadic.left, EBINNOT)
- )
- {
- expr->data.diadic.left = left->data.monadic;
- left->data.monadic = expr->data.diadic.right;
- expr->data.diadic.right = left;
- }
-
- break;
- }
-
- return expr;
-}
-
-static ENode *TransformExprTree(ENode *expr) {
- ENodeList *list;
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- expr->data.monadic = TransformExprTree(expr->data.monadic);
- break;
-
- ENODE_CASE_DIADIC_ALL:
- expr->data.diadic.left = TransformExprTree(expr->data.diadic.left);
- expr->data.diadic.right = TransformExprTree(expr->data.diadic.right);
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- TransformExprTree(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- TransformExprTree(list->node);
- break;
-
- case ECOND:
- TransformExprTree(expr->data.cond.cond);
- TransformExprTree(expr->data.cond.expr1);
- TransformExprTree(expr->data.cond.expr2);
- break;
-
- case ENULLCHECK:
- TransformExprTree(expr->data.nullcheck.nullcheckexpr);
- TransformExprTree(expr->data.nullcheck.condexpr);
- break;
- }
-
- return TransformExprNode(expr);
-}
-
-static void FoldConstantsinAssociativeExprs(ENode *expr) {
- short nodetype1;
- short nodetype2;
- short nodetype3;
- Boolean changed;
- short op;
- CInt64 val1;
- CInt64 val2;
- CInt64 tmpval;
-
- if (
- (
- expr->type == EADD ||
- expr->type == EMUL ||
- expr->type == EAND ||
- expr->type == EXOR ||
- expr->type == EOR ||
- expr->type == ESHL ||
- expr->type == ESHR
- ) &&
- IS_TYPE_INT(expr->rtype) &&
- expr->data.diadic.right->type == EINTCONST
- )
- {
- do {
- changed = 0;
-
- if (
- expr->data.diadic.left->type == expr->type &&
- expr->data.diadic.left->data.diadic.right->type == EINTCONST
- )
- {
- val1 = expr->data.diadic.right->data.intval;
- val2 = expr->data.diadic.left->data.diadic.right->data.intval;
- switch (expr->type) {
- case EADD:
- case ESHL:
- op = '+';
- break;
- case ESHR:
- op = '+';
- if (!IRO_IsUnsignedType(expr->rtype)) {
- CInt64_SetLong(&tmpval, expr->rtype->size * 8);
- if (CInt64_GreaterEqualU(val1, tmpval) || CInt64_GreaterEqualU(val2, tmpval))
- return;
-
- if (CInt64_GreaterEqualU(CMach_CalcIntDiadic(expr->rtype, val1, '+', val2), tmpval)) {
- val1 = CInt64_Sub(tmpval, cint64_one);
- val2 = cint64_zero;
- }
- }
- break;
- case EMUL:
- op = '*';
- break;
- case EAND:
- op = '&';
- break;
- case EOR:
- op = '|';
- break;
- case EXOR:
- op = '^';
- break;
- default:
- return;
- }
-
- expr->data.diadic.right->data.intval = CMach_CalcIntDiadic(expr->rtype, val1, op, val2);
- expr->data.diadic.left = expr->data.diadic.left->data.diadic.left;
- changed = 1;
- } else if (
- ((nodetype1 = expr->type) == EAND || nodetype1 == EOR) &&
- ((nodetype2 = expr->data.diadic.left->type) == EAND || nodetype2 == EOR) &&
- ((nodetype3 = expr->data.diadic.left->data.diadic.left->type) == EAND || nodetype3 == EOR) &&
- expr->data.diadic.left->data.diadic.left->data.diadic.right->type == EINTCONST
- )
- {
- val1 = expr->data.diadic.right->data.intval;
- if (CInt64_Equal(val1, expr->data.diadic.left->data.diadic.left->data.diadic.right->data.intval)) {
- if (nodetype1 == nodetype3) {
- expr->data.diadic.left->data.diadic.left = expr->data.diadic.left->data.diadic.left->data.diadic.left;
- changed = 1;
- } else if (nodetype2 == nodetype3) {
- *expr = *expr->data.diadic.right;
- changed = 1;
- } else {
- expr->data.diadic.left = expr->data.diadic.left->data.diadic.right;
- changed = 1;
- }
- }
- }
- } while (changed);
- }
-}
-
-static void TransformExprTree1(ENode *expr) {
- ENodeList *list;
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- TransformExprTree1(expr->data.monadic);
- break;
-
- ENODE_CASE_DIADIC_ALL:
- TransformExprTree1(expr->data.diadic.left);
- TransformExprTree1(expr->data.diadic.right);
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- TransformExprTree1(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- TransformExprTree1(list->node);
- break;
-
- case ECOND:
- TransformExprTree1(expr->data.cond.cond);
- TransformExprTree1(expr->data.cond.expr1);
- TransformExprTree1(expr->data.cond.expr2);
- break;
-
- case ENULLCHECK:
- TransformExprTree1(expr->data.nullcheck.nullcheckexpr);
- TransformExprTree1(expr->data.nullcheck.condexpr);
- break;
- }
-
- FoldConstantsinAssociativeExprs(expr);
-}
-
-static int RemoveRedundantBitOperations(ENode *expr) {
- Boolean a;
- Boolean b;
-
- if (expr->type == ExprType) {
- a = RemoveRedundantBitOperations(expr->data.diadic.left);
- b = RemoveRedundantBitOperations(expr->data.diadic.right);
- return a & b;
- }
-
- if (expr->type == EINDIRECT) {
- if (expr->data.monadic->type == EOBJREF) {
- if (!OperandObject) {
- OperandObject = expr->data.monadic->data.objref;
- IndirectRef = expr;
- return 1;
- } else {
- return expr->data.monadic->data.objref == OperandObject;
- }
- } else {
- return 0;
- }
- }
-
- if (expr->type == EINTCONST) {
- if (FirstTime) {
- OperandConst = expr->data.intval;
- FirstTime = 0;
- } else if (ExprType == EAND) {
- OperandConst = CInt64_And(expr->data.intval, OperandConst);
- } else if (ExprType == EOR) {
- OperandConst = CInt64_Or(expr->data.intval, OperandConst);
- } else if (ExprType == EXOR) {
- OperandConst = CInt64_Xor(expr->data.intval, OperandConst);
- }
- return 1;
- }
-
- return 0;
-}
-
-static void TransformExprTree2(ENode *expr) {
- ENodeList *list;
-
- switch (expr->type) {
- ENODE_CASE_MONADIC:
- TransformExprTree2(expr->data.monadic);
- break;
-
- ENODE_CASE_DIADIC_ALL:
- TransformExprTree2(expr->data.diadic.left);
- TransformExprTree2(expr->data.diadic.right);
- break;
-
- case EFUNCCALL:
- case EFUNCCALLP:
- TransformExprTree2(expr->data.funccall.funcref);
- for (list = expr->data.funccall.args; list; list = list->next)
- TransformExprTree2(list->node);
- break;
-
- case ECOND:
- TransformExprTree2(expr->data.cond.cond);
- TransformExprTree2(expr->data.cond.expr1);
- TransformExprTree2(expr->data.cond.expr2);
- break;
-
- case ENULLCHECK:
- TransformExprTree2(expr->data.nullcheck.nullcheckexpr);
- TransformExprTree2(expr->data.nullcheck.condexpr);
- break;
- }
-
- if (
- ENODE_IS3(expr, EAND, EOR, EXOR) &&
- (expr->type == expr->data.diadic.left->type || expr->type == expr->data.diadic.right->type)
- )
- {
- OperandObject = NULL;
- ExprType = expr->type;
- FirstTime = 1;
- IndirectRef = NULL;
-
- if (RemoveRedundantBitOperations(expr)) {
- expr->data.diadic.left = IndirectRef;
- expr->data.diadic.right->type = EINTCONST;
- expr->data.diadic.right->data.intval = OperandConst;
- }
- }
-}
-
-static void PullOutPostOps(Statement *stmt, ENode **pExpr) {
- ENode *ind;
- ENode *inner;
- Statement *newStmt;
-
- switch ((*pExpr)->type) {
- ENODE_CASE_MONADIC:
- if ((*pExpr)->type != EFORCELOAD)
- PullOutPostOps(stmt, &(*pExpr)->data.monadic);
-
- if (ENODE_IS2(*pExpr, EPOSTINC, EPOSTDEC)) {
- inner = (*pExpr)->data.monadic;
- if (
- ENODE_IS(inner, EINDIRECT) &&
- inner->rtype &&
- !CParser_IsVolatile(inner->rtype, ENODE_QUALS(inner)) &&
- ENODE_IS(inner->data.monadic, EOBJREF) &&
- !is_volatile_object(inner->data.monadic->data.objref)
- )
- {
- newStmt = lalloc(sizeof(Statement));
- memset(newStmt, 0, sizeof(Statement));
- newStmt->type = ST_EXPRESSION;
- newStmt->expr = *pExpr;
- newStmt->dobjstack = stmt->dobjstack;
- newStmt->sourceoffset = stmt->sourceoffset;
- newStmt->sourcefilepath = stmt->sourcefilepath;
- newStmt->value = stmt->value;
- newStmt->flags = stmt->flags;
- newStmt->next = stmt->next;
- stmt->next = newStmt;
-
- ind = IRO_NewENode(EINDIRECT);
- *ind = *inner;
- ind->data.monadic = IRO_NewENode(EOBJREF);
- *ind->data.monadic = *inner->data.monadic;
- *pExpr = ind;
- }
- }
- break;
-
- ENODE_CASE_DIADIC_ALL:
- if (ENODE_IS(*pExpr, ECOND))
- break;
- if (ENODE_IS(*pExpr, ECOMMA))
- break;
- if (ENODE_IS(*pExpr, ELOR))
- break;
- if (ENODE_IS(*pExpr, ELAND))
- break;
- if (ENODE_IS(*pExpr, ENULLCHECK))
- break;
- PullOutPostOps(stmt, &(*pExpr)->data.diadic.left);
- PullOutPostOps(stmt, &(*pExpr)->data.diadic.right);
- break;
- }
-}
-
-void IRO_TransformTree(Statement *statements) {
- Statement *stmt;
- Statement *next;
-
- for (stmt = statements; stmt; stmt = next) {
- next = stmt->next;
- switch (stmt->type) {
- case ST_EXPRESSION:
- case ST_SWITCH:
- case ST_IFGOTO:
- case ST_IFNGOTO:
- case ST_RETURN:
- if (stmt->expr) {
- stmt->expr = TransformExprTree(stmt->expr);
- TransformExprTree2(stmt->expr);
- TransformExprTree1(stmt->expr);
- }
- break;
- }
- }
-
- IRO_CheckForUserBreak();
-}
diff --git a/compiler_and_linker/unsorted/IroUnrollLoop.c b/compiler_and_linker/unsorted/IroUnrollLoop.c
deleted file mode 100644
index 45b774e..0000000
--- a/compiler_and_linker/unsorted/IroUnrollLoop.c
+++ /dev/null
@@ -1,2305 +0,0 @@
-#include "compiler/IroUnrollLoop.h"
-#include "compiler/CError.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroUtil.h"
-#include "compiler/LoopDetection.h"
-#include "compiler/IroLoop.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroVars.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct LoopList {
- UInt8 flags;
- BitVector *bv;
- struct LoopList *next;
- IRONode *fnode;
- int xE;
-} LoopList;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-// forward decls
-static void IRO_FindLoops_Unroll(void);
-static void LoopUnroll(int count, IRONode *fnode);
-static int IsLoopUnrollable(IROLoop *loop);
-static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval);
-static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop);
-static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list);
-static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop);
-static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop);
-
-void IRO_LoopUnroller(void) {
- VectorPhaseCalledFromUnroll = 1;
- IRO_FindLoops_Unroll();
- IRO_CheckForUserBreak();
-}
-
-static void IRO_FindLoops_Unroll(void) {
- IRONode *fnode;
- IRONode *pred;
- UInt16 i;
- UInt16 flag;
- LoopList *list;
- LoopList *list2;
-
- fnode = IRO_FirstNode;
- LoopList_First = NULL;
-
- while (fnode) {
- flag = 0;
- for (i = 0; i < fnode->numpred; i++) {
- pred = IRO_NodeTable[fnode->pred[i]];
- if (Bv_IsBitSet(fnode->index, pred->dom)) {
- if (!flag) {
- Bv_AllocVector(&InLoop, IRO_NumNodes + 1);
- Bv_Clear(InLoop);
- Bv_SetBit(fnode->index, InLoop);
- }
- flag = 1;
- Bv_SetBit(pred->index, InLoop);
- if (pred != fnode)
- AddPreds(pred);
- }
- }
-
- if (flag) {
- if (!LoopList_First) {
- list = oalloc(sizeof(LoopList));
- list->next = NULL;
- } else {
- list = oalloc(sizeof(LoopList));
- list->next = LoopList_First;
- }
- LoopList_First = list;
-
- Bv_AllocVector(&list->bv, IRO_NumNodes + 1);
- list->flags |= 1;
- Bv_Copy(InLoop, list->bv);
- list->fnode = fnode;
- list->xE = 0;
- }
-
- fnode = fnode->nextnode;
- }
-
- list = LoopList_First;
- Bv_AllocVector(&LoopTemp, IRO_NumNodes + 1);
- while (list) {
- for (list2 = LoopList_First; list2; list2 = list2->next) {
- if (list2 != list) {
- IRO_Dump(" header = %d \n", list2->fnode->index);
- IRO_Dump(" l1 bit vector=\n");
- IRO_DumpBits("", list2->bv);
- IRO_Dump(" l bit vector=\n");
- IRO_DumpBits("", list->bv);
- if (Bv_IsSubset(list->bv, list2->bv))
- list2->flags &= ~1;
- }
- }
- list = list->next;
- }
-
- for (list = LoopList_First; list; list = list->next) {
- if (list->flags & 1) {
- IRONode *listfnode;
- Bv_Copy(list->bv, InLoop);
- listfnode = list->fnode;
- IRO_Dump("IRO_FindLoops_Unroll:Found loop with header %d\n", listfnode->index);
- IRO_DumpBits("Loop includes: ", InLoop);
- LoopUnroll(copts.unrollfactor, listfnode);
- IRO_UpdateFlagsOnInts();
- }
- }
-}
-
-static int CheckConstant(CInt64 a, CInt64 b, CInt64 *result) {
- CInt64 shl = cint64_zero;
- CInt64 work = cint64_zero;
- CInt64 and = cint64_zero;
- CInt64 i;
-
- for (i = cint64_zero; CInt64_Less(i, a); i = CInt64_Add(i, cint64_one)) {
- shl = CInt64_Shl(b, i);
- and = CInt64_And(shl, work);
- if (CInt64_NotEqual(and, cint64_zero))
- return 0;
- work = CInt64_Or(shl, work);
- }
-
- *result = work;
- return 1;
-}
-
-typedef struct LoopPattern {
- IROLinear *nd0;
- IROLinear *nd4;
- Type *type;
- IROLinear *ndC;
- IROLinear *nd10;
- CInt64 val14;
- CInt64 val1C;
-} LoopPattern;
-
-static void UnrollWhileLoopBody(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, LoopPattern *pattern, UInt32 unrollFactor) {
- IRONode *scan;
- int pass;
- IROLinear *firstnode;
- IROLinear *lastnd;
- IROLinear *nd;
- IROLinear *nd1;
- IROLinear *nd2;
- IROLinear *nd3;
- IROLinear *nd4;
- IROLinear *nd5;
- IROLinear *nd6;
- IROLinear *nd8;
- IROLinear *nd7;
- ENode *expr;
- IROList list;
- CInt64 zero;
- CInt64 shiftval;
-
- CInt64_SetLong(&zero, 0);
-
- pass = 0;
-
- do {
- firstnode = NULL;
- for (scan = fnode3; scan && scan != header; scan = scan->nextnode) {
- IRO_InitList(&list);
- lastnd = scan->last;
- nd = scan->first;
- while (1) {
- if (nd->stmt)
- nd->stmt->flags |= StmtFlag_10;
-
- if (
- (nd->index < loop->index20 || nd->index > loop->index24) &&
- nd->type != IROLinearLabel &&
- nd->type != IROLinearNop &&
- !(nd->flags & IROLF_Reffed)
- )
- {
- CError_ASSERT(345, nd->nodetype == EORASS || nd->nodetype == EANDASS || nd->nodetype == EXORASS);
-
- IRO_DuplicateExpr(pattern->nd0, &list);
- nd1 = list.tail;
-
- shiftval = cint64_one;
- shiftval = CInt64_Shl(shiftval, pattern->val1C);
-
- nd2 = IRO_NewLinear(IROLinearOperand);
- nd2->index = ++IRO_NumLinear;
- nd2->rtype = pattern->nd0->rtype;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = pattern->nd0->rtype;
- CInt64_SetLong(&expr->data.intval, pass * CInt64_GetULong(&shiftval));
- nd2->u.node = expr;
- IRO_AddToList(nd2, &list);
-
- IRO_DuplicateExpr(pattern->nd4, &list);
-
- nd3 = IRO_NewLinear(IROLinearOp2Arg);
- nd3->index = ++IRO_NumLinear;
- nd3->nodetype = EADD;
- nd3->rtype = pattern->type;
- nd3->u.diadic.left = list.tail;
- nd3->u.diadic.right = nd2;
- IRO_AddToList(nd3, &list);
-
- nd4 = IRO_NewLinear(IROLinearOp2Arg);
- nd4->index = ++IRO_NumLinear;
- nd4->nodetype = EADD;
- nd4->rtype = pattern->type;
- nd4->u.diadic.left = nd3;
- nd4->u.diadic.right = nd1;
- IRO_AddToList(nd4, &list);
-
- nd5 = IRO_NewLinear(IROLinearOp1Arg);
- nd5->index = ++IRO_NumLinear;
- nd5->nodetype = EINDIRECT;
- nd5->rtype = nd->rtype;
- nd5->u.monadic = nd4;
- IRO_AddToList(nd5, &list);
-
- nd6 = IRO_NewLinear(IROLinearOp2Arg);
- *nd6 = *nd;
- nd6->index = ++IRO_NumLinear;
- nd6->u.diadic.left = list.tail;
- nd6->next = NULL;
-
- nd7 = IRO_NewLinear(IROLinearOperand);
- nd7->index = ++IRO_NumLinear;
- nd7->rtype = pattern->ndC->rtype;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = pattern->ndC->rtype;
- nd7->u.node = expr;
- nd7->next = NULL;
- expr->data.intval = pattern->val14;
-
- if (
- IS_LINEAR_DIADIC(nd, EANDASS) &&
- CInt64_Equal(pattern->val14, cint64_zero)
- )
- {
- nd6->nodetype = EASS;
- } else if (
- IS_LINEAR_DIADIC(nd, EORASS) &&
- !CTool_EndianReadWord32(&pattern->val14.hi)
- )
- {
- UInt32 tmp = CInt64_GetULong(&pattern->val14);
- if (
- (nd->rtype->size == 1 && tmp == 0xFF) ||
- (nd->rtype->size == 2 && tmp == 0xFFFF) ||
- (nd->rtype->size == 4 && tmp == 0xFFFFFFFF)
- )
- {
- nd6->nodetype = EASS;
- }
- }
-
- IRO_AddToList(nd7, &list);
-
- if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) {
- nd8 = IRO_NewLinear(IROLinearOp1Arg);
- *nd8 = *pattern->nd10;
- nd8->index = ++IRO_NumLinear;
- nd8->u.monadic = nd7;
- nd8->next = NULL;
- IRO_AddToList(nd8, &list);
- } else {
- nd8 = nd7;
- }
- nd6->u.diadic.right = nd8;
- IRO_AddToList(nd6, &list);
-
- if (!firstnode)
- firstnode = list.head;
- }
-
- if (nd == lastnd)
- break;
- nd = nd->next;
- }
-
- if (list.head && list.tail)
- IRO_Paste(list.head, list.tail, fnode2->last);
- }
- } while (++pass < 8);
-}
-
-static int PatternMatchLoop(IRONode *fnode, IROLoop *loop, IROLoopInd *ind, UInt32 *unrollFactor, SInt32 *result1, SInt32 *result2, LoopPattern *pattern) {
- IROLinear *scan;
- IROLinear *varnode;
- IROLinear *nd1;
- IROLinear *nd2;
- IROLinear *left1;
- IROLinear *left2;
- IROLinear *right1;
- IROLinear *right2;
- Object *obj1;
- Object *obj2;
- CInt64 shl;
- CInt64 val;
-
- *result1 = 0;
- *result2 = 0;
-
- if ((scan = fnode->first)) {
- while (1) {
- if (
- (scan->index < loop->index20 || scan->index > loop->index24) &&
- !(scan->flags & IROLF_Reffed) &&
- scan->type != IROLinearNop &&
- scan->type != IROLinearLabel
- )
- {
- if (IS_LINEAR_DIADIC_3(scan, EORASS, EXORASS, EANDASS)) {
- (*result2)++;
- if (IS_LINEAR_MONADIC(scan->u.diadic.left, EINDIRECT)) {
- varnode = scan->u.diadic.left->u.monadic;
- if (IS_LINEAR_DIADIC(varnode, EADD)) {
- pattern->nd4 = varnode->u.diadic.left;
- pattern->type = varnode->rtype;
- if (IRO_IsVariable(varnode->u.diadic.left)) {
- pattern->nd0 = varnode->u.diadic.right;
- if (
- IS_LINEAR_DIADIC(pattern->nd0, ESHL) &&
- IRO_IsConstant(pattern->nd0->u.diadic.right)
- )
- {
- pattern->val1C = pattern->nd0->u.diadic.right->u.node->data.intval;
- nd1 = pattern->nd0->u.diadic.left;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
-
- pattern->nd10 = scan->u.diadic.right;
-
- if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) {
- if (IS_LINEAR_DIADIC(scan, EANDASS)) {
- if (IS_LINEAR_MONADIC(pattern->nd10->u.monadic, EBINNOT)) {
- pattern->ndC = pattern->nd10->u.monadic->u.monadic;
- } else {
- return 0;
- }
- } else {
- pattern->ndC = pattern->nd10->u.monadic;
- }
-
- if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) {
- val = pattern->ndC->u.diadic.left->u.node->data.intval;
- nd2 = pattern->ndC->u.diadic.right;
- } else {
- return 0;
- }
- } else if (IS_LINEAR_DIADIC(pattern->nd10, ESHL) && IS_LINEAR_DIADIC_2(scan, EORASS, EXORASS)) {
- pattern->ndC = pattern->nd10;
- if (IRO_IsConstant(pattern->ndC->u.diadic.left)) {
- val = pattern->ndC->u.diadic.left->u.node->data.intval;
- nd2 = pattern->ndC->u.diadic.right;
- } else {
- return 0;
- }
- } else if (IS_LINEAR_MONADIC(pattern->nd10, EBINNOT) && IS_LINEAR_DIADIC(scan, EANDASS)) {
- pattern->ndC = pattern->nd10->u.monadic;
- if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) {
- val = pattern->ndC->u.diadic.left->u.node->data.intval;
- nd2 = pattern->ndC->u.diadic.right;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
-
- if (IS_LINEAR_DIADIC(nd2, EAND) && IS_LINEAR_DIADIC(nd1, ESHR)) {
- left1 = nd1->u.diadic.left;
- left2 = nd2->u.diadic.left;
- obj1 = IRO_IsVariable(left1);
- obj2 = IRO_IsVariable(left2);
- if (obj1 == obj2 && obj1 == ind->var->object) {
- right1 = nd1->u.diadic.right;
- right2 = nd2->u.diadic.right;
- if (IRO_IsConstant(right1) && IRO_IsConstant(right2)) {
- shl = cint64_one;
- shl = CInt64_Shl(shl, right1->u.node->data.intval);
- shl = CInt64_Sub(shl, cint64_one);
- if (CInt64_Equal(shl, right2->u.node->data.intval)) {
- if (CTool_EndianReadWord32(&shl.hi) == 0) {
- *unrollFactor = CInt64_GetULong(&shl) + 1;
- if (CheckConstant(CInt64_Add(shl, cint64_one), val, &pattern->val14)) {
- (*result1)++;
- if (IS_LINEAR_DIADIC(scan, EANDASS))
- pattern->val14 = CInt64_Not(pattern->val14);
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
-
- if (scan == fnode->last)
- break;
- scan = scan->next;
- }
- }
-
- return 1;
-}
-
-static UInt32 UnrollWhileLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) {
- IROLoopInd *ind;
- IRONode *scan;
- CLabel *lastlabel;
- IROLinear *lastlabelnode;
- IROLinear *earlyLoopExitTest;
- CLabel *earlyLoopExitTestLabel;
- IROLinear *origIterationCount;
- IROLinear *unrolledFinalValue;
- IROLinear *preAlignTemp;
- IROLinear *newFinalValue;
- IROLinear *savedHead60;
- IROLinear *unrolledBodyEntryTest;
- CLabel *label;
- IROLinear *savedHead2;
- IROLinear *loophead25;
- IROLinear *loopend;
- IROLinear *loopscan;
- IROLinear *indvar;
- IROLinear *less;
- IROLinear *loopExitTest;
- IROLinear *saveTail;
- CLabel *label2;
- IROLinear *gotond;
- CLabel *label3;
- IROLinear *savedHead3;
- IROLinear *updIndInc;
- IROLinear *label2nd;
- IROLinear *less2;
- IROLinear *saveTail2;
- IROLinear *less3;
- IROLinear *wtf;
- IROLinear *constnd;
- IROLinear *ass;
- IROLinear *nd18;
- IRONode *fn19;
- IRONode *newfnode1;
- IRONode *newfnode2;
- IRONode *newfnode3;
- IRONode *newfnode4;
- IRONode *newfnode5;
- IRONode *newfnode6;
- IRONode *newfnode7;
- IRONode *newfnode8;
- IROLinear *lastnd;
- ENode *expr;
- SInt32 result1;
- SInt32 result2;
- LoopPattern pattern;
- IROList list;
-
- IRO_Dump("while(n--) loop \n");
-
- if (loop->flags & LoopFlags_800) {
- IRO_Dump("loop not unrolled because induction used in loop \n");
- return 0;
- }
- if (loop->flags & LoopFlags_1000) {
- IRO_Dump("loop not unrolled because loop has multiple exits \n");
- return 0;
- }
-
- if (!(loop->flags & LP_HAS_MULTIPLE_INDUCTIONS))
- return 0;
-
- for (ind = FirstInd; ind; ind = ind->next) {
- if ((ind->flags & LoopInd_HasMod) && (ind->flags & LoopInd_HasDiv))
- break;
- }
-
- if (!ind) {
- IRO_Dump("Could not find loop with and induction with MOD and DIV operation\n");
- return 0;
- }
-
- if (!IRO_IsUnsignedType(ind->nd->rtype))
- return 0;
-
- if (ind->nd->type == IROLinearOp2Arg) {
- if (ind->nd->nodetype == EADDASS && IRO_IsConstant(ind->nd->u.diadic.right)) {
- if (ind->addConst != 1)
- return 0;
- } else if (ind->nd->nodetype == EASS) {
- if (
- ind->nd->u.diadic.right->type != IROLinearOp2Arg ||
- ind->nd->u.diadic.right->nodetype != EADD ||
- !IRO_IsConstant(ind->nd->u.diadic.right->u.diadic.right)
- )
- return 0;
-
- if (ind->addConst != 1)
- return 0;
- } else {
- return 0;
- }
- } else if (ind->nd->type == IROLinearOp1Arg && ind->nd->nodetype != EPREINC && ind->nd->nodetype != EPOSTINC) {
- return 0;
- }
-
- loop->induction = ind;
- loop->index24 = ind->nd->index;
- loop->index20 = IRO_FindStart(ind->nd)->index;
-
- scan = IRO_FirstNode;
- memset(&pattern, 0, sizeof(pattern));
- while (scan) {
- if (Bv_IsBitSet(scan->index, InLoop) && scan != header) {
- if (!PatternMatchLoop(scan, loop, ind, &unrollFactor, &result1, &result2, &pattern))
- return 0;
- }
- scan = scan->nextnode;
- }
-
- if (result1 > 1 || result2 > 1)
- return 0;
-
- lastlabel = fnode2->last->u.label.label;
- lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last);
-
- IRO_InitList(&list);
- IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4->u.diadic.left, &list);
- IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
- lastlabelnode = list.tail;
-
- IRO_InitList(&list);
- earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list);
- earlyLoopExitTestLabel = IRO_NewLabel();
- earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel;
- earlyLoopExitTest->u.label.x4 = lastlabelnode;
- earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed;
- earlyLoopExitTest->rtype = LoopNode->last->rtype;
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- origIterationCount = BuildOrigIterationCount_DoWhile(&list, loop);
- IRO_Paste(list.head, list.tail, fnode2->last);
- savedHead60 = list.head;
-
- IRO_InitList(&list);
- preAlignTemp = BuildPreAlignTemp(ind, unrollFactor, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- unrolledFinalValue = BuildUnrolledFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- newFinalValue = BuildNewFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel);
- IRO_Paste(list.head, list.tail, fnode2->last);
- unrolledBodyEntryTest = list.tail;
-
- IRO_InitList(&list);
- label = BuildLabel(&list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- savedHead2 = list.head;
- loophead25 = NULL;
- for (scan = fnode3; scan && scan != header; scan = scan->nextnode) {
- IRO_InitList(&list);
- loopend = scan->last;
- loopscan = scan->first;
- while (1) {
- if (loopscan->stmt)
- loopscan->stmt->flags |= StmtFlag_10;
- if (loopscan->type != IROLinearLabel && !(loopscan->flags & IROLF_Reffed)) {
- IRO_DuplicateExpr(loopscan, &list);
- if (!loophead25)
- loophead25 = list.head;
- }
- if (loopscan == loopend)
- break;
- loopscan = loopscan->next;
- }
-
- if (list.head && list.tail)
- IRO_Paste(list.head, list.tail, fnode2->last);
- }
-
- IRO_InitList(&list);
-
- if (ind->nd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(ind->nd->u.monadic, &list);
- else
- IRO_DuplicateExpr(ind->nd->u.diadic.left, &list);
- list.tail->flags &= ~IROLF_Assigned;
- indvar = list.tail;
-
- IRO_DuplicateExpr(preAlignTemp, &list);
- list.tail->flags &= ~IROLF_Assigned;
-
- less = IRO_NewLinear(IROLinearOp2Arg);
- less->nodetype = ELESS;
- less->rtype = TYPE(&stbool);
- less->index = ++IRO_NumLinear;
- less->next = NULL;
- less->u.diadic.left = indvar;
- less->u.diadic.right = list.tail;
- IRO_AddToList(less, &list);
- less->flags |= IROLF_Reffed;
-
- loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list);
- loopExitTest->u.label.label = label;
- loopExitTest->u.label.x4 = less;
- loopExitTest->u.label.x4->flags |= IROLF_Reffed;
- loopExitTest->rtype = LoopNode->last->rtype;
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveTail = list.tail;
-
- IRO_InitList(&list);
- label2 = IRO_NewLabel();
- gotond = IRO_NewLinear(IROLinearOp1Arg);
- gotond->index = ++IRO_NumLinear;
- gotond->type = IROLinearGoto;
- gotond->u.label.label = label2;
- IRO_AddToList(gotond, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- label3 = BuildLabel(&list);
- IRO_Paste(list.head, list.tail, fnode2->last);
- savedHead3 = list.head;
-
- UnrollWhileLoopBody(header, fnode2, fnode3, loop, &pattern, unrollFactor);
- updIndInc = UpdateInductionIncrement(loop, 8 * unrollFactor, fnode2->last);
-
- IRO_InitList(&list);
- label2nd = IRO_NewLinear(IROLinearLabel);
- label2nd->index = IRO_NumLinear++;
- label2nd->u.label.label = label2;
- label2nd->flags |= IROLF_1;
- IRO_AddToList(label2nd, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
-
- if (ind->nd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(ind->nd->u.monadic, &list);
- else
- IRO_DuplicateExpr(ind->nd->u.diadic.left, &list);
- list.tail->flags &= ~IROLF_Assigned;
- indvar = list.tail;
-
- IRO_DuplicateExpr(unrolledFinalValue, &list);
- list.tail->flags &= ~IROLF_Assigned;
-
- less2 = IRO_NewLinear(IROLinearOp2Arg);
- less2->nodetype = ELESS;
- less2->rtype = TYPE(&stbool);
- less2->index = ++IRO_NumLinear;
- less2->next = NULL;
- less2->u.diadic.left = indvar;
- less2->u.diadic.right = list.tail;
- IRO_AddToList(less2, &list);
- less2->flags |= IROLF_Reffed;
-
- loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list);
- loopExitTest->u.label.label = label3;
- loopExitTest->u.label.x4 = less2;
- loopExitTest->u.label.x4->flags |= IROLF_Reffed;
- loopExitTest->rtype = LoopNode->last->rtype;
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveTail2 = list.tail;
-
- IRO_InitList(&list);
-
- if (ind->nd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(ind->nd->u.monadic, &list);
- else
- IRO_DuplicateExpr(ind->nd->u.diadic.left, &list);
- list.tail->flags &= ~IROLF_Assigned;
- indvar = list.tail;
-
- IRO_DuplicateExpr(newFinalValue, &list);
- list.tail->flags &= ~IROLF_Assigned;
-
- less3 = IRO_NewLinear(IROLinearOp2Arg);
- less3->nodetype = ELESS;
- less3->rtype = TYPE(&stbool);
- less3->index = ++IRO_NumLinear;
- less3->next = NULL;
- less3->u.diadic.left = indvar;
- less3->u.diadic.right = list.tail;
- IRO_AddToList(less3, &list);
- less3->flags |= IROLF_Reffed;
-
- wtf = LoopNode->last->u.label.x4;
- IRO_Paste(list.head, list.tail, LoopNode->last);
- LoopNode->last->u.label.x4 = list.tail;
-
- IRO_InitList(&list);
-
- constnd = IRO_NewLinear(IROLinearOperand);
- constnd->index = ++IRO_NumLinear;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = wtf->u.diadic.left->rtype;
- expr->data.intval = cint64_zero;
- constnd->u.node = expr;
- constnd->rtype = expr->rtype;
- IRO_AddToList(constnd, &list);
- constnd->flags |= IROLF_Reffed;
-
- IRO_DuplicateExpr(wtf->u.diadic.left, &list);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->nodetype = EASS;
- ass->rtype = list.tail->rtype;
- ass->index = ++IRO_NumLinear;
- ass->next = NULL;
- ass->u.diadic.left = list.tail;
- ass->u.diadic.right = constnd;
- IRO_AddToList(ass, &list);
- ass->flags |= IROLF_Assigned;
-
- IRO_NopOut(wtf);
-
- fn19 = fnode2->nextnode;
- nd18 = fnode2->last;
- fnode2->last = earlyLoopExitTest;
-
- newfnode1 = IRO_NewFlowGraphNode();
- newfnode1->first = savedHead60;
- newfnode1->last = unrolledBodyEntryTest;
- fnode2->nextnode = newfnode1;
-
- newfnode2 = IRO_NewFlowGraphNode();
- newfnode2->first = savedHead2;
- newfnode2->last = saveTail;
- savedHead2->u.label.label->stmt = (Statement *) newfnode2;
- newfnode1->nextnode = newfnode2;
-
- newfnode3 = IRO_NewFlowGraphNode();
- newfnode3->first = gotond;
- newfnode3->last = gotond;
- newfnode2->nextnode = newfnode3;
-
- newfnode4 = IRO_NewFlowGraphNode();
- newfnode4->first = savedHead3;
- newfnode4->last = updIndInc;
- savedHead3->u.label.label->stmt = (Statement *) newfnode4;
- newfnode3->nextnode = newfnode4;
-
- newfnode5 = IRO_NewFlowGraphNode();
- newfnode5->first = label2nd;
- newfnode5->last = saveTail2;
- label2nd->u.label.label->stmt = (Statement *) newfnode5;
- newfnode4->nextnode = newfnode5;
-
- newfnode6 = IRO_NewFlowGraphNode();
- newfnode6->first = nd18;
- newfnode6->last = nd18;
- newfnode5->nextnode = newfnode6;
- newfnode6->nextnode = fn19;
-
- newfnode7 = oalloc(sizeof(IRONode));
- memset(newfnode7, 0, sizeof(IRONode));
- newfnode7->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- newfnode7->first = list.head;
- newfnode7->last = list.tail;
-
- list.tail->next = LoopNode->last->next;
- LoopNode->last->next = list.head;
-
- newfnode7->nextnode = LoopNode->nextnode;
- LoopNode->nextnode = newfnode7;
-
- newfnode8 = oalloc(sizeof(IRONode));
- memset(newfnode8, 0, sizeof(IRONode));
- newfnode8->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- lastnd = IRO_NewLinear(IROLinearLabel);
- lastnd->index = IRO_NumLinear++;
- lastnd->next = NULL;
- lastnd->u.label.label = earlyLoopExitTestLabel;
- lastnd->flags |= IROLF_1;
- earlyLoopExitTestLabel->stmt = (Statement *) newfnode8;
-
- newfnode8->first = lastnd;
- newfnode8->last = lastnd;
-
- lastnd->next = newfnode7->last->next;
- newfnode7->last->next = lastnd;
-
- newfnode8->nextnode = newfnode7->nextnode;
- newfnode7->nextnode = newfnode8;
-
- return 1;
-}
-
-void IRO_IterateForLoopBody(IRONode *start, IRONode *end, IROLoop *loop, IROLinear *destnode, SInt32 addConst, CInt64 *val, Boolean funkyFlag) {
- IROLinear *first = NULL;
- IROLinear *last = NULL;
- IRONode *fnode;
- IROLinear *lastnd;
- IROLinear *nd;
- IROList list;
-
- for (fnode = start; fnode && fnode != end; fnode = fnode->nextnode) {
- IRO_InitList(&list);
-
- lastnd = fnode->last;
- nd = fnode->first;
- while (1) {
- if (nd->stmt)
- nd->stmt->flags |= StmtFlag_10;
-
- if (
- (nd->index < loop->index20 || nd->index > loop->index24) &&
- nd->type != IROLinearLabel &&
- !(nd->flags & IROLF_Reffed)
- )
- {
- IRO_DuplicateExpr(nd, &list);
- if (!first)
- first = list.head;
- last = list.tail;
- }
-
- if (nd == lastnd)
- break;
- nd = nd->next;
- }
-
- if (list.head && list.tail)
- IRO_Paste(list.head, list.tail, destnode);
- }
-
- if (funkyFlag) {
- *val = CInt64_Add(*val, IRO_MakeLong(loop->induction->addConst));
- ChangeInductionReference(first, last, *val, loop);
- }
-}
-
-void IRO_LinearizeForLoopPostLoop(IRONode *fnode1, IRONode *fnode2, IROLoop *loop, IRONode *fnode3, UInt32 unrollFactor) {
- IRONode *newfnode;
- IROLinear *newnd;
- SInt32 i;
- CInt64 val;
-
- newfnode = oalloc(sizeof(IRONode));
- memset(newfnode, 0, sizeof(IRONode));
- newfnode->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- newnd = IRO_NewLinear(IROLinearNop);
- newnd->index = IRO_NumLinear++;
- newnd->next = NULL;
- newnd->flags |= IROLF_1;
-
- newfnode->first = newfnode->last = newnd;
-
- newfnode->nextnode = fnode3->nextnode;
- fnode3->nextnode = newfnode;
-
- newnd->next = fnode3->last->next;
- fnode3->last->next = newnd;
-
- val = cint64_zero;
- for (i = 0; i < unrollFactor; i++)
- IRO_IterateForLoopBody(fnode2, fnode1, loop, newfnode->last, loop->induction->addConst, &val, i > 0);
- UpdateInductionIncrement(loop, unrollFactor, newfnode->last);
-}
-
-static UInt32 UnrollForLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) {
- IROLinear *lastlabelnode;
- IROLinear *earlyLoopExitTest;
- IROLinear *origIterationCount;
- IROLinear *saveHead1;
- IROLinear *newFinalValue;
- IROLinear *unrolledBodyEntryTest;
- IROLinear *gotoNd;
- IROLinear *saveHead2;
- IROLinear *updIndInc;
- IROLinear *labelNd;
- IROLinear *saveTail2;
- IROLinear *ndCopy;
- IROLinear *saveTail3;
- IROLinear *loopExitTest;
- IROLinear *lastnd;
- IROLinear *labelNd2;
- IROLinear *saveTail4;
- IROLinear *labelNd3;
- IROLinear *scan;
- IRONode *nd18;
- IRONode *newfnode1;
- IRONode *newfnode2;
- IRONode *newfnode3;
- IRONode *newfnode4;
- IRONode *newfnode5;
- IRONode *newfnode6;
- CLabel *lastlabel;
- CLabel *earlyLoopExitTestLabel;
- CLabel *label;
- CLabel *label2;
- SInt32 i;
-
- IROList list;
- CInt64 iterCount;
- int isConstant;
- UInt32 needOrigLoop = 0;
- UInt32 needUnrollBodyTest = 0;
- UInt32 resetUnrolledFinalValue = 0;
- SInt32 leftOver;
- CInt64 val;
-
- lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last);
- lastlabel = IRO_NewLabel();
-
- IRO_InitList(&list);
- IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4, &list);
- IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
- lastlabelnode = list.tail;
-
- IRO_InitList(&list);
- earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list);
- earlyLoopExitTestLabel = IRO_NewLabel();
- earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel;
- earlyLoopExitTest->u.label.x4 = lastlabelnode;
- earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed;
- earlyLoopExitTest->rtype = LoopNode->last->rtype;
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- isConstant = IsIterationCountConstant(loop, &iterCount);
- needOrigLoop = 1;
- needUnrollBodyTest = 1;
- resetUnrolledFinalValue = 0;
- if (isConstant)
- IRO_TestConstantIterationCount(loop, &iterCount, 1, &unrollFactor, &leftOver, &needOrigLoop, &needUnrollBodyTest, &resetUnrolledFinalValue);
-
- IRO_InitList(&list);
- origIterationCount = BuildOrigIterationCount(&list, loop);
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveHead1 = list.head;
-
- IRO_InitList(&list);
- newFinalValue = BuildNewFinalvalue(origIterationCount, unrollFactor, &list, loop);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel);
- IRO_Paste(list.head, list.tail, fnode2->last);
- unrolledBodyEntryTest = list.tail;
-
- label = IRO_NewLabel();
- IRO_InitList(&list);
- gotoNd = IRO_NewLinear(IROLinearOp1Arg);
- gotoNd->index = ++IRO_NumLinear;
- gotoNd->type = IROLinearGoto;
- gotoNd->u.label.label = label;
- IRO_AddToList(gotoNd, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
- label2 = BuildLabel(&list);
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveHead2 = list.head;
-
- val = cint64_zero;
- for (i = 0; i < unrollFactor; i++)
- IRO_IterateForLoopBody(fnode3, header, loop, fnode2->last, loop->induction->addConst, &val, i > 0);
- updIndInc = UpdateInductionIncrement(loop, unrollFactor, fnode2->last);
-
- IRO_InitList(&list);
- labelNd = IRO_NewLinear(IROLinearLabel);
- labelNd->index = IRO_NumLinear++;
- labelNd->u.label.label = label;
- labelNd->flags |= IROLF_1;
- IRO_AddToList(labelNd, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- IRO_InitList(&list);
-
- IRO_DuplicateExpr(LoopNode->last->u.label.x4->u.diadic.left, &list);
- saveTail2 = list.tail;
-
- if (resetUnrolledFinalValue)
- IRO_DuplicateExpr(loop->nd18->u.diadic.right, &list);
- else
- IRO_DuplicateExpr(newFinalValue, &list);
-
- ndCopy = IRO_NewLinear(LoopNode->last->u.label.x4->type);
- *ndCopy = *LoopNode->last->u.label.x4;
- ndCopy->index = ++IRO_NumLinear;
- ndCopy->next = NULL;
- ndCopy->expr = NULL;
- ndCopy->u.diadic.left = saveTail2;
- ndCopy->u.diadic.right = list.tail;
- IRO_AddToList(ndCopy, &list);
-
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveTail3 = list.tail;
-
- IRO_InitList(&list);
- loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list);
- loopExitTest->u.label.label = label2;
- loopExitTest->u.label.x4 = saveTail3;
- loopExitTest->u.label.x4->flags |= IROLF_Reffed;
- loopExitTest->rtype = LoopNode->last->rtype;
- IRO_Paste(list.head, list.tail, fnode2->last);
- saveTail4 = list.tail;
-
- IRO_InitList(&list);
- labelNd2 = IRO_NewLinear(IROLinearLabel);
- labelNd2->index = IRO_NumLinear++;
- labelNd2->u.label.label = lastlabel;
- labelNd2->flags |= IROLF_1;
- IRO_AddToList(labelNd2, &list);
- IRO_Paste(list.head, list.tail, fnode2->last);
-
- lastnd = fnode2->last;
- nd18 = fnode2->nextnode;
- fnode2->last = earlyLoopExitTest;
-
- newfnode1 = IRO_NewFlowGraphNode();
- newfnode1->first = saveHead1;
- newfnode1->last = unrolledBodyEntryTest;
- fnode2->nextnode = newfnode1;
-
- newfnode2 = IRO_NewFlowGraphNode();
- newfnode2->first = gotoNd;
- newfnode2->last = gotoNd;
- newfnode1->nextnode = newfnode2;
-
- newfnode3 = IRO_NewFlowGraphNode();
- newfnode3->first = saveHead2;
- newfnode3->last = updIndInc;
-
- saveHead2->u.label.label->stmt = (Statement *) newfnode3;
- if (newfnode2)
- newfnode2->nextnode = newfnode3;
- else
- newfnode1->nextnode = newfnode3;
-
- newfnode4 = IRO_NewFlowGraphNode();
- newfnode4->first = labelNd;
- newfnode4->last = saveTail4;
- labelNd->u.label.label->stmt = (Statement *) newfnode4;
- newfnode3->nextnode = newfnode4;
-
- newfnode5 = IRO_NewFlowGraphNode();
- newfnode5->first = labelNd2;
- newfnode5->last = lastnd;
- newfnode4->nextnode = newfnode5;
- newfnode5->nextnode = nd18;
-
- newfnode6 = oalloc(sizeof(IRONode));
- memset(newfnode6, 0, sizeof(IRONode));
- newfnode6->index = IRO_NumNodes;
- IRO_NumNodes++;
-
- labelNd3 = IRO_NewLinear(IROLinearLabel);
- labelNd3->index = IRO_NumLinear++;
- labelNd3->next = NULL;
- labelNd3->u.label.label = earlyLoopExitTestLabel;
- labelNd3->flags |= IROLF_1;
- earlyLoopExitTestLabel->stmt = (Statement *) newfnode6;
-
- newfnode6->first = labelNd3;
- newfnode6->last = labelNd3;
-
- labelNd3->next = LoopNode->last->next;
- LoopNode->last->next = labelNd3;
-
- newfnode6->nextnode = LoopNode->nextnode;
- LoopNode->nextnode = newfnode6;
-
- if (!needOrigLoop) {
- NoOpBlock(newfnode5);
- NoOpBlock(header);
- NoOpBlock(fnode3);
- NoOpBlock(loop->induction->fnode);
- IRO_NopOut(newfnode1->last->u.label.x4);
- newfnode1->last->type = IROLinearNop;
- }
-
- if (!needUnrollBodyTest) {
- IRO_NopOut(earlyLoopExitTest->u.label.x4);
- earlyLoopExitTest->type = IROLinearNop;
-
- IRO_NopOut(newfnode4->last->u.label.x4);
- newfnode4->last->type = IROLinearNop;
-
- if (newfnode2)
- newfnode2->last->type = IROLinearNop;
-
- for (scan = newfnode1->first; scan; scan = scan->next) {
- if (!(scan->flags & IROLF_Reffed))
- IRO_NopOut(scan);
- if (scan == newfnode1->last)
- break;
- }
- }
-
- return 1;
-}
-
-static UInt32 UnrollStandardLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, int count) {
- IROLoop *loop;
-
- ConditionalHeaderAtBottom = 1;
- loop = ExtractLoopInfo(header);
- loop->xC = fnode2;
- loop->x10 = fnode3;
- FindAssignmenttoInductionVar(loop, fnode2);
-
- if (!IsLoopUnrollable(loop)) {
- IRO_Dump("LoopUnroll:loop with header %d not unrolled because IsLoopUnrollable failed\n", header->index);
- return 0;
- }
-
- if (loop->flags & LoopFlags_10000)
- return UnrollWhileLoop(header, fnode2, fnode3, loop, count);
- else
- return UnrollForLoop(header, fnode2, fnode3, loop, count);
-}
-
-static void LoopUnroll(int count, IRONode *header) {
- VarRecord *var;
- IRONode *tmp;
- UInt16 i;
- UInt16 j;
- IRONode *prevpred;
- IRONode *prevsucc;
- int foundpred;
- UInt32 predcount;
- UInt32 success = 0;
-
- LoopNode = header;
- FindMustReach();
-
- for (var = IRO_FirstVar; var; var = var->next)
- var->xA = 1;
-
- ComputeLoopKills();
- ComputeLoopInvariance();
- ComputeLoopInduction();
-
- LoopNode = header;
- ConditionalHeaderAtBottom = 0;
-
- prevpred = NULL;
- foundpred = 0;
- for (i = 0; i < LoopNode->numpred; i++) {
- tmp = IRO_NodeTable[LoopNode->pred[i]];
- if (!Bv_IsBitSet(tmp->index, InLoop)) {
- foundpred = 1;
- if (tmp->nextnode == header) {
- CError_ASSERT(2101, !prevpred || tmp == prevpred);
- prevpred = tmp;
- }
- }
- }
-
- if (!foundpred) {
- IRO_Dump("No predecessor outside the loop\n");
- return;
- }
-
- if (LoopNode->last->type == IROLinearIf || LoopNode->last->type == IROLinearIfNot) {
- if (LoopNode->nextnode && !Bv_IsBitSet(LoopNode->nextnode->index, InLoop)) {
- prevsucc = NULL;
- for (i = 0; i < LoopNode->numsucc; i++) {
- tmp = IRO_NodeTable[LoopNode->succ[i]];
- if (Bv_IsBitSet(tmp->index, InLoop)) {
- CError_ASSERT(2159, !prevsucc);
- prevsucc = tmp;
- }
- }
-
- prevpred = NULL;
- predcount = 0;
- for (j = 0; j < LoopNode->numpred; j++) {
- tmp = IRO_NodeTable[LoopNode->pred[j]];
- if (!Bv_IsBitSet(tmp->index, InLoop)) {
- prevpred = tmp;
- predcount++;
- }
- }
-
- if (
- predcount == 1 &&
- prevpred->last->type == IROLinearGoto &&
- prevpred->nextnode == prevsucc &&
- prevsucc != LoopNode
- )
- {
- success = UnrollStandardLoop(header, prevpred, prevsucc, count);
- }
- }
- } else {
- IRO_Dump(" LoopUnroll:Loop with header = %d is not a conditional loop\n", header->index);
- }
-
- if (!success)
- return;
-
- IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes);
- memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes);
- for (tmp = IRO_FirstNode; tmp; tmp = tmp->nextnode)
- IRO_NodeTable[tmp->index] = tmp;
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- if (success)
- IRO_Dump(" LoopUnroll:Loop with header = %d Unrolled\n", header->index);
-}
-
-static int IsLoopUnrollable(IROLoop *loop) {
- CInt64 tmp;
-
- if (loop->flags & LP_LOOP_HAS_ASM) {
- IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_ASM \n");
- return 0;
- }
- if (loop->flags & LP_IFEXPR_NON_CANONICAL) {
- IRO_Dump("IsLoopUnrollable:No due to LP_IFEXPR_NON_CANONICAL \n");
- return 0;
- }
- if (loop->flags & LP_LOOP_HAS_CALLS) {
- IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CALLS \n");
- return 0;
- }
- if (loop->flags & LP_LOOP_HAS_CNTRLFLOW) {
- IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CNTRLFLOW \n");
- return 0;
- }
- if (loop->flags & LP_INDUCTION_NOT_FOUND) {
- IRO_Dump("IsLoopUnrollable:No due to LP_INDUCTION_NOT_FOUND \n");
- return 0;
- }
- if (loop->flags & LP_LOOP_HDR_HAS_SIDEEFFECTS) {
- IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HDR_HAS_SIDEEFFECTS \n");
- return 0;
- }
- if (!(loop->flags & LoopFlags_200)) {
- IRO_Dump("IsLoopUnrollable:No because header does not follow induction update \n");
- return 0;
- }
-
- if (!(loop->flags & LoopFlags_10000)) {
- IROLinear *upperBound = loop->nd18->u.diadic.right;
- if (!IRO_IsIntConstant(upperBound) && !(upperBound->flags & IROLF_LoopInvariant)) {
- IRO_Dump("IsLoopUnrollable:No because Loop Upper Bound is Variant in the loop\n");
- return 0;
- }
- if (!loop->nd14) {
- IRO_Dump("IsLoopUnrollable:No because there is no initialization of loop index in PreHeader\n");
- return 0;
- }
- if (!IRO_IsVariable(loop->nd14->u.diadic.left)) {
- IRO_Dump("IsLoopUnrollable:No because initial value of induction stored thru pointer\n");
- return 0;
- }
-
- if (!IRO_IsUnsignedType(loop->nd14->rtype)) {
- if (IRO_IsIntConstant(loop->nd14->u.diadic.right)) {
- if (!CInt64_GreaterEqual(loop->nd14->u.diadic.right->u.node->data.intval, cint64_zero)) {
- IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed but init < 0\n");
- return 0;
- }
- } else if (IsIterationCountConstant(loop, &tmp)) {
- IRO_Dump("IsLoopUnrollable:Yes, the limits substract out to be constants\n");
- } else {
- IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed and not constant\n");
- return 0;
- }
- }
-
- if (!(loop->flags & LP_LOOP_STEP_ISADD)) {
- IRO_Dump("IsLoopUnrollable:No because LP_LOOP_STEP_ISADD is not set i.e induciton is not updated by 1\n");
- return 0;
- }
-
- } else {
- if (!IRO_IsUnsignedType(loop->nd18->u.diadic.left->rtype)) {
- IRO_Dump("IsLoopUnrollable:No because the while loop induction is signed\n");
- return 0;
- }
- if (!(loop->flags & LoopFlags_2000)) {
- IRO_Dump("IsLoopUnrollable:No because the while loop operator is not of decrement form\n");
- return 0;
- }
- }
-
- if (loop->sizeBySomeMeasurement > copts.unrollinstrfactor) {
- IRO_Dump("IsLoopUnrollable:No because loop size greater than threshold\n");
- return 0;
- }
-
- return 1;
-}
-
-IROLinear *BuildEarlyLoopExitTest(IROLinearType type, IROList *list) {
- IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg);
- nd->index = ++IRO_NumLinear;
- if (type == IROLinearIf)
- nd->type = IROLinearIfNot;
- else
- nd->type = IROLinearIf;
- IRO_AddToList(nd, list);
- return nd;
-}
-
-IROLinear *BuildLoopExitTest(IROLinearType type, IROList *list) {
- IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg);
- nd->index = ++IRO_NumLinear;
- nd->type = type;
- IRO_AddToList(nd, list);
- return nd;
-}
-
-int IsIterationCountConstant(IROLoop *loop, CInt64 *pval) {
- IROLinear *lowerBound;
- IROLinear *upperBound;
- Type *type;
- int isUnsigned;
- IROAddrRecord *lowerRec;
- IROAddrRecord *upperRec;
- CInt64 lowerval;
- CInt64 upperval;
- CInt64 incval;
- CInt64 negOne;
-
- lowerBound = loop->nd14->u.diadic.right;
- if (loop->flags & LoopFlags_1) {
- upperBound = loop->nd18->u.diadic.right;
- type = loop->nd18->u.diadic.right->rtype;
- } else {
- upperBound = loop->nd18->u.diadic.left;
- type = loop->nd18->u.diadic.left->rtype;
- }
-
- isUnsigned = IRO_IsUnsignedType(type);
-
- if (IRO_IsIntConstant(lowerBound) && IRO_IsIntConstant(upperBound)) {
- lowerval = lowerBound->u.node->data.intval;
- upperval = upperBound->u.node->data.intval;
- if (isUnsigned) {
- if (CInt64_LessEqualU(upperval, lowerval))
- return 0;
- } else {
- if (CInt64_LessEqual(upperval, lowerval))
- return 0;
- }
-
- CInt64_SetLong(&incval, loop->induction->addConst);
- CInt64_SetLong(&negOne, -1);
- *pval = CInt64_Sub(upperval, lowerval);
- *pval = CInt64_Add(*pval, incval);
-
- if (IS_LINEAR_DIADIC(loop->nd18, ELESS))
- *pval = CInt64_Add(*pval, negOne);
-
- CError_ASSERT(2486, !CInt64_IsZero(&incval));
-
- if (isUnsigned)
- *pval = CInt64_DivU(*pval, incval);
- else
- *pval = CInt64_Div(*pval, incval);
-
- if (CInt64_Equal(*pval, cint64_zero))
- return 0;
-
- if (isUnsigned) {
- CError_ASSERT(2508, !CInt64_LessEqualU(*pval, cint64_zero));
- } else {
- CError_ASSERT(2517, !CInt64_LessEqual(*pval, cint64_zero));
- }
-
- return 1;
- }
-
- lowerRec = IRO_InitAddrRecordPointer(lowerBound);
- upperRec = IRO_InitAddrRecordPointer(upperBound);
-
- if (IS_LINEAR_DIADIC(lowerBound, EADD)) {
- IRO_DecomposeAddressExpression(lowerBound, lowerRec);
- } else if (IRO_IsIntConstant(lowerBound)) {
- lowerRec->numInts++;
- IRO_AddElmToList(lowerBound, &lowerRec->ints);
- lowerRec->numObjRefs = 0;
- lowerRec->numMisc = 0;
- } else {
- lowerRec->numMisc++;
- IRO_AddElmToList(lowerBound, &lowerRec->misc);
- lowerRec->numObjRefs = 0;
- lowerRec->numInts = 0;
- }
-
- if (IS_LINEAR_DIADIC(upperBound, EADD)) {
- IRO_DecomposeAddressExpression(upperBound, upperRec);
- } else if (IRO_IsIntConstant(upperBound)) {
- upperRec->numInts++;
- IRO_AddElmToList(upperBound, &upperRec->ints);
- upperRec->numObjRefs = 0;
- upperRec->numMisc = 0;
- } else {
- upperRec->numMisc++;
- IRO_AddElmToList(upperBound, &upperRec->misc);
- upperRec->numObjRefs = 0;
- upperRec->numInts = 0;
- }
-
- if (IsDifferenceOfTermsConstant(lowerRec, upperRec, isUnsigned, pval)) {
- if (IS_LINEAR_DIADIC(loop->nd18, ELESSEQU))
- *pval = CInt64_Add(*pval, cint64_one);
- return 1;
- }
-
- return 0;
-}
-
-static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval) {
- UInt32 i;
- CInt64 upperval;
- CInt64 lowerval;
- IROElmList *el;
- IROLinear *nd;
-
- if (upperRec->numObjRefs == lowerRec->numObjRefs && upperRec->numObjRefs != 0)
- return 0;
- else if (upperRec->numObjRefs != lowerRec->numObjRefs)
- return 0;
-
- if (upperRec->numMisc == lowerRec->numMisc && upperRec->numMisc != 0) {
- for (i = 0; i < upperRec->numMisc; i++) {
- // bug? surely this should index on i...?
- if (!IRO_ExprsSame(lowerRec->misc->element, upperRec->misc->element))
- return 0;
- }
- } else if (upperRec->numMisc != lowerRec->numMisc) {
- return 0;
- }
-
- upperval = cint64_zero;
- for (el = upperRec->ints; el; el = el->next) {
- nd = el->element;
- upperval = CMach_CalcIntDiadic(nd->rtype, upperval, '+', nd->u.node->data.intval);
- }
-
- lowerval = cint64_zero;
- for (el = lowerRec->ints; el; el = el->next) {
- nd = el->element;
- lowerval = CMach_CalcIntDiadic(nd->rtype, lowerval, '+', nd->u.node->data.intval);
- }
-
- if (CInt64_Equal(upperval, lowerval))
- return 0;
-
- if (CInt64_Greater(upperval, lowerval)) {
- *pval = CInt64_Sub(upperval, lowerval);
- return 1;
- } else {
- return 0;
- }
-}
-
-void NoOpBlock(IRONode *fnode) {
- IROLinear *last, *scan;
-
- for (scan = fnode->first, last = fnode->last; scan; scan = scan->next) {
- scan->type = IROLinearNop;
- if (scan == last)
- break;
- }
-}
-
-void IRO_TestConstantIterationCount(IROLoop *loop, CInt64 *iterCount, SInt32 vectorStride, UInt32 *unrollFactor, SInt32 *leftOver, UInt32 *needOrigLoop, UInt32 *needUnrollBodyTest, UInt32 *resetUnrolledFinalValue) {
- UInt32 isUnsigned;
- CInt64 val;
- CInt64 val3;
- CInt64 mod;
- CInt64 val2;
- CInt64 loopvar3;
- CInt64 loopvar1;
- CInt64 loopvar2;
- CInt64 strideVal;
-
- CError_ASSERT(2737, *unrollFactor);
-
- isUnsigned = IRO_IsUnsignedType(
- (loop->flags & LoopFlags_1) ? loop->nd18->u.diadic.right->rtype :loop->nd18->u.diadic.left->rtype);
-
- CError_ASSERT(2756, vectorStride);
-
- strideVal = IRO_MakeLong(vectorStride);
- if (isUnsigned ? CInt64_LessU(*iterCount, strideVal) : CInt64_Less(*iterCount, strideVal)) {
- *needOrigLoop = 1;
- *needUnrollBodyTest = 0;
- *unrollFactor = 0;
- *leftOver = CInt64_GetULong(iterCount);
- } else {
- switch (vectorStride) {
- case 1:
- val = *iterCount;
- break;
- case 2:
- val = CInt64_ShrU(*iterCount, cint64_one);
- break;
- case 4:
- val = CInt64_ShrU(*iterCount, IRO_MakeLong(2));
- break;
- case 8:
- val = CInt64_ShrU(*iterCount, IRO_MakeLong(3));
- break;
- case 16:
- val = CInt64_ShrU(*iterCount, IRO_MakeLong(4));
- break;
- default:
- val = CInt64_Div(*iterCount, strideVal);
- }
-
- if (CInt64_LessU(val, IRO_MakeLong(*unrollFactor)))
- *unrollFactor = CInt64_GetULong(&val);
-
- CInt64_SetLong(&val2, *unrollFactor);
- switch (vectorStride) {
- case 1:
- val3 = cint64_zero;
- break;
- case 2:
- val3 = CInt64_And(*iterCount, cint64_one);
- break;
- case 4:
- val3 = CInt64_And(*iterCount, IRO_MakeLong(3));
- break;
- case 8:
- val3 = CInt64_And(*iterCount, IRO_MakeLong(7));
- break;
- case 16:
- val3 = CInt64_And(*iterCount, IRO_MakeLong(15));
- break;
- default:
- val3 = CInt64_Mod(*iterCount, strideVal);
- }
-
- if (CInt64_LessEqualU(val, IRO_MakeLong(8))) {
- *needUnrollBodyTest = vectorStride > 1;
- *unrollFactor = CInt64_GetULong(&val);
- *leftOver = CInt64_GetULong(&val3);
- *needOrigLoop = *leftOver != 0;
- *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest);
- } else {
- loopvar1 = IRO_MakeLong(0x7FFFFFFF);
- loopvar2 = IRO_MakeLong(0x7FFFFFFF);
- do {
- mod = CInt64_Mod(val, val2);
- loopvar3 = CInt64_Add(CInt64_Mul(mod, strideVal), val3);
- if (CInt64_Less(loopvar3, loopvar2)) {
- loopvar2 = loopvar3;
- loopvar1 = val2;
- }
- if (vectorStride > 1)
- break;
- val2 = CInt64_Add(val2, cint64_negone);
- } while (CInt64_GreaterEqualU(CInt64_Mul(val2, val2), val));
-
- *unrollFactor = CInt64_GetULong(&loopvar1);
- *leftOver = CInt64_GetULong(&loopvar2);
- *needOrigLoop = *leftOver != 0;
- *needUnrollBodyTest = CInt64_Less(loopvar1, val) || vectorStride > 1;
- *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest);
- }
- }
-
- IRO_Dump(
- "---- IterCount = %d, VectorStride = %d, UnrollFactor = %d, LeftOver = %d,\n"
- "\tNeedOrigLoop = %d, NeedUnrollBodyTest = %d, ResetUnrolledFinalValue = %d\n",
- CInt64_GetULong(iterCount), vectorStride, *unrollFactor, *leftOver,
- *needOrigLoop, *needUnrollBodyTest, *resetUnrolledFinalValue
- );
-}
-
-IROLinear *BuildOrigIterationCount(IROList *list, IROLoop *loop) {
- IROLinear *upperBound;
- IROLinear *nd29b;
- IROLinear *lowerBound;
- IROLinear *finalCount;
- IROLinear *divisor;
- Type *type;
- IROLinear *nd25;
- IROLinear *tmp;
- Boolean isZeroBase;
- Object *tempobj;
- IROLinear *iterCount;
- IROLinear *negone;
- IROLinear *ass;
- ENode *expr;
- SInt32 powval;
-
- isZeroBase = 0;
- lowerBound = loop->nd14->u.diadic.right;
- if (IRO_IsIntConstant(lowerBound) && CInt64_Equal(lowerBound->u.node->data.intval, cint64_zero))
- isZeroBase = 1;
-
- if (!isZeroBase)
- lowerBound = IRO_DuplicateExpr(lowerBound, list);
-
- if (loop->flags & LoopFlags_1) {
- upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list);
- type = loop->nd18->u.diadic.right->rtype;
- } else {
- upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list);
- type = loop->nd18->u.diadic.left->rtype;
- }
-
- CError_ASSERT(2924, loop->induction);
- CError_ASSERT(2929, loop->induction->addConst);
-
- divisor = IRO_NewLinear(IROLinearOperand);
- divisor->index = ++IRO_NumLinear;
- divisor->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, loop->induction->addConst);
- divisor->u.node = expr;
-
- if (isZeroBase) {
- iterCount = upperBound;
- } else {
- iterCount = IRO_NewLinear(IROLinearOp2Arg);
- iterCount->index = ++IRO_NumLinear;
- iterCount->nodetype = ESUB;
- iterCount->u.diadic.left = upperBound;
- iterCount->u.diadic.right = lowerBound;
- iterCount->rtype = type;
- IRO_AddToList(iterCount, list);
- }
-
- nd25 = IRO_DuplicateExpr(divisor, list);
-
- nd29b = IRO_NewLinear(IROLinearOp2Arg);
- nd29b->index = ++IRO_NumLinear;
- nd29b->nodetype = EADD;
- nd29b->u.diadic.left = iterCount;
- nd29b->u.diadic.right = nd25;
- nd29b->rtype = type;
- IRO_AddToList(nd29b, list);
-
- if (loop->nd18->type == IROLinearOp2Arg && loop->nd18->nodetype == ELESS) {
- tmp = nd29b;
-
- negone = IRO_NewLinear(IROLinearOperand);
- negone->index = ++IRO_NumLinear;
- negone->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, -1);
- negone->u.node = expr;
- IRO_AddToList(negone, list);
-
- nd29b = IRO_NewLinear(IROLinearOp2Arg);
- nd29b->index = ++IRO_NumLinear;
- nd29b->nodetype = EADD;
- nd29b->u.diadic.left = tmp;
- nd29b->u.diadic.right = negone;
- nd29b->rtype = type;
- IRO_AddToList(nd29b, list);
- }
-
- if (CInt64_Equal(divisor->u.node->data.intval, cint64_one)) {
- finalCount = nd29b;
- } else {
- if (divisor->rtype->size <= 4 && IS_TYPE_INT(divisor->rtype) && IRO_IsPow2(divisor, &powval)) {
- finalCount = IRO_NewLinear(IROLinearOp2Arg);
- finalCount->index = ++IRO_NumLinear;
- finalCount->nodetype = ESHL;
- finalCount->u.diadic.left = nd29b;
- finalCount->u.diadic.right = divisor;
- CInt64_SetLong(&divisor->u.node->data.intval, powval);
- finalCount->rtype = type;
- IRO_AddToList(divisor, list);
- IRO_AddToList(finalCount, list);
- } else {
- finalCount = IRO_NewLinear(IROLinearOp2Arg);
- finalCount->index = ++IRO_NumLinear;
- finalCount->nodetype = EDIV;
- finalCount->u.diadic.left = nd29b;
- finalCount->u.diadic.right = divisor;
- finalCount->rtype = type;
- IRO_AddToList(divisor, list);
- IRO_AddToList(finalCount, list);
- }
- }
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = finalCount;
- ass->u.diadic.right->flags |= IROLF_Reffed;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop) {
- IROLinear *finalCount;
- IROLinear *count;
- IROLinear *ass;
- Type *type;
- Object *tempobj;
- ENode *expr;
-
- type = loop->nd18->u.diadic.left->rtype;
-
- count = IRO_NewLinear(IROLinearOperand);
- count->index = ++IRO_NumLinear;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- expr->data.intval = cint64_one;
- count->u.node = expr;
- count->rtype = type;
- IRO_AddToList(count, list);
- count->flags |= IROLF_Reffed;
-
- finalCount = IRO_NewLinear(IROLinearOp2Arg);
- finalCount->index = ++IRO_NumLinear;
- finalCount->nodetype = EADD;
- finalCount->rtype = type;
- finalCount->u.diadic.left = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list);
- finalCount->u.diadic.left->flags |= IROLF_Reffed;
- finalCount->u.diadic.left->flags &= ~IROLF_Assigned;
- finalCount->u.diadic.left->u.monadic->flags &= ~IROLF_Assigned;
- finalCount->u.diadic.right = count;
- IRO_AddToList(finalCount, list);
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = finalCount;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-IROLinear *BuildNewFinalvalue(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) {
- IROLinear *sub;
- IROLinear *addvalue;
- Type *type;
- IROLinear *ass;
- IROLinear *dupbound;
- Object *tempobj;
- ENode *expr;
-
- type = iterCount->rtype;
-
- addvalue = IRO_NewLinear(IROLinearOperand);
- addvalue->index = ++IRO_NumLinear;
- addvalue->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor);
- addvalue->u.node = expr;
- IRO_AddToList(addvalue, list);
-
- if (loop->flags & LoopFlags_1)
- dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list);
- else
- dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list);
-
- sub = IRO_NewLinear(IROLinearOp2Arg);
- sub->index = ++IRO_NumLinear;
- sub->nodetype = ESUB;
- sub->u.diadic.left = dupbound;
- sub->u.diadic.right = addvalue;
- sub->rtype = type;
- IRO_AddToList(sub, list);
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = sub;
- ass->u.diadic.right->flags |= IROLF_Reffed;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list) {
- Type *type;
- IROLinear *indnd;
- IROLinear *factornd;
- IROLinear *div;
- IROLinear *constnd;
- IROLinear *add;
- IROLinear *mul;
- IROLinear *ass;
- Object *tempobj;
- ENode *expr;
-
- indnd = ind->nd;
- type = indnd->rtype;
-
- factornd = IRO_NewLinear(IROLinearOperand);
- factornd->index = ++IRO_NumLinear;
- factornd->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, unrollFactor);
- factornd->u.node = expr;
- IRO_AddToList(factornd, list);
-
- if (indnd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(indnd->u.monadic, list);
- else
- IRO_DuplicateExpr(indnd->u.diadic.left, list);
-
- list->tail->flags &= ~IROLF_Assigned;
- list->tail->u.monadic->flags &= ~IROLF_Assigned;
-
- div = IRO_NewLinear(IROLinearOp2Arg);
- div->index = ++IRO_NumLinear;
- div->nodetype = EDIV;
- div->u.diadic.left = list->tail;
- div->u.diadic.right = factornd;
- div->rtype = type;
- IRO_AddToList(div, list);
- div->flags |= IROLF_Reffed;
-
- constnd = IRO_NewLinear(IROLinearOperand);
- constnd->index = ++IRO_NumLinear;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- expr->data.intval = cint64_one;
- constnd->u.node = expr;
- constnd->rtype = type;
- IRO_AddToList(constnd, list);
- constnd->flags |= IROLF_Reffed;
-
- add = IRO_NewLinear(IROLinearOp2Arg);
- add->index = ++IRO_NumLinear;
- add->nodetype = EADD;
- add->u.diadic.left = div;
- add->u.diadic.right = constnd;
- add->rtype = type;
- IRO_AddToList(add, list);
- add->flags |= IROLF_Reffed;
-
- IRO_DuplicateExpr(factornd, list);
-
- mul = IRO_NewLinear(IROLinearOp2Arg);
- mul->index = ++IRO_NumLinear;
- mul->nodetype = EMUL;
- mul->u.diadic.left = add;
- mul->u.diadic.right = list->tail;
- mul->rtype = type;
- IRO_AddToList(mul, list);
- mul->flags |= IROLF_Reffed;
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = mul;
- ass->u.diadic.right->flags |= IROLF_Reffed;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) {
- IROLinear *addvalue;
- IROLinear *add;
- IROLinear *mul;
- IROLinear *ass;
- Type *type;
- Object *tempobj;
- ENode *expr;
-
- type = iterCount->rtype;
-
- addvalue = IRO_NewLinear(IROLinearOperand);
- addvalue->index = ++IRO_NumLinear;
- addvalue->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, loop->induction->addConst);
- addvalue->u.node = expr;
- IRO_AddToList(addvalue, list);
- addvalue->flags |= IROLF_Reffed;
-
- mul = IRO_NewLinear(IROLinearOp2Arg);
- mul->index = ++IRO_NumLinear;
- mul->nodetype = EMUL;
- mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list);
- mul->u.diadic.right = addvalue;
- mul->rtype = type;
- IRO_AddToList(mul, list);
- mul->flags |= IROLF_Reffed;
- mul->u.diadic.left->flags &= ~IROLF_Assigned;
- mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned;
-
- if (loop->induction->nd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(loop->induction->nd->u.monadic, list);
- else
- IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list);
- list->tail->flags &= ~IROLF_Assigned;
- list->tail->u.diadic.left->flags &= ~IROLF_Assigned;
-
- add = IRO_NewLinear(IROLinearOp2Arg);
- add->index = ++IRO_NumLinear;
- add->nodetype = EADD;
- add->u.diadic.left = mul;
- add->u.diadic.right = list->tail;
- add->rtype = type;
- IRO_AddToList(add, list);
- add->flags |= IROLF_Reffed;
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = add;
- ass->u.diadic.right->flags |= IROLF_Reffed;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) {
- IROLinear *addvalue_mult;
- IROLinear *addvalue;
- IROLinear *mul;
- IROLinear *sub;
- IROLinear *add;
- IROLinear *ass;
- Type *type;
- Object *tempobj;
- ENode *expr;
-
- type = iterCount->rtype;
-
- addvalue_mult = IRO_NewLinear(IROLinearOperand);
- addvalue_mult->index = ++IRO_NumLinear;
- addvalue_mult->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor);
- addvalue_mult->u.node = expr;
- IRO_AddToList(addvalue_mult, list);
- addvalue_mult->flags |= IROLF_Reffed;
-
- addvalue = IRO_NewLinear(IROLinearOperand);
- addvalue->index = ++IRO_NumLinear;
- addvalue->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, loop->induction->addConst);
- addvalue->u.node = expr;
- IRO_AddToList(addvalue, list);
- addvalue->flags |= IROLF_Reffed;
-
- mul = IRO_NewLinear(IROLinearOp2Arg);
- mul->index = ++IRO_NumLinear;
- mul->nodetype = EMUL;
- mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list);
- mul->u.diadic.right = addvalue;
- mul->rtype = type;
- IRO_AddToList(mul, list);
- mul->flags |= IROLF_Reffed;
- mul->u.diadic.left->flags &= ~IROLF_Assigned;
- mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned;
-
- sub = IRO_NewLinear(IROLinearOp2Arg);
- sub->index = ++IRO_NumLinear;
- sub->nodetype = ESUB;
- sub->u.diadic.left = mul;
- sub->u.diadic.right = addvalue_mult;
- sub->rtype = type;
- IRO_AddToList(sub, list);
- sub->flags |= IROLF_Reffed;
-
- if (loop->induction->nd->type == IROLinearOp1Arg)
- IRO_DuplicateExpr(loop->induction->nd->u.monadic, list);
- else
- IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list);
- list->tail->flags &= ~IROLF_Assigned;
- list->tail->u.diadic.left->flags &= ~IROLF_Assigned;
-
- add = IRO_NewLinear(IROLinearOp2Arg);
- add->index = ++IRO_NumLinear;
- add->nodetype = EADD;
- add->u.diadic.left = sub;
- add->u.diadic.right = list->tail;
- add->rtype = type;
- IRO_AddToList(add, list);
- add->flags |= IROLF_Reffed;
-
- tempobj = create_temp_object(type);
- IRO_FindVar(tempobj, 1, 1);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EASS;
- ass->u.diadic.left = IRO_TempReference(tempobj, list);
- ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind;
- ass->u.diadic.right = add;
- ass->u.diadic.right->flags |= IROLF_Reffed;
- ass->rtype = type;
- IRO_AddToList(ass, list);
-
- return ass->u.diadic.left;
-}
-
-void BuildUnrolledBodyEntryTest(IROList *list, IROLinear *iterCount, UInt32 unrollFactor, CLabel *label) {
- Type *type;
- IROLinear *ifnot;
- IROLinear *comp;
- IROLinear *var;
- IROLinear *value;
- ENode *expr;
-
- type = iterCount->rtype;
-
- value = IRO_NewLinear(IROLinearOperand);
- value->index = ++IRO_NumLinear;
- value->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, unrollFactor);
- value->u.node = expr;
- IRO_AddToList(value, list);
-
- var = IRO_DuplicateExpr(iterCount, list);
-
- comp = IRO_NewLinear(IROLinearOp2Arg);
- comp->index = ++IRO_NumLinear;
- comp->nodetype = EGREATER;
- comp->u.diadic.left = var;
- comp->u.diadic.right = value;
- comp->u.diadic.right->flags |= IROLF_Reffed;
- comp->rtype = type;
- IRO_AddToList(comp, list);
-
- ifnot = IRO_NewLinear(IROLinearOp1Arg);
- ifnot->index = ++IRO_NumLinear;
- ifnot->type = IROLinearIfNot;
- ifnot->u.label.x4 = comp;
- ifnot->u.label.x4->flags |= IROLF_Reffed;
- ifnot->rtype = type;
- ifnot->u.label.label = label;
- IRO_AddToList(ifnot, list);
-}
-
-void ChangeInductionReference(IROLinear *first, IROLinear *last, CInt64 val, IROLoop *loop) {
- IROLinear *nd;
- IROLinear *value;
- IROLinear *add;
- UInt32 isUnsigned;
- IROLinear *father;
- Boolean flag;
- IROLinear *father2;
- IROLinear *father3;
- Type *tmp;
- UInt32 flag2;
- Object *varobj;
- IROLinear *next;
- ENode *expr;
- Type *type;
-
- CInt64 val2;
- CInt64 val1;
- IROList list;
-
- type = loop->induction->nd->rtype;
- isUnsigned = IRO_IsUnsignedType(type);
-
- for (nd = first; nd; nd = next) {
- next = nd->next;
-
- varobj = IRO_IsVariable(nd);
- if (varobj && loop->induction->var->object == varobj) {
- value = IRO_NewLinear(IROLinearOperand);
- value->index = ++IRO_NumLinear;
- value->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- expr->data.intval = val;
- value->u.node = expr;
-
- add = IRO_NewLinear(IROLinearOp2Arg);
- add->index = ++IRO_NumLinear;
- add->nodetype = EADD;
- add->rtype = type;
-
- father = IRO_LocateFather(nd);
- flag = 1;
- if (father && IS_LINEAR_MONADIC(father, ETYPCON)) {
- tmp = father->rtype;
- father = IRO_LocateFather(father);
- if (tmp->type != nd->rtype->type || tmp->size < nd->rtype->size)
- flag = 0;
- }
-
- flag2 = 0;
- if (
- flag &&
- father &&
- IS_LINEAR_DIADIC_2(father, ESHL, EMUL) &&
- IRO_IsIntConstant(father->u.diadic.right) &&
- (father2 = IRO_LocateFather(father)) &&
- IS_LINEAR_DIADIC(father2, EADD) &&
- father2->u.diadic.right == father &&
- (father3 = IRO_LocateFather(father2))
- )
- {
- IRO_InitList(&list);
- val2 = father->u.diadic.right->u.node->data.intval;
- if (father->nodetype == ESHL)
- val2 = CInt64_Shl(cint64_one, val2);
-
- val1 = value->u.node->data.intval;
- if (isUnsigned)
- val1 = CInt64_MulU(val2, val1);
- else
- val1 = CInt64_Mul(val2, val1);
- value->u.node->data.intval = val1;
-
- IRO_AddToList(value, &list);
- IRO_AddToList(add, &list);
- add->u.diadic.right = value;
- IRO_Paste(list.head, list.tail, father3);
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(father2, add);
- add->u.diadic.left = father2;
- add->rtype = father2->rtype;
- flag2 = 1;
- }
-
- if (!flag2) {
- add->u.diadic.right = value;
- add->u.diadic.right->flags |= IROLF_Reffed;
- value->next = add;
-
- add->u.diadic.left = nd;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, add);
- add->flags |= IROLF_Reffed;
-
- nd->next = value;
- add->next = next;
- }
- }
-
- if (nd == last)
- break;
- }
-}
-
-IROLinear *UpdateInductionIncrement(IROLoop *loop, SInt32 value, IROLinear *before) {
- IROLinear *ind_nd;
- IROLinear *addvalue;
- IROLinear *ass;
- Type *type;
- ENode *expr;
- IROList list;
-
- IRO_InitList(&list);
- ind_nd = loop->induction->nd;
- type = ind_nd->rtype;
-
- addvalue = IRO_NewLinear(IROLinearOperand);
- addvalue->index = ++IRO_NumLinear;
- addvalue->rtype = type;
- expr = IRO_NewENode(EINTCONST);
- expr->rtype = type;
- CInt64_SetLong(&expr->data.intval, value * loop->induction->addConst);
- addvalue->u.node = expr;
- IRO_AddToList(addvalue, &list);
-
- if (IS_LINEAR_MONADIC_2(ind_nd, EPREINC, EPOSTINC)) {
- ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EADDASS;
- ass->u.diadic.left = ind_nd;
- ass->u.diadic.right = addvalue;
- ass->rtype = type;
- IRO_AddToList(ass, &list);
- } else if (IS_LINEAR_MONADIC_2(ind_nd, EPREDEC, EPOSTDEC)) {
- ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = ESUBASS;
- ass->u.diadic.left = ind_nd;
- ass->u.diadic.right = addvalue;
- ass->rtype = type;
- IRO_AddToList(ass, &list);
- } else if (IS_LINEAR_DIADIC(ind_nd, EADDASS)) {
- ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list);
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->index = ++IRO_NumLinear;
- ass->nodetype = EADDASS;
- ass->u.diadic.left = ind_nd;
- ass->u.diadic.right = addvalue;
- ass->rtype = type;
- IRO_AddToList(ass, &list);
- }
-
- IRO_Paste(list.head, list.tail, before);
- return list.tail;
-}
-
-void GenInitialAssignment(IROLoop *loop, Object *var, IROList *list) {
- Type *type;
- IROLinear *nd;
-
- CError_ASSERT(3924, loop->nd14 && loop->nd14->type == IROLinearOp2Arg);
-
- type = loop->induction->nd->rtype;
-
- nd = IRO_NewLinear(IROLinearOp2Arg);
- nd->index = ++IRO_NumLinear;
- nd->nodetype = EASS;
- nd->u.diadic.left = IRO_TempReference(var, list);
- nd->u.diadic.right = IRO_DuplicateExpr(loop->nd14->u.diadic.right, list);
- nd->rtype = type;
- IRO_AddToList(nd, list);
-}
-
-void GenNewInduction(void) {
- CError_FATAL(3941);
-}
diff --git a/compiler_and_linker/unsorted/IroUtil.c b/compiler_and_linker/unsorted/IroUtil.c
deleted file mode 100644
index 4ade9b1..0000000
--- a/compiler_and_linker/unsorted/IroUtil.c
+++ /dev/null
@@ -1,1262 +0,0 @@
-#include "compiler/IroUtil.h"
-#include "compiler/IroCSE.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroLoop.h"
-#include "compiler/IroVars.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CCompiler.h"
-#include "compiler/CError.h"
-#include "compiler/CException.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/Exceptions.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-#include "cos.h"
-
-static UInt32 IRO_LastUserBreakTick;
-static IROLinear *ExprStart;
-static IROLinear *ExprEnd;
-static IRONode *IRO_Node;
-static SInt32 FuncLevel;
-Object *FunctionName;
-Boolean IRO_IsLeafFunction;
-Boolean IRO_FunctionHasReturn;
-Boolean DisableDueToAsm;
-Boolean LoopOptimizerRun;
-
-Object *IRO_IsVariable(IROLinear *linear) {
- if (linear->type == IROLinearOp1Arg &&
- linear->nodetype == EINDIRECT &&
- linear->u.monadic->type == IROLinearOperand &&
- linear->u.monadic->u.node->type == EOBJREF)
- return linear->u.monadic->u.node->data.objref;
-
- return NULL;
-}
-
-Boolean IRO_IsConstant(IROLinear *linear) {
- if (linear->type == IROLinearOperand && ENODE_IS3(linear->u.node, EINTCONST, EVECTOR128CONST, EFLOATCONST))
- return 1;
- return 0;
-}
-
-Boolean IRO_IsPow2(IROLinear *linear, SInt32 *powvalue) {
- UInt32 desired;
- UInt32 value;
- SInt32 i;
-
- *powvalue = -1;
- if (linear->type == IROLinearOperand && linear->u.node->type == EINTCONST) {
- if (CTool_EndianReadWord32(&linear->u.node->data.intval.hi))
- return 0;
-
- desired = CInt64_GetULong(&linear->u.node->data.intval);
- value = 1;
- for (i = 0; i < 31; i++) {
- if (value == desired) {
- *powvalue = i;
- return 1;
- }
- value += value;
- }
- }
-
- return 0;
-}
-
-Boolean IRO_IsIntConstant(IROLinear *linear) {
- if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EINTCONST))
- return 1;
- return 0;
-}
-
-Boolean IRO_IsFloatConstant(IROLinear *linear) {
- if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EFLOATCONST))
- return 1;
- return 0;
-}
-
-Boolean IRO_IsVector128Constant(IROLinear *linear) {
- if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EVECTOR128CONST))
- return 1;
- return 0;
-}
-
-Boolean IRO_IsAssignment(IROLinear *linear) {
- if (linear->type == IROLinearOp1Arg || linear->type == IROLinearOp2Arg) {
- if (IRO_IsAssignOp[linear->nodetype])
- return 1;
- }
- return 0;
-}
-
-static Boolean IRO_OperandsSame(ENode *a, ENode *b) {
- if (a->type == b->type) {
- switch (a->type) {
- case EINTCONST:
- return CInt64_Equal(a->data.intval, b->data.intval);
- case ESTRINGCONST:
- return 0;
- case EFLOATCONST:
- return a->data.floatval.value == b->data.floatval.value;
- case EVECTOR128CONST:
- return (a->data.vector128val.ul[0] == b->data.vector128val.ul[0]) &&
- (a->data.vector128val.ul[1] == b->data.vector128val.ul[1]) &&
- (a->data.vector128val.ul[2] == b->data.vector128val.ul[2]) &&
- (a->data.vector128val.ul[3] == b->data.vector128val.ul[3]);
- case EOBJREF:
- return a->data.objref == b->data.objref;
- }
- }
-
- return 0;
-}
-
-Boolean IRO_TypesEqual(Type *a, Type *b) {
- if (IS_TYPE_BITFIELD(a)) {
- if (IS_TYPE_BITFIELD(b)) {
- if (
- (TYPE_BITFIELD(a)->bitfieldtype == TYPE_BITFIELD(b)->bitfieldtype) &&
- (TYPE_BITFIELD(a)->offset == TYPE_BITFIELD(b)->offset) &&
- (TYPE_BITFIELD(a)->bitlength == TYPE_BITFIELD(b)->bitlength))
- return 1;
- }
- return 0;
- }
-
- if (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b))
- return 1;
-
- return is_typeequal(a, b) != 0;
-}
-
-Type *IRO_UnsignedType(Type *type) {
- if (IS_TYPE_ENUM(type) || IS_TYPE_POINTER_ONLY(type)) {
- if (type->size == stunsignedchar.size)
- return TYPE(&stunsignedchar);
- if (type->size == stunsignedint.size)
- return TYPE(&stunsignedint);
- if (type->size == stunsignedshort.size)
- return TYPE(&stunsignedshort);
- if (type->size == stunsignedlong.size)
- return TYPE(&stunsignedlong);
- if (type->size == stunsignedlonglong.size)
- return TYPE(&stunsignedlonglong);
- CError_FATAL(281);
- return NULL;
- }
-
- if (!IS_TYPE_INT(type)) {
- CError_FATAL(287);
- return NULL;
- }
-
- if (type == TYPE(&stbool) || type == TYPE(&stwchar))
- return type;
-
- if (type == TYPE(&stchar) || type == TYPE(&stsignedchar) || type == TYPE(&stunsignedchar))
- return TYPE(&stunsignedchar);
- if (type == TYPE(&stsignedshort) || type == TYPE(&stunsignedshort))
- return TYPE(&stunsignedshort);
- if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint))
- return TYPE(&stunsignedint);
- if (type == TYPE(&stsignedlong) || type == TYPE(&stunsignedlong))
- return TYPE(&stunsignedlong);
- if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
- return TYPE(&stunsignedlonglong);
-
- CError_FATAL(319);
- return NULL;
-}
-
-Type *IRO_SignedType(Type *type) {
- if (IS_TYPE_ENUM(type) || IS_TYPE_POINTER_ONLY(type)) {
- if (type->size == stsignedchar.size)
- return TYPE(&stsignedchar);
- if (type->size == stsignedint.size)
- return TYPE(&stsignedint);
- if (type->size == stsignedshort.size)
- return TYPE(&stsignedshort);
- if (type->size == stsignedlong.size)
- return TYPE(&stsignedlong);
- if (type->size == stsignedlonglong.size)
- return TYPE(&stsignedlonglong);
- CError_FATAL(357);
- return NULL;
- }
-
- if (!IS_TYPE_INT(type)) {
- CError_FATAL(363);
- return NULL;
- }
-
- if (type == TYPE(&stbool) && type->size == stsignedchar.size)
- return TYPE(&stsignedchar);
-
- if (type == TYPE(&stwchar) && type->size == stsignedshort.size)
- return TYPE(&stsignedshort);
-
- if (type == TYPE(&stchar) || type == TYPE(&stsignedchar) || type == TYPE(&stunsignedchar))
- return TYPE(&stsignedchar);
- if (type == TYPE(&stsignedshort) || type == TYPE(&stunsignedshort))
- return TYPE(&stsignedshort);
- if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint))
- return TYPE(&stsignedint);
- if (type == TYPE(&stsignedlong) || type == TYPE(&stunsignedlong))
- return TYPE(&stsignedlong);
- if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
- return TYPE(&stsignedlonglong);
-
- CError_FATAL(399);
- return NULL;
-}
-
-Boolean IRO_is_CPtypeequal(Type *a, Type *b) {
- if (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b))
- return 1;
-
- return is_typeequal(a, b) != 0;
-}
-
-Boolean IRO_ExprsSame(IROLinear *a, IROLinear *b) {
- if (a->type == b->type && IRO_TypesEqual(a->rtype, b->rtype)) {
- switch (a->type) {
- case IROLinearOperand:
- return IRO_OperandsSame(a->u.node, b->u.node);
- case IROLinearOp1Arg:
- if (a->nodetype == b->nodetype)
- return IRO_ExprsSame(a->u.monadic, b->u.monadic);
- return 0;
- case IROLinearOp2Arg:
- if (a->nodetype == b->nodetype)
- return IRO_ExprsSame(a->u.diadic.left, b->u.diadic.left) &&
- IRO_ExprsSame(a->u.diadic.right, b->u.diadic.right);
- return 0;
- case IROLinearOp3Arg:
- if (a->nodetype == b->nodetype)
- return IRO_ExprsSame(a->u.args3.a, b->u.args3.a) &&
- IRO_ExprsSame(a->u.args3.b, b->u.args3.b) &&
- IRO_ExprsSame(a->u.args3.c, b->u.args3.c);
- return 0;
- case IROLinearFunccall:
- return 0;
- default:
- return 0;
- }
- }
-
- return 0;
-}
-
-CLabel *IRO_NewLabel(void) {
- CLabel *label = newlabel();
- label->next = Labels;
- Labels = label;
- return label;
-}
-
-Boolean IRO_ExprsSameSemantically(IROLinear *a, IROLinear *b) {
- if (a->type == b->type && IRO_TypesEqual(a->rtype, b->rtype)) {
- Boolean flag = 0;
-
- switch (a->type) {
- case IROLinearOperand:
- return IRO_OperandsSame(a->u.node, b->u.node);
- case IROLinearOp1Arg:
- if (a->nodetype == b->nodetype)
- return IRO_ExprsSameSemantically(a->u.monadic, b->u.monadic);
- return 0;
- case IROLinearOp2Arg:
- if (a->nodetype == b->nodetype) {
- switch (a->nodetype) {
- case EMUL:
- case EADD:
- case EAND:
- case EXOR:
- case EOR:
- case ELAND:
- case ELOR:
- if (!IRO_HasSideEffect(a)) {
- flag = IRO_ExprsSameSemantically(a->u.diadic.left, b->u.diadic.right) &&
- IRO_ExprsSameSemantically(a->u.diadic.right, b->u.diadic.left);
- }
- }
-
- return flag || (IRO_ExprsSameSemantically(a->u.diadic.left, b->u.diadic.left) &&
- IRO_ExprsSameSemantically(a->u.diadic.right, b->u.diadic.right));
- }
- return 0;
- case IROLinearOp3Arg:
- if (a->nodetype == b->nodetype)
- return IRO_ExprsSameSemantically(a->u.args3.a, b->u.args3.a) &&
- IRO_ExprsSameSemantically(a->u.args3.b, b->u.args3.b) &&
- IRO_ExprsSameSemantically(a->u.args3.c, b->u.args3.c);
- return 0;
- case IROLinearFunccall:
- return 0;
- default:
- return 0;
- }
- }
-
- return 0;
-}
-
-IROLinear *IRO_FindPrecedAfter(IROLinear *a, IROLinear *iter) {
- IROLinear *prev = iter;
- while (iter && iter != a) {
- prev = iter;
- iter = iter->next;
- }
-
- if (iter)
- return prev;
- return iter;
-}
-
-IROLinear *IRO_FindPreced(IROLinear *a) {
- IROLinear *iter;
- IROLinear *prev;
-
- prev = iter = IRO_FirstLinear;
- while (iter && iter != a) {
- prev = iter;
- iter = iter->next;
- }
-
- if (iter)
- return prev;
- return iter;
-}
-
-IROLinear *IRO_FindFirst(IROLinear *linear) {
- short i;
-
- switch (linear->type) {
- case IROLinearOperand:
- return linear;
- case IROLinearOp1Arg:
- return IRO_FindFirst(linear->u.monadic);
- case IROLinearOp2Arg:
- if (linear->u.diadic.right->index < linear->u.diadic.left->index)
- return IRO_FindFirst(linear->u.diadic.right);
- else
- return IRO_FindFirst(linear->u.diadic.left);
- case IROLinearOp3Arg:
- if (linear->u.args3.a->index < linear->u.args3.b->index) {
- if (linear->u.args3.b->index < linear->u.args3.c->index)
- return IRO_FindFirst(linear->u.args3.a);
- else
- return IRO_FindFirst(linear->u.args3.c);
- } else {
- if (linear->u.args3.b->index < linear->u.args3.c->index)
- return IRO_FindFirst(linear->u.args3.b);
- else
- return IRO_FindFirst(linear->u.args3.c);
- }
- case IROLinearFunccall:
- i = linear->u.funccall.argCount - 1;
- return IRO_FindFirst(linear->u.funccall.args[i]);
- default:
- CError_FATAL(641);
- return NULL;
- }
-}
-
-void IRO_CutAndPasteAfter(IROLinear *a, IROLinear *b, IROLinear *c) {
- IROLinear *preced = IRO_FindPreced(a);
- preced->next = b->next;
- b->next = c->next;
- c->next = a;
-}
-
-Boolean IRO_IsConstantZero(IROLinear *linear) {
- return (IRO_IsIntConstant(linear) && CInt64_IsZero(&linear->u.node->data.intval)) ||
- (IRO_IsFloatConstant(linear) && CMach_FloatIsZero(linear->u.node->data.floatval));
-}
-
-Boolean IRO_IsConstantOne(IROLinear *linear) {
- return (IRO_IsIntConstant(linear) && CInt64_IsOne(&linear->u.node->data.intval)) ||
- (IRO_IsFloatConstant(linear) && CMach_FloatIsOne(linear->u.node->data.floatval));
-}
-
-Boolean IRO_IsConstantNegativeOne(IROLinear *linear) {
- CInt64 neg = CInt64_Neg(linear->u.node->data.intval);
- return (IRO_IsIntConstant(linear) && CInt64_IsOne(&neg)) ||
- (IRO_IsFloatConstant(linear) && CMach_FloatIsNegOne(linear->u.node->data.floatval));
-}
-
-static void ActNop(IROLinear *linear, Boolean isEntry) {
- if (!isEntry) {
- linear->type = IROLinearNop;
- linear->expr = NULL;
- }
-}
-
-void IRO_NopOut(IROLinear *linear) {
- IRO_WalkTree(linear, ActNop);
-}
-
-static Boolean NotNoppable(IROLinear *linear) {
- return (
- (linear->type == IROLinearFunccall) ||
- IRO_IsAssignment(linear) ||
- ((linear->type == IROLinearOperand) && ENODE_IS(linear->u.node, EINSTRUCTION)) ||
- (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) ||
- ((linear->type == IROLinearOperand) && ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref))
- );
-}
-
-static void ActNopNonSideEffects(IROLinear *linear, Boolean isEntry) {
- if (isEntry) {
- if (NotNoppable(linear)) {
- if (!FuncLevel)
- linear->flags &= ~IROLF_Reffed;
- FuncLevel++;
- }
- } else {
- if (NotNoppable(linear)) {
- FuncLevel--;
- } else if (!FuncLevel) {
- linear->type = IROLinearNop;
- }
- }
-}
-
-void IRO_NopNonSideEffects(IROLinear *linear, SInt32 level) {
- FuncLevel = level;
- IRO_WalkTree(linear, ActNopNonSideEffects);
-}
-
-void IRO_BuildList(IROLinear *linear, Boolean isEntry) {
- if (!isEntry) {
- linear->next = NULL;
- IRO_AddToList(linear, &IRO_InitLList);
- }
-}
-
-void IRO_WalkTree(IROLinear *linear, IROWalkTreeFunc func) {
- int i;
-
- func(linear, 1);
- switch (linear->type) {
- case IROLinearOperand:
- break;
- case IROLinearOp1Arg:
- IRO_WalkTree(linear->u.monadic, func);
- break;
- case IROLinearOp2Arg:
- IRO_WalkTree(linear->u.diadic.left, func);
- IRO_WalkTree(linear->u.diadic.right, func);
- break;
- case IROLinearOp3Arg:
- IRO_WalkTree(linear->u.args3.a, func);
- IRO_WalkTree(linear->u.args3.b, func);
- IRO_WalkTree(linear->u.args3.c, func);
- break;
- case IROLinearFunccall:
- IRO_WalkTree(linear->u.funccall.linear8, func);
- for (i = 0; i < linear->u.funccall.argCount; i++)
- IRO_WalkTree(linear->u.funccall.args[i], func);
- break;
- }
- func(linear, 0);
-}
-
-void IRO_WalkTreeToPropagateFlags(IROLinear *linear, IROWalkTreeFunc func) {
- int i;
-
- switch (linear->type) {
- case IROLinearOperand:
- break;
- case IROLinearOp1Arg:
- IRO_WalkTreeToPropagateFlags(linear->u.monadic, func);
- break;
- case IROLinearOp2Arg:
- IRO_WalkTreeToPropagateFlags(linear->u.diadic.left, func);
- IRO_WalkTreeToPropagateFlags(linear->u.diadic.right, func);
- break;
- case IROLinearOp3Arg:
- IRO_WalkTreeToPropagateFlags(linear->u.args3.a, func);
- IRO_WalkTreeToPropagateFlags(linear->u.args3.b, func);
- IRO_WalkTreeToPropagateFlags(linear->u.args3.c, func);
- break;
- case IROLinearFunccall:
- IRO_WalkTreeToPropagateFlags(linear->u.funccall.linear8, func);
- for (i = 0; i < linear->u.funccall.argCount; i++)
- IRO_WalkTreeToPropagateFlags(linear->u.funccall.args[i], func);
- break;
- }
- func(linear, 0);
-}
-
-void IRO_WalkInts(IROLinear *a, IROLinear *b, IROWalkTreeFunc func) {
- IROLinear *scan;
-
- for (scan = a; scan; scan = scan->next) {
- switch (scan->type) {
- case IROLinearBeginCatch:
- case IROLinearEndCatch:
- case IROLinearEndCatchDtor:
- IRO_WalkTree(scan->u.ctch.linear, func);
- break;
- case IROLinearOperand:
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- case IROLinearOp3Arg:
- case IROLinearFunccall:
- IRO_WalkTree(scan, func);
- break;
- case IROLinearIf:
- case IROLinearIfNot:
- IRO_WalkTree(scan->u.label.x4, func);
- break;
- case IROLinearReturn:
- if (scan->u.monadic)
- IRO_WalkTree(scan->u.monadic, func);
- break;
- case IROLinearSwitch:
- IRO_WalkTree(scan->u.swtch.x4, func);
- break;
- case IROLinearAsm:
- func(scan, 1);
- func(scan, 0);
- break;
- case IROLinearEnd:
- break;
- }
-
- if (scan == b)
- break;
- }
-}
-
-void IRO_Cut(IROLinear *a, IROLinear *b) {
- IROLinear *scan;
- IROLinear *prev;
- IRONode *node;
-
- scan = a;
- while (1) {
- scan->stmt = NULL;
- if (scan == b)
- break;
- scan = scan->next;
- }
-
- prev = NULL;
- for (scan = IRO_FirstLinear; scan && scan != a; scan = scan->next)
- prev = scan;
-
- CError_ASSERT(951, scan);
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first == a) {
- if (node->last == b) {
- node->first = node->last = NULL;
- break;
- } else {
- node->first = b->next;
- break;
- }
- } else if (node->last == b) {
- node->last = prev;
- break;
- }
- }
-
- if (prev)
- prev->next = b->next;
- else
- IRO_FirstLinear = b->next;
-}
-
-void IRO_Paste(IROLinear *a, IROLinear *b, IROLinear *c) {
- IROLinear *prev;
- IROLinear *scan;
- IRONode *node;
-
- CError_ASSERT(1002, c && c->type != IROLinearLabel);
-
- prev = NULL;
- for (scan = IRO_FirstLinear; scan && scan != c; scan = scan->next)
- prev = scan;
-
- CError_ASSERT(1016, scan);
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->first == c) {
- node->first = a;
- break;
- }
- }
-
- b->next = c;
- if (prev)
- prev->next = a;
- else
- IRO_FirstLinear = a;
-}
-
-void IRO_PasteAfter(IROLinear *a, IROLinear *b, IROLinear *c) {
- IRONode *node;
-
- switch (c->type) {
- case IROLinearGoto:
- case IROLinearIf:
- case IROLinearIfNot:
- case IROLinearSwitch:
- CError_FATAL(1060);
- }
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- if (node->last == c) {
- node->last = b;
- break;
- }
- }
-
- b->next = c->next;
- c->next = a;
-}
-
-static void FindStart(IROLinear *linear, Boolean isEntry) {
- IROLinear *scan;
- if (isEntry) {
- scan = linear;
- do {
- if (scan == ExprStart) {
- ExprStart = linear;
- return;
- }
- if (scan == ExprEnd)
- return;
- } while ((scan = scan->next));
- }
-}
-
-void IRO_ClipExpr(IROExpr *expr) {
- ExprStart = ExprEnd = expr->linear;
- IRO_WalkTree(expr->linear, FindStart);
- IRO_Cut(ExprStart, ExprEnd);
-}
-
-void IRO_ClipExprTree(IROLinear *linear) {
- ExprStart = ExprEnd = linear;
- IRO_WalkTree(linear, FindStart);
- IRO_Cut(ExprStart, ExprEnd);
-}
-
-static void SetNodeNumInExprList(IROLinear *linear, Boolean isEntry) {
- if (isEntry && linear->expr)
- linear->expr->node = IRO_Node;
-}
-
-void IRO_MoveExpression(IROExpr *expr, IROLinear *linear) {
- IRONode *node;
- IROLinear *scan;
-
- ExprStart = ExprEnd = expr->linear;
- IRO_WalkTree(expr->linear, FindStart);
-
- if (ExprStart != linear) {
- IRO_Cut(ExprStart, ExprEnd);
- IRO_Paste(ExprStart, ExprEnd, linear);
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- for (scan = node->first; scan; scan = scan->next) {
- if (scan == expr->linear) {
- expr->node = node;
- break;
- }
- if (scan == node->last)
- break;
- }
- }
-
- IRO_Node = expr->node;
- IRO_WalkTree(expr->linear, SetNodeNumInExprList);
- }
-}
-
-void IRO_InitList(IROList *list) {
- list->head = list->tail = NULL;
-}
-
-void IRO_AddToList(IROLinear *linear, IROList *list) {
- if (list->head)
- list->tail->next = linear;
- else
- list->head = linear;
-
- list->tail = linear;
- while (list->tail->next)
- list->tail = list->tail->next;
-}
-
-IROLinear *IRO_FindLabelNode(CLabel *label, IROLinear *linear) {
- IROLinear *scan;
-
- for (scan = linear; scan; scan = scan->next) {
- if (scan->type == IROLinearLabel && scan->u.label.label == label)
- break;
- }
-
- CError_ASSERT(1244, scan);
- return scan;
-}
-
-void IRO_DuplicateExprRange(IROLinear *start, IROLinear *end, IROList *list) {
- IROLinear *scan;
-
- for (scan = start; scan; scan = scan->next) {
- if (scan->type != IROLinearNop && !(scan->flags & IROLF_Reffed))
- IRO_DuplicateExpr(scan, list);
- if (scan == end)
- break;
- }
-}
-
-IROLinear *IRO_DuplicateExpr(IROLinear *linear, IROList *list) {
- IROLinear *copy;
- ENode *copynode;
- int i;
-
- copy = IRO_NewLinear(linear->type);
- *copy = *linear;
-
- copy->index = ++IRO_NumLinear;
- copy->next = NULL;
- copy->expr = NULL;
-
- switch (copy->type) {
- case IROLinearOperand:
- copynode = lalloc(sizeof(ENode));
- *copynode = *linear->u.node;
- copy->u.node = copynode;
- break;
- case IROLinearOp1Arg:
- copy->u.monadic = IRO_DuplicateExpr(copy->u.monadic, list);
- break;
- case IROLinearOp2Arg:
- if (linear->flags & IROLF_8000) {
- copy->u.diadic.right = IRO_DuplicateExpr(copy->u.diadic.right, list);
- copy->u.diadic.left = IRO_DuplicateExpr(copy->u.diadic.left, list);
- } else {
- copy->u.diadic.left = IRO_DuplicateExpr(copy->u.diadic.left, list);
- copy->u.diadic.right = IRO_DuplicateExpr(copy->u.diadic.right, list);
- }
- break;
- case IROLinearOp3Arg:
- copy->u.args3.a = IRO_DuplicateExpr(copy->u.args3.a, list);
- copy->u.args3.b = IRO_DuplicateExpr(copy->u.args3.b, list);
- copy->u.args3.c = IRO_DuplicateExpr(copy->u.args3.c, list);
- break;
- case IROLinearFunccall:
- copy->u.funccall.linear8 = IRO_DuplicateExpr(copy->u.funccall.linear8, list);
- copy->u.funccall.args = oalloc(sizeof(IROLinear *) * copy->u.funccall.argCount);
- for (i = 0; i < copy->u.funccall.argCount; i++) {
- copy->u.funccall.args[i] = IRO_DuplicateExpr(linear->u.funccall.args[i], list);
- }
- break;
- case IROLinearAsm:
- copy->u.asm_stmt = CodeGen_CopyAsmStat(linear->u.asm_stmt);
- break;
- }
-
- IRO_AddToList(copy, list);
- return copy;
-}
-
-IROLinear *IRO_TempReference(Object *obj, IROList *list) {
- IROLinear *op;
- IROLinear *ind;
-
- op = IRO_NewLinear(IROLinearOperand);
- op->u.node = create_objectrefnode(obj);
- op->rtype = op->u.node->data.objref->type;
- op->index = ++IRO_NumLinear;
- op->flags |= IROLF_Reffed | IROLF_Ind;
- IRO_AddToList(op, list);
-
- ind = IRO_NewLinear(IROLinearOp1Arg);
- ind->nodetype = EINDIRECT;
- ind->rtype = obj->type;
- ind->u.monadic = op;
- ind->index = ++IRO_NumLinear;
- ind->next = NULL;
- IRO_AddToList(ind, list);
-
- return ind;
-}
-
-CW_INLINE IROLinear *LocateFatherHelper(IROLinear *linear, Boolean a, IROLinear ***b) {
- IROLinear *scan;
- SInt32 index;
- int i;
-
- for (scan = linear->next, index = 0; index < (a ? 2 : 1); index++) {
- while (scan) {
- switch (scan->type) {
- case IROLinearIf:
- case IROLinearIfNot:
- if (scan->u.label.x4 == linear) {
- if (b)
- *b = &scan->u.label.x4;
- return scan;
- }
- break;
- case IROLinearReturn:
- if (scan->u.monadic == linear) {
- if (b)
- *b = &scan->u.monadic;
- return scan;
- }
- break;
- case IROLinearOp1Arg:
- if (scan->u.monadic == linear) {
- if (b)
- *b = &scan->u.monadic;
- return scan;
- }
- break;
- case IROLinearSwitch:
- if (scan->u.swtch.x4 == linear) {
- if (b)
- *b = &scan->u.swtch.x4;
- return scan;
- }
- break;
- case IROLinearOp2Arg:
- if (scan->u.diadic.left == linear) {
- if (b)
- *b = &scan->u.diadic.left;
- return scan;
- }
- if (scan->u.diadic.right == linear) {
- if (b)
- *b = &scan->u.diadic.right;
- return scan;
- }
- break;
- case IROLinearOp3Arg:
- if (scan->u.args3.a == linear) {
- if (b)
- *b = &scan->u.args3.a;
- return scan;
- }
- if (scan->u.args3.b == linear) {
- if (b)
- *b = &scan->u.args3.b;
- return scan;
- }
- if (scan->u.args3.c == linear) {
- if (b)
- *b = &scan->u.args3.c;
- return scan;
- }
- break;
- case IROLinearFunccall:
- if (scan->u.funccall.linear8 == linear) {
- if (b)
- *b = &scan->u.funccall.linear8;
- return scan;
- }
- for (i = 0; i < scan->u.funccall.argCount; i++) {
- if (scan->u.funccall.args[i] == linear) {
- if (b)
- *b = &scan->u.funccall.args[i];
- return scan;
- }
- }
- break;
- case IROLinearNop:
- case IROLinearOperand:
- case IROLinearGoto:
- case IROLinearLabel:
- case IROLinearEntry:
- case IROLinearExit:
- case IROLinearBeginCatch:
- case IROLinearEndCatch:
- case IROLinearEndCatchDtor:
- case IROLinearAsm:
- case IROLinearEnd:
- break;
- default:
- CError_FATAL(1536);
- }
- scan = scan->next;
- }
-
- scan = IRO_FirstLinear;
- }
-
- if (b)
- *b = NULL;
- return NULL;
-}
-
-IROLinear *IRO_LocateFather(IROLinear *linear) {
- return LocateFatherHelper(linear, 0, NULL);
-}
-
-IROLinear *IRO_LocateFather_Cut_And_Paste(IROLinear *a, IROLinear *b) {
- IROLinear **p;
- IROLinear *l = LocateFatherHelper(a, 0, &p);
- if (l) {
- CError_ASSERT(1568, p && *p);
- IRO_NopOut(a);
- *p = b;
- }
- return l;
-}
-
-IROLinear *IRO_LocateFather_Cut_And_Paste_Without_Nopping(IROLinear *a, IROLinear *b) {
- IROLinear **p;
- IROLinear *l = LocateFatherHelper(a, 0, &p);
- if (l) {
- CError_ASSERT(1585, p && *p);
- *p = b;
- }
- return l;
-}
-
-void IRO_ReplaceReference(IROLinear *a, Object *obj, IROLinear *b) {
- IROLinear **ptr;
- IROList list;
-
- if (LocateFatherHelper(a, 1, &ptr)) {
- CError_ASSERT(1605, ptr && *ptr);
- IRO_InitList(&list);
- *ptr = IRO_TempReference(obj, &list);
- IRO_PasteAfter(list.head, list.tail, b);
- if (a->flags & IROLF_LoopInvariant)
- list.tail->flags |= IROLF_LoopInvariant;
- } else {
- IRO_Dump("Oh, oh, did not find reference to replace\n");
- }
-}
-
-void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b) {
- IROLinear **ptr;
- IROList list;
-
- if (LocateFatherHelper(a, 1, &ptr)) {
- CError_ASSERT(1664, ptr && *ptr);
- *ptr = b;
- b->flags |= IROLF_Reffed;
- } else {
- IRO_Dump("Oh, oh, did not find reference to replace\n");
- }
-}
-
-VarRecord *IRO_GetTemp(IROExpr *expr) {
- expr->x8 = create_temp_object(expr->linear->rtype);
- return IRO_FindVar(expr->x8, 1, 1);
-}
-
-IROLinear *IRO_AssignToTemp(IROExpr *expr) {
- IROLinear *objref;
- IROLinear *ind;
- IROLinear *ass;
-
- objref = IRO_NewLinear(IROLinearOperand);
- objref->u.node = create_objectrefnode(expr->x8);
- objref->rtype = objref->u.node->data.objref->type;
- objref->index = ++IRO_NumLinear;
- objref->flags |= IROLF_Reffed | IROLF_Assigned | IROLF_Ind;
-
- ind = IRO_NewLinear(IROLinearOp1Arg);
- ind->nodetype = EINDIRECT;
- ind->rtype = expr->linear->rtype;
- ind->u.monadic = objref;
- ind->index = ++IRO_NumLinear;
- ind->flags |= IROLF_Reffed | IROLF_Assigned;
-
- ass = IRO_NewLinear(IROLinearOp2Arg);
- ass->nodetype = EASS;
- ass->u.diadic.left = ind;
- ass->u.diadic.right = expr->linear;
- ass->rtype = expr->linear->rtype;
- ass->index = ++IRO_NumLinear;
-
- objref->next = ind;
- ind->next = ass;
- IRO_PasteAfter(objref, ass, expr->linear);
- return ass;
-}
-
-IROLinear *IRO_FindStart(IROLinear *linear) {
- ExprStart = ExprEnd = linear;
- IRO_WalkTree(linear, FindStart);
- return ExprStart;
-}
-
-void IRO_DeleteCommaNode(IROLinear *linear, IROExpr *expr) {
- IROLinear *scan;
- for (scan = linear; scan; scan = scan->next) {
- if (scan->nodetype == ECOMMA) {
- if (scan != expr->linear) {
- IRO_NopOut(scan->u.diadic.left);
- IRO_LocateFather_Cut_And_Paste(scan, scan->u.diadic.right);
- } else {
- IRO_NopOut(scan->u.diadic.left);
- expr->linear = scan->u.diadic.right;
- }
- }
- }
-}
-
-void IRO_RemoveCommaNodeFromIR(void) {
- IRONode *node;
- IROLinear *linear;
-
- for (node = IRO_FirstNode; node; node = node->nextnode) {
- linear = node->first;
- do {
- if (!linear)
- break;
- if (linear->nodetype == ECOMMA) {
- linear->u.diadic.left->flags = linear->u.diadic.left->flags & ~IROLF_Reffed;
- IRO_LocateFather_Cut_And_Paste_Without_Nopping(linear, linear->u.diadic.right);
- linear->type = IROLinearNop;
- }
- linear = linear->next;
- } while (linear != node->last);
- }
-}
-
-IROAddrRecord *IRO_InitAddrRecordPointer(IROLinear *linear) {
- IROAddrRecord *rec = oalloc(sizeof(IROAddrRecord));
- rec->numObjRefs = 0;
- rec->objRefs = NULL;
- rec->numMisc = 0;
- rec->misc = NULL;
- rec->numInts = 0;
- rec->ints = NULL;
- rec->x16 = 0;
- rec->linear = linear;
- return rec;
-}
-
-IROLinear *IRO_HasSideEffect(IROLinear *linear) {
- IROLinear *tmp;
-
- if (!linear)
- return linear;
-
- if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS))
- return linear;
-
- switch (linear->type) {
- case IROLinearAsm:
- return linear;
- case IROLinearOperand:
- if (ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref))
- return linear;
- return NULL;
- case IROLinearOp1Arg:
- if (IRO_IsAssignOp[linear->nodetype])
- return linear;
- else
- return IRO_HasSideEffect(linear->u.monadic);
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype])
- return linear;
- else if ((tmp = IRO_HasSideEffect(linear->u.diadic.left)))
- return tmp;
- else
- return IRO_HasSideEffect(linear->u.diadic.right);
- case IROLinearOp3Arg:
- if ((tmp = IRO_HasSideEffect(linear->u.args3.a)))
- return tmp;
- else if ((tmp = IRO_HasSideEffect(linear->u.args3.b)))
- return tmp;
- else
- return IRO_HasSideEffect(linear->u.args3.c);
- case IROLinearFunccall:
- return linear;
- default:
- return linear;
- }
-}
-
-IROLinear *IRO_CheckSideEffect(IROLinear *linear) {
- IROLinear *result;
- IROLinear *tmp;
- IROLinear *tmp2;
- IROLinear *tmp3;
-
- if (!linear)
- return linear;
-
- if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) {
- linear->flags &= ~IROLF_Reffed;
- return linear;
- }
-
- result = NULL;
- switch (linear->type) {
- case IROLinearAsm:
- linear->flags &= ~IROLF_Reffed;
- return linear;
- case IROLinearOperand:
- if (ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref)) {
- linear->flags &= ~IROLF_Reffed;
- return linear;
- }
- break;
- case IROLinearOp1Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- linear->flags &= ~IROLF_Reffed;
- return linear;
- }
- if ((result = IRO_CheckSideEffect(linear->u.monadic))) {
- if (linear->nodetype == EINDIRECT && linear->u.monadic->type == IROLinearOperand) {
- linear->flags &= ~IROLF_Reffed;
- return linear;
- }
- }
- break;
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- linear->flags &= ~IROLF_Reffed;
- return linear;
- }
- tmp = IRO_CheckSideEffect(linear->u.diadic.left);
- tmp2 = IRO_CheckSideEffect(linear->u.diadic.right);
- if (tmp)
- result = tmp;
- else
- result = tmp2;
- break;
- case IROLinearOp3Arg:
- tmp = IRO_CheckSideEffect(linear->u.args3.a);
- tmp2 = IRO_CheckSideEffect(linear->u.args3.b);
- tmp3 = IRO_CheckSideEffect(linear->u.args3.c);
- result = tmp ? tmp : tmp2 ? tmp2 : tmp3;
- break;
- case IROLinearFunccall:
- linear->flags &= ~IROLF_Reffed;
- return linear;
- default:
- return linear;
- }
-
- linear->type = IROLinearNop;
- IRO_Dump("Nop out with side-effects checking at: %d\n", linear->index);
- return result;
-}
-
-void IRO_WalkExcActions(ExceptionAction *action, WalkObjFunc func) {
- while (action) {
- switch (action->type) {
- case EAT_DESTROYLOCAL:
- func(action->data.destroy_local.local);
- break;
- case EAT_DESTROYLOCALCOND:
- func(action->data.destroy_local_cond.local);
- func(action->data.destroy_local_cond.cond);
- break;
- case EAT_DESTROYLOCALOFFSET:
- func(action->data.destroy_local_offset.local);
- break;
- case EAT_DESTROYLOCALPOINTER:
- func(action->data.destroy_local_pointer.pointer);
- break;
- case EAT_DESTROYLOCALARRAY:
- func(action->data.destroy_local_array.localarray);
- break;
- case EAT_DESTROYPARTIALARRAY:
- func(action->data.destroy_partial_array.arraypointer);
- func(action->data.destroy_partial_array.arraycounter);
- func(action->data.destroy_partial_array.element_size);
- break;
- case EAT_DESTROYBASE:
- func(action->data.destroy_member.objectptr); // wrong union?
- break;
- case EAT_DESTROYMEMBER:
- func(action->data.destroy_member.objectptr);
- break;
- case EAT_DESTROYMEMBERCOND:
- func(action->data.destroy_member_cond.objectptr);
- func(action->data.destroy_member_cond.cond);
- break;
- case EAT_DESTROYMEMBERARRAY:
- func(action->data.destroy_member_array.objectptr);
- break;
- case EAT_DELETEPOINTER:
- func(action->data.delete_pointer.pointerobject);
- break;
- case EAT_DELETEPOINTERCOND:
- func(action->data.delete_pointer_cond.pointerobject);
- func(action->data.delete_pointer_cond.cond);
- break;
- }
- action = action->prev;
- }
-}
-
-Boolean IRO_FunctionCallMightThrowException(IROLinear *linear) {
- Object *obj;
- if (linear->type == IROLinearFunccall) {
- obj = NULL;
- if (linear->u.funccall.linear8->type == IROLinearOperand && ENODE_IS(linear->u.funccall.linear8->u.node, EOBJREF))
- obj = linear->u.funccall.linear8->u.node->data.objref;
- if (!obj || CExcept_CanThrowException(obj, obj->datatype == DVFUNC && !(linear->nodeflags & ENODE_FLAG_80)))
- return 1;
- }
- return 0;
-}
-
-IROLinear *IRO_NewIntConst(CInt64 val, Type *type) {
- ENode *node;
- IROLinear *linear;
-
- node = IRO_NewENode(EINTCONST);
- node->data.intval = val;
- node->rtype = type;
-
- linear = IRO_NewLinear(IROLinearOperand);
- linear->index = ++IRO_NumLinear;
- linear->rtype = type;
- linear->u.node = node;
- return linear;
-}
-
-IROLinear *IRO_NewFloatConst(const Float val, Type *type) {
- ENode *node;
- IROLinear *linear;
-
- node = IRO_NewENode(EFLOATCONST);
- node->data.floatval = val;
- node->rtype = type;
-
- linear = IRO_NewLinear(IROLinearOperand);
- linear->index = ++IRO_NumLinear;
- linear->rtype = type;
- linear->u.node = node;
- return linear;
-}
-
-Boolean IRO_IsAddressMultiply(IROLinear *linear) {
- return 0;
-}
-
-void IRO_SetupForUserBreakChecking(void) {
- IRO_LastUserBreakTick = 0;
-}
-
-void IRO_CheckForUserBreak(void) {
- if (IRO_LastUserBreakTick + 8 < COS_GetTicks()) {
- if (CWUserBreak(cparams.context))
- CError_UserBreak();
- IRO_LastUserBreakTick = COS_GetTicks();
- }
-}
diff --git a/compiler_and_linker/unsorted/IroVars.c b/compiler_and_linker/unsorted/IroVars.c
deleted file mode 100644
index 6bb3d02..0000000
--- a/compiler_and_linker/unsorted/IroVars.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-#include "compiler/IroVars.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroJump.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IROUseDef.h"
-#include "compiler/CClass.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CParser.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Exceptions.h"
-#include "compiler/objects.h"
-#include "compiler/InlineAsm.h"
-#include "compiler/InlineAsmPPC.h"
-#include "compiler/BitVector.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct IndirectRecordMatch {
- IROLinear *nd;
- struct IndirectRecordMatch *otherMatches;
-} IndirectRecordMatch;
-
-typedef struct IndirectRecord {
- IROLinear *linear;
- unsigned char flags;
- VarRecord *var;
- SInt32 addend;
- SInt32 size;
- int startbit;
- int endbit;
- Type *type;
- struct IndirectRecord *next;
- IndirectRecordMatch *matches;
- IROLinear *x26;
-} IndirectRecord;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static IndirectRecord *IRO_FirstIndirectRecord;
-static IndirectRecord *IRO_LastIndirectRecord;
-static IROLinear *TheBaseTerm;
-VarRecord *IRO_FirstVar;
-VarRecord *IRO_LastVar;
-SInt32 IRO_NumVars;
-Boolean IRO_IsBitField;
-SInt32 IRO_BaseTerms;
-SInt32 IRO_VarTerms;
-Boolean IRO_IsModifyOp[MAXEXPR];
-Boolean IRO_IsAssignOp[MAXEXPR];
-
-// forward decls
-static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag);
-static Boolean CheckAddressConsistency(IROLinear *nd, VarRecord *var, SInt32 addend, Type *type);
-static void DisableEntries(IndirectRecord *irec);
-static void DisableAddressedEntries(void);
-static UInt32 ObjectIsArg(Object *obj);
-
-void IRO_InitializeIRO_IsModifyOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- IRO_IsModifyOp[i] = 0;
-
- IRO_IsModifyOp[EPOSTINC] = 1;
- IRO_IsModifyOp[EPOSTDEC] = 1;
- IRO_IsModifyOp[EPREINC] = 1;
- IRO_IsModifyOp[EPREDEC] = 1;
- IRO_IsModifyOp[EINDIRECT] = 0;
- IRO_IsModifyOp[EMONMIN] = 0;
- IRO_IsModifyOp[EBINNOT] = 0;
- IRO_IsModifyOp[ELOGNOT] = 0;
- IRO_IsModifyOp[EFORCELOAD] = 0;
- IRO_IsModifyOp[EMUL] = 0;
- IRO_IsModifyOp[EMULV] = 0;
- IRO_IsModifyOp[EDIV] = 0;
- IRO_IsModifyOp[EMODULO] = 0;
- IRO_IsModifyOp[EADDV] = 0;
- IRO_IsModifyOp[ESUBV] = 0;
- IRO_IsModifyOp[EADD] = 0;
- IRO_IsModifyOp[ESUB] = 0;
- IRO_IsModifyOp[ESHL] = 0;
- IRO_IsModifyOp[ESHR] = 0;
- IRO_IsModifyOp[ELESS] = 0;
- IRO_IsModifyOp[EGREATER] = 0;
- IRO_IsModifyOp[ELESSEQU] = 0;
- IRO_IsModifyOp[EGREATEREQU] = 0;
- IRO_IsModifyOp[EEQU] = 0;
- IRO_IsModifyOp[ENOTEQU] = 0;
- IRO_IsModifyOp[EAND] = 0;
- IRO_IsModifyOp[EXOR] = 0;
- IRO_IsModifyOp[EOR] = 0;
- IRO_IsModifyOp[ELAND] = 0;
- IRO_IsModifyOp[ELOR] = 0;
- IRO_IsModifyOp[EASS] = 0;
- IRO_IsModifyOp[EMULASS] = 1;
- IRO_IsModifyOp[EDIVASS] = 1;
- IRO_IsModifyOp[EMODASS] = 1;
- IRO_IsModifyOp[EADDASS] = 1;
- IRO_IsModifyOp[ESUBASS] = 1;
- IRO_IsModifyOp[ESHLASS] = 1;
- IRO_IsModifyOp[ESHRASS] = 1;
- IRO_IsModifyOp[EANDASS] = 1;
- IRO_IsModifyOp[EXORASS] = 1;
- IRO_IsModifyOp[EORASS] = 1;
- IRO_IsModifyOp[ECOMMA] = 0;
- IRO_IsModifyOp[EPMODULO] = 1;
- IRO_IsModifyOp[EROTL] = 1;
- IRO_IsModifyOp[EROTR] = 1;
- IRO_IsModifyOp[EBCLR] = 1;
- IRO_IsModifyOp[EBTST] = 1;
- IRO_IsModifyOp[EBSET] = 1;
- IRO_IsModifyOp[ETYPCON] = 0;
- IRO_IsModifyOp[EBITFIELD] = 0;
- IRO_IsModifyOp[EINTCONST] = 0;
- IRO_IsModifyOp[EFLOATCONST] = 0;
- IRO_IsModifyOp[ESTRINGCONST] = 0;
- IRO_IsModifyOp[ECOND] = 0;
- IRO_IsModifyOp[EFUNCCALL] = 0;
- IRO_IsModifyOp[EFUNCCALLP] = 0;
- IRO_IsModifyOp[EOBJREF] = 0;
- IRO_IsModifyOp[EMFPOINTER] = 0;
- IRO_IsModifyOp[ENULLCHECK] = 0;
- IRO_IsModifyOp[EPRECOMP] = 0;
- IRO_IsModifyOp[ETEMP] = 0;
- IRO_IsModifyOp[EARGOBJ] = 0;
- IRO_IsModifyOp[ELOCOBJ] = 0;
- IRO_IsModifyOp[ELABEL] = 0;
- IRO_IsModifyOp[ESETCONST] = 0;
- IRO_IsModifyOp[ENEWEXCEPTION] = 0;
- IRO_IsModifyOp[ENEWEXCEPTIONARRAY] = 0;
- IRO_IsModifyOp[EOBJLIST] = 0;
- IRO_IsModifyOp[EMEMBER] = 0;
- IRO_IsModifyOp[ETEMPLDEP] = 0;
- IRO_IsModifyOp[EINSTRUCTION] = 0;
- IRO_IsModifyOp[EDEFINE] = 0;
- IRO_IsModifyOp[EREUSE] = 0;
- IRO_IsModifyOp[EASSBLK] = 0;
- IRO_IsModifyOp[EVECTOR128CONST] = 0;
- IRO_IsModifyOp[ECONDASS] = 1;
-}
-
-void IRO_InitializeIRO_IsAssignOpArray(void) {
- int i;
-
- for (i = 0; i < MAXEXPR; i++)
- IRO_IsAssignOp[i] = 0;
-
- IRO_IsAssignOp[EPOSTINC] = 1;
- IRO_IsAssignOp[EPOSTDEC] = 1;
- IRO_IsAssignOp[EPREINC] = 1;
- IRO_IsAssignOp[EPREDEC] = 1;
- IRO_IsAssignOp[EINDIRECT] = 0;
- IRO_IsAssignOp[EMONMIN] = 0;
- IRO_IsAssignOp[EBINNOT] = 0;
- IRO_IsAssignOp[ELOGNOT] = 0;
- IRO_IsAssignOp[EFORCELOAD] = 0;
- IRO_IsAssignOp[EMUL] = 0;
- IRO_IsAssignOp[EMULV] = 0;
- IRO_IsAssignOp[EDIV] = 0;
- IRO_IsAssignOp[EMODULO] = 0;
- IRO_IsAssignOp[EADDV] = 0;
- IRO_IsAssignOp[ESUBV] = 0;
- IRO_IsAssignOp[EADD] = 0;
- IRO_IsAssignOp[ESUB] = 0;
- IRO_IsAssignOp[ESHL] = 0;
- IRO_IsAssignOp[ESHR] = 0;
- IRO_IsAssignOp[ELESS] = 0;
- IRO_IsAssignOp[EGREATER] = 0;
- IRO_IsAssignOp[ELESSEQU] = 0;
- IRO_IsAssignOp[EGREATEREQU] = 0;
- IRO_IsAssignOp[EEQU] = 0;
- IRO_IsAssignOp[ENOTEQU] = 0;
- IRO_IsAssignOp[EAND] = 0;
- IRO_IsAssignOp[EXOR] = 0;
- IRO_IsAssignOp[EOR] = 0;
- IRO_IsAssignOp[ELAND] = 0;
- IRO_IsAssignOp[ELOR] = 0;
- IRO_IsAssignOp[EASS] = 1;
- IRO_IsAssignOp[EMULASS] = 1;
- IRO_IsAssignOp[EDIVASS] = 1;
- IRO_IsAssignOp[EMODASS] = 1;
- IRO_IsAssignOp[EADDASS] = 1;
- IRO_IsAssignOp[ESUBASS] = 1;
- IRO_IsAssignOp[ESHLASS] = 1;
- IRO_IsAssignOp[ESHRASS] = 1;
- IRO_IsAssignOp[EANDASS] = 1;
- IRO_IsAssignOp[EXORASS] = 1;
- IRO_IsAssignOp[EORASS] = 1;
- IRO_IsAssignOp[ECOMMA] = 0;
- IRO_IsAssignOp[EPMODULO] = 1;
- IRO_IsAssignOp[EROTL] = 1;
- IRO_IsAssignOp[EROTR] = 1;
- IRO_IsAssignOp[EBCLR] = 1;
- IRO_IsAssignOp[EBTST] = 1;
- IRO_IsAssignOp[EBSET] = 1;
- IRO_IsAssignOp[ETYPCON] = 0;
- IRO_IsAssignOp[EBITFIELD] = 0;
- IRO_IsAssignOp[EINTCONST] = 0;
- IRO_IsAssignOp[EFLOATCONST] = 0;
- IRO_IsAssignOp[ESTRINGCONST] = 0;
- IRO_IsAssignOp[ECOND] = 0;
- IRO_IsAssignOp[EFUNCCALL] = 0;
- IRO_IsAssignOp[EFUNCCALLP] = 0;
- IRO_IsAssignOp[EOBJREF] = 0;
- IRO_IsAssignOp[EMFPOINTER] = 0;
- IRO_IsAssignOp[ENULLCHECK] = 0;
- IRO_IsAssignOp[EPRECOMP] = 0;
- IRO_IsAssignOp[ETEMP] = 0;
- IRO_IsAssignOp[EARGOBJ] = 0;
- IRO_IsAssignOp[ELOCOBJ] = 0;
- IRO_IsAssignOp[ELABEL] = 0;
- IRO_IsAssignOp[ESETCONST] = 0;
- IRO_IsAssignOp[ENEWEXCEPTION] = 0;
- IRO_IsAssignOp[ENEWEXCEPTIONARRAY] = 0;
- IRO_IsAssignOp[EOBJLIST] = 0;
- IRO_IsAssignOp[EMEMBER] = 0;
- IRO_IsAssignOp[ETEMPLDEP] = 0;
- IRO_IsAssignOp[EINSTRUCTION] = 0;
- IRO_IsAssignOp[EDEFINE] = 0;
- IRO_IsAssignOp[EREUSE] = 0;
- IRO_IsAssignOp[EASSBLK] = 0;
- IRO_IsAssignOp[EVECTOR128CONST] = 0;
- IRO_IsAssignOp[ECONDASS] = 1;
-}
-
-VarRecord *IRO_FindVar(Object *object, Boolean flag1, Boolean flag2) {
- VarRecord *var;
- VarInfo *vi;
-
- var = object->varptr;
- if (!var && flag1) {
- vi = NULL;
- if (object->datatype == DLOCAL)
- vi = object->u.var.info;
- if (vi)
- vi->usage = 0;
- var = oalloc(sizeof(VarRecord));
- var->object = object;
- var->index = ++IRO_NumVars;
- var->x6 = 0;
- var->xA = 0;
- var->next = NULL;
- var->defs = NULL;
- var->uses = NULL;
- var->x1A = NULL;
- var->x1E = NULL;
- var->xB = 0;
- if (IRO_FirstVar)
- IRO_LastVar->next = var;
- else
- IRO_FirstVar = var;
- IRO_LastVar = var;
- object->varptr = var;
- }
-
- if (var && !flag2) {
- var->xB = 1;
- if (object->datatype == DLOCAL && object->u.var.info && object->u.var.info->noregister == 0)
- object->u.var.info->noregister = 2;
- }
-
- return var;
-}
-
-static void ResetVars(void) {
- VarRecord *var;
-
- for (var = IRO_FirstVar; var; var = var->next) {
- var->xB = 0;
- if (var->object && var->object->datatype == DLOCAL && var->object->u.var.info) {
- if (var->object->u.var.info->noregister == 2)
- var->object->u.var.info->noregister = 0;
- }
- }
-}
-
-static void IRO_HandleExceptionActions(IROLinear *linear) {
- ExceptionAction *action;
-
- for (action = linear->stmt->dobjstack; action; action = action->prev) {
- switch (action->type) {
- case EAT_DESTROYLOCAL:
- IRO_FindVar(action->data.destroy_local.local, 1, 0);
- break;
- case EAT_DESTROYLOCALCOND:
- IRO_FindVar(action->data.destroy_local_cond.local, 1, 0);
- break;
- case EAT_DESTROYLOCALOFFSET:
- IRO_FindVar(action->data.destroy_local_offset.local, 1, 0);
- break;
- case EAT_DESTROYLOCALARRAY:
- IRO_FindVar(action->data.destroy_local_array.localarray, 1, 0);
- break;
- case EAT_DESTROYMEMBER:
- case EAT_DESTROYBASE:
- IRO_FindVar(action->data.destroy_member.objectptr, 1, 0);
- break;
- case EAT_DESTROYMEMBERCOND:
- IRO_FindVar(action->data.destroy_member_cond.objectptr, 1, 0);
- break;
- case EAT_DESTROYMEMBERARRAY:
- IRO_FindVar(action->data.destroy_member_array.objectptr, 1, 0);
- break;
- case EAT_CATCHBLOCK:
- if (action->data.catch_block.catch_object)
- IRO_FindVar(action->data.catch_block.catch_object, 1, 0);
- IRO_FindVar(action->data.catch_block.catch_info_object, 1, 0);
- break;
- case EAT_ACTIVECATCHBLOCK:
- IRO_FindVar(action->data.active_catch_block.catch_info_object, 1, 0);
- break;
- }
- }
-}
-
-void IRO_FindAllVars(void) {
- IROLinear *linear;
- VarRecord *var;
-
- linear = IRO_FirstLinear;
- IRO_NumVars = 0;
- IRO_FirstVar = IRO_LastVar = NULL;
-
- while (linear) {
- if (IS_LINEAR_ENODE(linear, EOBJREF)) {
- if (Inline_IsObjectData(linear->u.node->data.objref) || linear->u.node->data.objref->datatype == DLOCAL)
- IRO_FindVar(linear->u.node->data.objref, 1, (linear->flags & IROLF_Ind) != 0);
- else
- linear->u.node->data.objref->varptr = NULL;
- } else if (linear->type == IROLinearFunccall) {
- if (linear->stmt && IRO_FunctionCallMightThrowException(linear))
- IRO_HandleExceptionActions(linear);
- } else if (linear->type == IROLinearAsm) {
- IAEffects effects;
- int i;
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++)
- IRO_FindVar(effects.operands[i].object, 1, effects.operands[i].type != IAEffect_3);
- }
- linear = linear->next;
- }
-
- var = IRO_FirstVar;
- Bv_AllocVector(&IRO_FuncKills, IRO_NumVars + 1);
- Bv_SetBit(0, IRO_FuncKills);
- while (var) {
- if (Inline_IsObjectData(var->object) || var->xB)
- Bv_SetBit(var->index, IRO_FuncKills);
- var = var->next;
- }
-
- IRO_CheckForUserBreak();
-}
-
-void IRO_ZapVarPtrs(void) {
- VarRecord *var;
-
- for (var = IRO_FirstVar; var; var = var->next)
- var->object->varptr = NULL;
-}
-
-void IRO_UpdateVars(void) {
- IROLinear *linear;
- VarRecord *var;
-
- ResetVars();
-
- for (linear = IRO_FirstLinear; linear; linear = linear->next) {
- if (IS_LINEAR_ENODE(linear, EOBJREF)) {
- if (Inline_IsObjectData(linear->u.node->data.objref) || linear->u.node->data.objref->datatype == DLOCAL)
- IRO_FindVar(linear->u.node->data.objref, 0, (linear->flags & IROLF_Ind) || !(linear->flags & IROLF_Reffed));
- } else if (linear->type == IROLinearFunccall) {
- if (linear->stmt && IRO_FunctionCallMightThrowException(linear))
- IRO_HandleExceptionActions(linear);
- } else if (linear->type == IROLinearAsm) {
- IAEffects effects;
- int i;
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++)
- IRO_FindVar(effects.operands[i].object, 0, effects.operands[i].type != IAEffect_3);
- }
- }
-
- var = IRO_FirstVar;
- Bv_AllocVector(&IRO_FuncKills, IRO_NumVars + 1);
- Bv_SetBit(0, IRO_FuncKills);
- while (var) {
- if (Inline_IsObjectData(var->object) || var->xB)
- Bv_SetBit(var->index, IRO_FuncKills);
- var = var->next;
- }
-}
-
-void IRO_AddElmToList(IROLinear *linear, IROElmList **list) {
- IROElmList *l = oalloc(sizeof(IROElmList));
- l->element = linear;
- l->next = NULL;
- if (!*list) {
- *list = l;
- } else {
- l->next = *list;
- *list = l;
- }
-}
-
-void IRO_DecomposeAddressExpression(IROLinear *linear, IROAddrRecord *rec) {
- if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD)) {
- IRO_DecomposeAddressExpression(linear->u.diadic.left, rec);
- } else if (IS_LINEAR_ENODE(linear->u.diadic.left, EINTCONST)) {
- rec->numInts++;
- IRO_AddElmToList(linear->u.diadic.left, &rec->ints);
- } else if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF)) {
- rec->numObjRefs++;
- IRO_AddElmToList(linear->u.diadic.left, &rec->objRefs);
- } else {
- rec->numMisc++;
- IRO_AddElmToList(linear->u.diadic.left, &rec->misc);
- }
-
- if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD)) {
- IRO_DecomposeAddressExpression(linear->u.diadic.right, rec);
- } else if (IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) {
- rec->numInts++;
- IRO_AddElmToList(linear->u.diadic.right, &rec->ints);
- } else if (IS_LINEAR_ENODE(linear->u.diadic.right, EOBJREF)) {
- rec->numObjRefs++;
- IRO_AddElmToList(linear->u.diadic.right, &rec->objRefs);
- } else {
- rec->numMisc++;
- IRO_AddElmToList(linear->u.diadic.right, &rec->misc);
- }
-}
-
-void IRO_DecomposeAddressExpression_Cheap(IROLinear *linear) {
- if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD)) {
- IRO_DecomposeAddressExpression_Cheap(linear->u.diadic.left);
- } else if (!IS_LINEAR_ENODE(linear->u.diadic.left, EINTCONST)) {
- if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF)) {
- IRO_BaseTerms++;
- TheBaseTerm = linear->u.diadic.left;
- } else {
- IRO_VarTerms++;
- }
- }
-
- if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD)) {
- IRO_DecomposeAddressExpression_Cheap(linear->u.diadic.right);
- } else if (!IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) {
- if (IS_LINEAR_ENODE(linear->u.diadic.right, EOBJREF)) {
- IRO_BaseTerms++;
- TheBaseTerm = linear->u.diadic.right;
- } else {
- IRO_VarTerms++;
- }
- }
-}
-
-VarRecord *IRO_FindAssigned(IROLinear *linear) {
- VarRecord *rec;
-
- IRO_IsBitField = 0;
- if (linear->type == IROLinearOp2Arg)
- linear = linear->u.diadic.left;
- else if (linear->type == IROLinearOp1Arg)
- linear = linear->u.monadic;
- else
- CError_FATAL(818);
-
- if (IS_LINEAR_MONADIC(linear, EINDIRECT))
- linear = linear->u.monadic;
-
- if (IS_LINEAR_MONADIC(linear, EBITFIELD)) {
- IRO_IsBitField = 1;
- linear = linear->u.monadic;
- }
-
- if (IS_LINEAR_DIADIC(linear, EADD)) {
- if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF) && IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) {
- linear = linear->u.diadic.left;
- } else {
- IRO_BaseTerms = 0;
- IRO_DecomposeAddressExpression_Cheap(linear);
- if (IRO_BaseTerms == 1)
- linear = TheBaseTerm;
- }
- }
-
- if (!IS_LINEAR_ENODE(linear, EOBJREF))
- return NULL;
-
- if ((rec = IRO_FindVar(linear->u.node->data.objref, 0, 1)))
- return rec;
- else
- return NULL;
-}
-
-static void GetKillsByIndirectAssignment(IROLinear *linear) {
- IROListNode *resultList;
- IROLinear *nd;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *inner;
- Boolean result;
- Boolean foundLinear;
-
- result = 0;
-
- if (linear->type == IROLinearOp2Arg)
- linear = linear->u.diadic.left;
- else
- linear = linear->u.monadic;
-
- if (
- linear &&
- linear->type == IROLinearOp1Arg &&
- linear->nodetype == EINDIRECT &&
- (inner = linear->u.monadic) &&
- copts.opt_pointer_analysis &&
- inner->pointsToFunction &&
- FunctionName
- )
- {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList);
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundLinear = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundLinear = 1;
- break;
- }
- }
- if (!foundLinear) {
- result = 1;
- break;
- }
- }
-
- if (!result) {
- while (list) {
- for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- Object *obj;
- VarRecord *var;
- int index;
-
- obj = nd->u.node->data.objref;
- CError_ASSERT(952, obj != NULL);
-
- var = IRO_FindVar(obj, 1, 1);
- CError_ASSERT(954, var != NULL);
-
- index = var->index;
- CError_ASSERT(956, index != 0);
-
- Bv_SetBit(index, IRO_VarKills);
- }
- }
-
- list = list->nextList;
- }
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result)
- Bv_Or(IRO_FuncKills, IRO_VarKills);
-}
-
-static void GetKillsByFunctionCall(IROLinear *linear) {
- IROListNode *resultList;
- IROLinear *nd;
- IROListNode *list;
- IROListNode *scan;
- IROLinear *inner;
- Boolean result;
- Boolean foundLinear;
- Object *obj;
- ObjectList *killList;
- ObjectList *olist;
-
- result = 0;
-
- if (
- (inner = linear->u.funccall.linear8) &&
- copts.opt_pointer_analysis &&
- inner->pointsToFunction &&
- FunctionName
- )
- {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList);
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundLinear = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundLinear = 1;
- obj = nd->u.node->data.objref;
- CError_ASSERT(1028, obj != NULL);
-
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, linear, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- if (!olist->object) {
- result = 1;
- break;
- }
- }
-
- while (killList) {
- ObjectList *next = killList->next;
- IRO_free(killList);
- killList = next;
- }
-
- if (result)
- break;
- }
- }
-
- if (!foundLinear)
- result = 1;
- if (result)
- break;
- }
-
- if (!result) {
- for (scan = resultList; scan; scan = scan->nextList) {
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- obj = nd->u.node->data.objref;
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, linear, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- VarRecord *var;
- int index;
-
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(1079, var != NULL);
-
- index = var->index;
- CError_ASSERT(1081, index != 0);
-
- Bv_SetBit(index, IRO_VarKills);
- }
-
- while (killList) {
- ObjectList *next = killList->next;
- IRO_free(killList);
- killList = next;
- }
- }
- }
- }
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- if (result)
- Bv_Or(IRO_FuncKills, IRO_VarKills);
-}
-
-void IRO_GetKills(IROLinear *linear) {
- VarRecord *var;
-
- switch (linear->type) {
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- if (IRO_IsAssignOp[linear->nodetype]) {
- IROLinear *assigned;
- int index;
-
- var = IRO_FindAssigned(linear);
- index = 0;
- if (var) index = var->index;
- Bv_SetBit(index, IRO_VarKills);
-
- if (!index)
- GetKillsByIndirectAssignment(linear);
- }
- break;
- case IROLinearFunccall:
- GetKillsByFunctionCall(linear);
- break;
- case IROLinearAsm: {
- IAEffects effects;
- int i;
-
- CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++) {
- switch (effects.operands[i].type) {
- case IAEffect_1:
- case IAEffect_2:
- case IAEffect_4:
- if ((var = IRO_FindVar(effects.operands[i].object, 0, 1)))
- Bv_SetBit(var->index, IRO_VarKills);
- break;
- }
- }
-
- if (effects.x1 || effects.x4)
- Bv_Or(IRO_FuncKills, IRO_VarKills);
- break;
- }
- }
-}
-
-void IRO_CheckInit(void) {
- IRONode *fnode;
- IROLinear *nd;
- VarRecord *var;
- ObjectList *olist;
- int flag;
- int i;
- BitVector *bv;
-
- IRO_MakeReachable(IRO_FirstNode);
- fnode = IRO_FirstNode;
- Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1);
-
- while (fnode) {
- Bv_AllocVector(&fnode->x16, IRO_NumVars + 1);
- Bv_AllocVector(&fnode->x1E, IRO_NumVars + 1);
-
- for (nd = fnode->first; nd; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- if (nd->flags & IROLF_Ind) {
- if (!(nd->flags & IROLF_Assigned) || (nd->flags & IROLF_Used)) {
- if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 1))) {
- if (!Bv_IsBitSet(var->index, fnode->x1E))
- Bv_SetBit(var->index, fnode->x16);
- }
- }
- } else {
- if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 0))) {
- Bv_SetBit(var->index, fnode->x1E);
- }
- }
- } else if (nd->type == IROLinearOp2Arg && nd->nodetype == EASS) {
- if ((var = IRO_FindAssigned(nd)))
- Bv_SetBit(var->index, fnode->x1E);
- } else if (nd->type == IROLinearAsm) {
- IAEffects effects;
-
- CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++) {
- var = IRO_FindVar(effects.operands[i].object, 0, 1);
- switch (effects.operands[i].type) {
- case IAEffect_1:
- case IAEffect_2:
- case IAEffect_4:
- Bv_SetBit(var->index, fnode->x1E);
- break;
- }
- }
- }
-
- if (nd == fnode->last)
- break;
- }
-
- fnode = fnode->nextnode;
- }
-
- Bv_AllocVector(&bv, IRO_NumVars + 1);
-
- do {
- flag = 0;
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- Bv_Copy(fnode->x1E, bv);
- for (i = 0; i < fnode->numpred; i++)
- Bv_Or(IRO_NodeTable[fnode->pred[i]]->x1E, bv);
- if (!Bv_Compare(bv, fnode->x1E)) {
- Bv_Copy(bv, fnode->x1E);
- flag = 1;
- }
- }
- } while (flag);
-
- Bv_Clear(IRO_VarKills);
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- if (fnode->x36) {
- Bv_Copy(fnode->x16, bv);
- for (i = 0; i < fnode->numpred; i++)
- Bv_Minus(IRO_NodeTable[fnode->pred[i]]->x1E, bv);
- Bv_Or(bv, IRO_VarKills);
- }
- }
-
- for (olist = locals; olist; olist = olist->next) {
- if ((var = IRO_FindVar(olist->object, 0, 1)) && Bv_IsBitSet(var->index, IRO_VarKills)) {
- VarInfo *vi = olist->object->u.var.info;
- if (!IsTempName(olist->object->name) && !is_volatile_object(olist->object)) {
- if (!IS_TYPE_CLASS(olist->object->type) || !CClass_IsEmpty(TYPE_CLASS(olist->object->type))) {
- CError_SetErrorToken(&vi->deftoken);
- CError_Warning(CErrorStr185, olist->object->name->name);
- }
- }
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static void RewriteIndDec(void) {
- IROLinear *add;
- IROLinear *indirect;
- IROLinear *Int;
- IROLinear *nd;
- CInt64 value;
- IROList list;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- if (
- nd->type == IROLinearOp1Arg &&
- (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC) &&
- !(nd->flags & IROLF_Reffed)
- ) {
- indirect = nd->u.monadic;
- if (
- indirect->type == IROLinearOp1Arg &&
- indirect->nodetype == EINDIRECT &&
- indirect->u.monadic->type == IROLinearOp1Arg &&
- indirect->u.monadic->nodetype == EBITFIELD
- ) {
- value = IRO_GetSelfAssignmentVal(nd);
- IRO_InitList(&list);
-
- nd->type = IROLinearOp2Arg;
- nd->nodetype = EASS;
- nd->u.diadic.left = indirect;
- IRO_DuplicateExpr(indirect, &list);
-
- Int = IRO_NewIntConst(value, indirect->rtype);
- Int->flags |= IROLF_Used | IROLF_Reffed;
-
- add = IRO_NewLinear(IROLinearOp2Arg);
- add->nodetype = EADD;
- add->u.diadic.left = list.tail;
- add->u.diadic.left->flags = 0;
- add->u.diadic.left->flags |= IROLF_Used | IROLF_Reffed;
- add->u.diadic.right = Int;
- add->rtype = indirect->rtype;
- add->flags = 0;
- add->flags |= IROLF_Used | IROLF_Reffed;
-
- nd->u.diadic.right = add;
-
- IRO_AddToList(Int, &list);
- IRO_AddToList(add, &list);
- IRO_PasteAfter(list.head, list.tail, indirect);
- }
- }
- }
-}
-
-void IRO_RewriteBitFieldTemps(void) {
- IROLinear *nd;
- IROLinear *expr2;
- Object *obj;
- VarRecord *var;
- IROList list;
-
- for (nd = IRO_FirstLinear; nd; nd = nd->next) {
- if ((obj = IRO_IsVariable(nd)) && (nd->flags & IROLF_BitfieldIndirect)) {
- var = IRO_FindVar(obj, 0, 1);
- CError_ASSERT(1526, var != NULL);
-
- expr2 = var->x1E;
- CError_ASSERT(1532, expr2 != NULL);
-
- IRO_InitList(&list);
- IRO_DuplicateExpr(expr2, &list);
- IRO_NopOut(nd->u.monadic);
- nd->u.monadic = list.tail;
- IRO_Paste(list.head, list.tail, nd);
- }
- }
-}
-
-static Boolean FunctionCallMightUseOrKillAnyAddressedVar(IROLinear *funccall) {
- IROLinear *funcnd;
- IROLinear *nd;
- IROListNode *scan;
- IROListNode *resultList;
- ObjectList *olist;
- ObjectList *killList;
- VarRecord *var;
- Boolean result;
- Boolean foundObjRef;
- Object *obj;
-
- result = 0;
-
- funcnd = funccall->u.funccall.linear8;
- if (funcnd && copts.opt_pointer_analysis && funcnd->pointsToFunction && FunctionName) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, funcnd, &resultList);
-
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = nd->u.node->data.objref;
- CError_ASSERT(1592, obj != NULL);
-
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, funccall, &killList);
- for (olist = killList; olist; olist = olist->next) {
- if (!olist->object) {
- result = 1;
- } else {
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(1604, var != NULL);
- if (var->xB)
- result = 1;
- }
-
- if (result)
- break;
- }
-
- while (killList) {
- ObjectList *next = killList->next;
- IRO_free(killList);
- killList = next;
- }
-
- if (!result) {
- killList = NULL;
- PointerAnalysis_GetFunctionDependencies(obj, funccall, &killList);
- for (olist = killList; olist; olist = olist->next) {
- if (!olist->object) {
- result = 1;
- } else {
- var = IRO_FindVar(olist->object, 1, 1);
- CError_ASSERT(1632, var != NULL);
- if (var->xB)
- result = 1;
- }
-
- if (result)
- break;
- }
-
- while (killList) {
- ObjectList *next = killList->next;
- IRO_free(killList);
- killList = next;
- }
- }
-
- if (result)
- break;
- }
- }
-
- if (!foundObjRef)
- result = 1;
- if (result)
- break;
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- return result;
-}
-
-static Boolean IndirectMightUseOrKillAnyAddressedVar(IROLinear *indirect) {
- Boolean result;
- IROLinear *inner;
- IROLinear *nd;
- IROListNode *scan;
- IROListNode *resultList;
- Boolean foundObjRef;
- Object *obj;
- VarRecord *var;
-
- result = 0;
-
- if (
- indirect &&
- indirect->type == IROLinearOp1Arg &&
- indirect->nodetype == EINDIRECT &&
- (inner = indirect->u.monadic) &&
- copts.opt_pointer_analysis &&
- inner->pointsToFunction &&
- FunctionName
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList);
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- result = 1;
- break;
- }
-
- foundObjRef = 0;
- for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) {
- if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = nd->u.node->data.objref;
- CError_ASSERT(1723, obj != NULL);
- var = IRO_FindVar(obj, 1, 1);
- CError_ASSERT(1725, var != NULL);
-
- if (var->xB)
- result = 1;
- }
- }
-
- if (!foundObjRef)
- result = 1;
- if (result)
- break;
- }
-
- while (resultList) {
- IROListNode *next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- result = 1;
- }
- } else {
- result = 1;
- }
-
- return result;
-}
-
-void IRO_ScalarizeClassDataMembers(void) {
- IROLinear *nd;
- VarRecord *var;
- Boolean flag;
- Object *obj;
- IndirectRecord *irec;
- IndirectRecordMatch *match;
- IROLinear *tmp;
-
- nd = IRO_FirstLinear;
- IRO_FirstIndirectRecord = NULL;
- IRO_LastIndirectRecord = NULL;
- RewriteIndDec();
- IRO_DumpAfterPhase("RewriteIndDec", 0);
- flag = 0;
-
- while (nd) {
- if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT) {
- CheckAddress(nd, &flag);
- }
- if (nd->type == IROLinearAsm) {
- IAEffects effects;
- SInt32 i;
- CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects);
- for (i = 0; i < effects.numoperands; i++) {
- if ((var = IRO_FindVar(effects.operands[i].object, 0, 1)))
- CheckAddressConsistency(nd, var, -1, &stvoid);
- else
- CError_FATAL(1823);
- }
- }
- if (nd->type == IROLinearFunccall && !flag)
- flag = FunctionCallMightUseOrKillAnyAddressedVar(nd);
-
- nd = nd->next;
- }
-
- if (flag)
- DisableAddressedEntries();
-
- for (irec = IRO_FirstIndirectRecord; irec; irec = irec->next) {
- if (!(irec->flags & 1)) {
- IROList list1;
- IROList list2;
-
- obj = create_temp_object(irec->type);
- var = IRO_FindVar(obj, 1, 1);
- for (match = irec->matches; match; match = match->otherMatches) {
- IRO_InitList(&list1);
- IRO_InitList(&list2);
- IRO_DuplicateExpr(match->nd, &list1);
- IRO_DuplicateExpr(match->nd, &list2);
- if (match->nd->type == IROLinearOperand && match->nd->u.node->type == EOBJREF) {
- tmp = IRO_LocateFather(match->nd);
- if (irec->flags & 2) {
- tmp->flags |= IROLF_BitfieldIndirect;
- var->x1A = match->nd->rtype;
- var->x1E = list2.tail;
- }
- match->nd->u.node = create_objectrefnode(obj);
- irec->x26 = list2.tail;
- } else {
- tmp = IRO_LocateFather(match->nd);
- if (irec->flags & 2) {
- tmp->flags |= IROLF_BitfieldIndirect;
- var->x1A = match->nd->rtype;
- var->x1E = list2.tail;
- }
- irec->x26 = list2.tail;
-
- IRO_NopOut(tmp->u.monadic);
- tmp->u.monadic = IRO_NewLinear(IROLinearOperand);
- tmp->u.monadic->u.node = create_objectrefnode(obj);
- tmp->u.monadic->rtype = match->nd->rtype;
- tmp->u.monadic->index = ++IRO_NumLinear;
- tmp->u.monadic->flags |= IROLF_Ind | IROLF_Reffed;
- IRO_NopOut(match->nd);
- IRO_PasteAfter(tmp->u.monadic, tmp->u.monadic, match->nd);
- }
- }
-
- if (ObjectIsArg(irec->var->object)) {
- IROLinear *op1;
- IROLinear *op2;
- IROLinear *op3;
- IROLinear *op4;
- IROLinear *op5;
-
- op1 = IRO_NewLinear(IROLinearOperand);
- op1->u.node = create_objectrefnode(obj);
- op1->rtype = op1->u.node->data.objref->type;
- op1->index = ++IRO_NumLinear;
- op1->flags |= IROLF_Ind | IROLF_Assigned;
-
- op2 = list1.tail;
-
- op3 = IRO_NewLinear(IROLinearOp1Arg);
- op3->nodetype = EINDIRECT;
- op3->rtype = irec->type;
- op3->u.monadic = op1;
- op3->index = ++IRO_NumLinear;
- op3->flags |= IROLF_Assigned;
-
- op4 = IRO_NewLinear(IROLinearOp1Arg);
- op4->nodetype = EINDIRECT;
- op4->rtype = irec->type;
- op4->u.monadic = op2;
- op4->index = ++IRO_NumLinear;
- op4->flags |= IROLF_Reffed;
-
- op5 = IRO_NewLinear(IROLinearOp2Arg);
- op5->nodetype = EASS;
- op5->u.diadic.left = op3;
- op5->u.diadic.right = op4;
- op5->rtype = irec->type;
- op5->index = ++IRO_NumLinear;
-
- op2->next = op4;
- op4->next = op1;
- op1->next = op3;
- op3->next = op5;
-
- IRO_PasteAfter(list1.head, op5, IRO_FirstLinear);
- }
- }
- }
-
- IRO_CheckForUserBreak();
-}
-
-static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag) {
- IROLinear *inner;
- VarRecord *var;
- Boolean result;
-
- inner = nd->u.monadic;
- if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD)
- inner = inner->u.monadic;
-
- result = 0;
-
- if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF) {
- if (IS_TYPE_CLASS(inner->u.node->data.objref->type) || IS_TYPE_STRUCT(inner->u.node->data.objref->type) ||
- IS_TYPE_ARRAY(inner->u.node->data.objref->type)) {
- if (inner->u.node->data.objref->datatype == DLOCAL) {
- var = IRO_FindVar(inner->u.node->data.objref, 0, 1);
- CError_ASSERT(2240, var != NULL);
- CheckAddressConsistency(nd, var, 0, nd->rtype);
- result = 1;
- }
- }
- } else if (
- inner->type == IROLinearOp2Arg &&
- inner->nodetype == EADD &&
- inner->u.diadic.left->type == IROLinearOperand &&
- inner->u.diadic.left->u.node->type == EOBJREF) {
- if (
- inner->u.diadic.right->type == IROLinearOperand &&
- inner->u.diadic.right->u.node->type == EINTCONST &&
- inner->u.diadic.right->u.node->data.intval.hi == 0) {
- if (
- IS_TYPE_CLASS(inner->u.diadic.left->u.node->data.objref->type) ||
- IS_TYPE_STRUCT(inner->u.diadic.left->u.node->data.objref->type) ||
- IS_TYPE_ARRAY(inner->u.diadic.left->u.node->data.objref->type)
- ) {
- if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) {
- var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1);
- CError_ASSERT(2267, var != NULL);
- CheckAddressConsistency(nd, var, inner->u.diadic.right->u.node->data.intval.lo, nd->rtype);
- result = 1;
- }
- }
- } else {
- if (
- IS_TYPE_CLASS(inner->u.diadic.left->u.node->data.objref->type) ||
- IS_TYPE_STRUCT(inner->u.diadic.left->u.node->data.objref->type) ||
- IS_TYPE_ARRAY(inner->u.diadic.left->u.node->data.objref->type)
- ) {
- if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) {
- var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1);
- CheckAddressConsistency(nd, var, -1, nd->rtype);
- result = 1;
- }
- }
- }
- }
-
- if (!result && !*resultFlag) {
- *resultFlag = IndirectMightUseOrKillAnyAddressedVar(nd);
- }
-
- return 0;
-}
-
-static Boolean CheckAddressConsistency(IROLinear *nd, VarRecord *var, SInt32 addend, Type *type) {
- IndirectRecord *rp;
- IndirectRecordMatch *match;
- UInt32 flag;
- IROLinear *inner;
- UInt32 start_bit;
- UInt32 end_bit;
-
- flag = 0;
- inner = nd->u.monadic;
- if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD) {
- start_bit = TYPE_BITFIELD(inner->rtype)->offset + 8 * addend;
- end_bit = start_bit + TYPE_BITFIELD(inner->rtype)->bitlength - 1;
- } else {
- start_bit = 8 * addend;
- end_bit = start_bit + 8 * type->size - 1;
- }
-
- if (var->xB && !copts.opt_pointer_analysis)
- return 0;
-
- if (nd->rtype && CParser_IsVolatile(nd->rtype, nd->nodeflags & ENODE_FLAG_QUALS))
- addend = -1;
- if (is_volatile_object(var->object))
- addend = -1;
-
- for (rp = IRO_FirstIndirectRecord; rp; rp = rp->next) {
- if (rp->var->index == var->index) {
- if (rp->flags & 1)
- return 0;
-
- if (addend == -1) {
- flag = 1;
- break;
- }
-
- if (IRO_TypesEqual(rp->type, type) && rp->startbit == start_bit && rp->endbit == end_bit) {
- match = oalloc(sizeof(IndirectRecordMatch));
- match->nd = inner;
- match->otherMatches = NULL;
- if (!rp->matches) {
- rp->matches = match;
- } else {
- match->otherMatches = rp->matches;
- rp->matches = match;
- }
-
- IRO_Dump("Exact Match of Type and bits at %d and %d\n", rp->linear->index, nd->index);
- IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit);
- return 1;
- }
-
- if (rp->startbit == start_bit && rp->endbit == end_bit && !IRO_TypesEqual(rp->type, type)) {
- IRO_Dump("match on bits but mismatch on type %d and %d\n", rp->linear->index, nd->index);
- IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit);
- flag = 1;
- break;
- }
-
- if (rp->startbit >= start_bit && end_bit >= rp->startbit) {
- IRO_Dump("Overlap detected --1 %d and %d\n", rp->linear->index, nd->index);
- IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit);
- flag = 1;
- break;
- }
-
- if (rp->startbit < start_bit && rp->endbit >= start_bit) {
- IRO_Dump("Overlap detected --2 %d and %d\n", rp->linear->index, nd->index);
- IRO_Dump("Rp->startbit=%d,Rp->endbit=%d,start_bit=%d,end_bit=%d\n", rp->startbit, rp->endbit, start_bit, end_bit);
- flag = 1;
- break;
- }
- }
- }
-
- if (flag) {
- DisableEntries(rp);
- if (addend >= 0)
- return 0;
- }
-
- IRO_Dump("Create Entry at %d\n", nd->index);
- IRO_Dump("start_bit=%d,end_bit=%d\n", start_bit, end_bit);
-
- rp = oalloc(sizeof(IndirectRecord));
- rp->linear = nd;
- rp->flags = 0;
- rp->var = var;
- rp->addend = addend;
- rp->size = type->size;
- rp->type = type;
- rp->next = NULL;
- rp->matches = oalloc(sizeof(IndirectRecordMatch));
- rp->matches->nd = inner;
- rp->matches->otherMatches = NULL;
- rp->startbit = start_bit;
- rp->endbit = end_bit;
-
- if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT &&
- nd->u.monadic->type == IROLinearOp1Arg && nd->u.monadic->nodetype == EBITFIELD)
- rp->flags |= 2;
-
- if (!(IS_TYPE_FLOAT(type) || IS_TYPE_INT(type) || IS_TYPE_POINTER_ONLY(type)) ||
- addend == -1 || ((inner->flags & IROLF_4000) && ObjectIsArg(var->object)))
- rp->flags |= 1;
-
- if (IRO_FirstIndirectRecord)
- IRO_LastIndirectRecord->next = rp;
- else
- IRO_FirstIndirectRecord = rp;
- IRO_LastIndirectRecord = rp;
- return 1;
-}
-
-static void DisableEntries(IndirectRecord *irec) {
- IndirectRecord *scan;
-
- for (scan = IRO_FirstIndirectRecord; scan; scan = scan->next) {
- if (irec->var->index == scan->var->index)
- scan->flags |= 1;
- }
-}
-
-static void DisableAddressedEntries(void) {
- IndirectRecord *scan;
-
- for (scan = IRO_FirstIndirectRecord; scan; scan = scan->next) {
- if (scan->var->xB)
- scan->flags |= 1;
- }
-}
-
-static UInt32 ObjectIsArg(Object *obj) {
- ObjectList *scan;
-
- for (scan = arguments; scan; scan = scan->next) {
- if (scan->object == obj)
- return 1;
- }
-
- return 0;
-}
-
diff --git a/compiler_and_linker/unsorted/LoopDetection.c b/compiler_and_linker/unsorted/LoopDetection.c
deleted file mode 100644
index 6bb2d51..0000000
--- a/compiler_and_linker/unsorted/LoopDetection.c
+++ /dev/null
@@ -1,885 +0,0 @@
-#include "compiler/LoopDetection.h"
-#include "compiler/CFunc.h"
-#include "compiler/PCode.h"
-#include "compiler/TOC.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/BitVectors.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-
-Loop *loopsinflowgraph;
-int loopdetection_nblocks;
-static UInt32 **dominators;
-static BlockList *loopheaders;
-static int nloopheaders;
-static PCodeBlock **loopstack;
-BitVector *LoopTemp;
-struct LoopList *LoopList_First;
-
-static void computedominators(void) {
- int i;
- PCodeBlock *block;
- int blockCount;
- int flag;
- UInt32 *myvec;
- PCLink *link;
-
- blockCount = pcblockcount;
- flag = 1;
-
- dominators = oalloc(sizeof(UInt32 *) * pcblockcount);
- for (i = 0; i < pcblockcount; i++)
- dominators[i] = oalloc(4 * ((blockCount + 31) >> 5));
-
- myvec = oalloc(4 * ((blockCount + 31) >> 5));
-
- bitvectorinitialize(dominators[pcbasicblocks->blockIndex], blockCount, 0);
- //dominators[pcbasicblocks->blockIndex][0] |= 1;
- bitvectorsetbit(0, dominators[pcbasicblocks->blockIndex]);
-
- for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock)
- bitvectorinitialize(dominators[block->blockIndex], blockCount, 0xFFFFFFFF);
-
- computedepthfirstordering();
-
- while (flag) {
- flag = 0;
- for (i = 0; i < pcblockcount; i++) {
- block = depthfirstordering[i];
- if (block && block->blockIndex != pcbasicblocks->blockIndex) {
- bitvectorcopy(myvec, dominators[block->predecessors->block->blockIndex], blockCount);
- for (link = block->predecessors->nextLink; link; link = link->nextLink)
- bitvectorintersect(myvec, dominators[link->block->blockIndex], blockCount);
- //myvec[block->blockIndex >> 5] |= 1 << (block->blockIndex & 31);
- bitvectorsetbit(block->blockIndex, myvec);
-
- if (bitvectorchanged(dominators[block->blockIndex], myvec, blockCount))
- flag = 1;
- }
- }
- }
-}
-
-static BlockList *findloopheaders(void) {
- PCodeBlock *block;
- PCLink *link;
- BlockList *list;
-
- loopheaders = NULL;
- nloopheaders = 0;
-
- for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
- for (link = block->predecessors; link; link = link->nextLink) {
- //if ((1 << (block->blockIndex & 31)) & dominators[link->block->blockIndex][block->blockIndex >> 5])
- if (bitvectorgetbit(block->blockIndex, dominators[link->block->blockIndex]))
- break;
- }
-
- if (link) {
- list = oalloc(sizeof(BlockList));
- list->block = block;
- list->next = loopheaders;
- loopheaders = list;
- nloopheaders++;
- }
- }
-
- return loopheaders;
-}
-
-void addblocktoloop(Loop *loop, PCodeBlock *block) {
- BlockList *list = lalloc(sizeof(BlockList));
-
- //loop->memberblocks[block->blockIndex >> 5] |= 1 << (block->blockIndex & 31);
- bitvectorsetbit(block->blockIndex, loop->memberblocks);
-
- list->block = block;
- list->next = loop->blocks;
- loop->blocks = list;
-}
-
-static void findnaturalloop(Loop *loop) {
- BlockList *list;
- BlockList *list2;
- PCLink *link;
- PCodeBlock *block;
- int i;
-
- i = 0;
- addblocktoloop(loop, loop->body);
- for (link = loop->body->predecessors; link; link = link->nextLink) {
- if (bitvectorgetbit(loop->body->blockIndex, dominators[link->block->blockIndex]) && link->block != loop->body) {
- addblocktoloop(loop, link->block);
- loopstack[i++] = link->block;
- }
- }
-
- while (i) {
- link = loopstack[--i]->predecessors;
- while (link) {
- if (!bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) {
- addblocktoloop(loop, link->block);
- loopstack[i++] = link->block;
- }
- link = link->nextLink;
- }
- }
-
- for (list = loop->blocks; list; list = list->next) {
- block = list->block;
- for (link = block->successors; link; link = link->nextLink) {
- if (!bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) {
- bitvectorsetbit(block->blockIndex, loop->vec24);
- break;
- }
- }
- }
-
- for (list = loop->blocks; list; list = list->next) {
- for (list2 = loop->blocks; list2; list2 = list2->next) {
- if (bitvectorgetbit(list2->block->blockIndex, loop->vec24) &&
- !bitvectorgetbit(list->block->blockIndex, dominators[list2->block->blockIndex]))
- break;
- }
-
- if (!list2)
- bitvectorsetbit(list->block->blockIndex, loop->vec28);
- }
-
- for (list = loop->blocks; list; list = list->next) {
- for (link = loop->body->predecessors; link; link = link->nextLink) {
- if (bitvectorgetbit(link->block->blockIndex, loop->memberblocks) &&
- !bitvectorgetbit(list->block->blockIndex, dominators[link->block->blockIndex]))
- break;
- }
-
- if (!link)
- bitvectorsetbit(list->block->blockIndex, loop->vec2C);
- }
-}
-
-static void addlooptolist(Loop *loop, Loop **list) {
- Loop **scan;
- Loop *scanloop;
-
- scan = list;
- while ((scanloop = *scan)) {
- if (bitvectorgetbit(loop->body->blockIndex, scanloop->memberblocks)) {
- loop->parent = scanloop;
- addlooptolist(loop, &scanloop->children);
- return;
- }
-
- if (bitvectorgetbit(scanloop->body->blockIndex, loop->memberblocks)) {
- *scan = scanloop->nextSibling;
- scanloop->parent = loop;
- scanloop->nextSibling = loop->children;
- loop->children = scanloop;
- } else {
- scan = &scanloop->nextSibling;
- }
- }
-
- loop->nextSibling = *list;
- *list = loop;
-}
-
-static void findnaturalloops(void) {
- Loop *loop;
- int size;
-
- loopdetection_nblocks = pcblockcount + 5 * nloopheaders;
- loopstack = oalloc(sizeof(PCodeBlock *) * pcblockcount);
- while (loopheaders) {
- loop = lalloc(sizeof(Loop));
- loop->parent = loop->nextSibling = loop->children = NULL;
- loop->body = loopheaders->block;
- loop->preheader = NULL;
- loop->blocks = NULL;
- loop->basicInductionVars = NULL;
- loop->footer = NULL;
- loop->pc18 = NULL;
- loop->loopWeight = loop->body->loopWeight;
-
- bitvectorinitialize(loop->memberblocks = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(loop->vec24 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(loop->vec28 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
- bitvectorinitialize(loop->vec2C = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0);
-
- findnaturalloop(loop);
- addlooptolist(loop, &loopsinflowgraph);
-
- loopheaders = loopheaders->next;
- }
-}
-
-static PCodeBlock *makepreheaderblock(void) {
- PCodeLabel *label;
- PCodeBlock *block;
-
- label = makepclabel();
- block = lalloc(sizeof(PCodeBlock));
- block->nextBlock = NULL;
- block->prevBlock = NULL;
- block->labels = NULL;
- block->successors = NULL;
- block->predecessors = NULL;
- block->firstPCode = block->lastPCode = NULL;
- block->pcodeCount = 0;
- block->flags = 0;
- block->blockIndex = pcblockcount++;
- pclabel(block, label);
- return block;
-}
-
-static void insertpreheaderbefore(PCodeBlock *a, PCodeBlock *b) {
- a->nextBlock = b;
- a->prevBlock = b->prevBlock;
- b->prevBlock->nextBlock = a;
- b->prevBlock = a;
-}
-
-void insertpreheaderblock(Loop *loop) {
- PCodeBlock *preheader;
- PCodeBlock *block29;
- PCodeBlock *block28;
- PCode *pcode27;
- PCLink *link; // r26
- PCLink **linkptr; // r25
- PCodeLabel *newlabel; // r23
- PCLink *innerlink;
- PCodeBlock *block;
- PCodeArg *arg;
- int i;
-
- preheader = loop->preheader = makepreheaderblock();
- block29 = NULL;
- block28 = loop->body;
-
- if (!block28->labels)
- pclabel(block28, makepclabel());
-
- appendpcode(preheader, makepcode(PC_B, block28->labels));
- preheader->loopWeight = loop->parent ? loop->parent->loopWeight : 1;
-
- linkptr = &block28->predecessors;
- while ((link = *linkptr)) {
- if (bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) {
- linkptr = &link->nextLink;
- } else {
- if (link->block->pcodeCount) {
- pcode27 = link->block->lastPCode;
- if (pcode27->op == PC_B) {
- CError_ASSERT(462, pcode27->args[0].kind == PCOp_LABEL);
- if (pcode27->args[0].data.label.label->block == block28)
- pcode27->args[0].data.label.label = preheader->labels;
- } else if (pcode27->op == PC_BT || pcode27->op == PC_BF) {
- CError_ASSERT(474, pcode27->args[2].kind == PCOp_LABEL);
- if (pcode27->args[2].data.label.label->block == block28)
- pcode27->args[2].data.label.label = preheader->labels;
- } else if (pcode27->op == PC_BCTR) {
- if (pcode27->argCount > 1 && pcode27->args[1].kind == PCOp_MEMORY) {
- Object *obj = pcode27->args[1].data.mem.obj;
- UInt32 *array = (UInt32 *) obj->u.data.u.switchtable.data;
- int i;
- for (i = 0; i < obj->u.data.u.switchtable.size; i++) {
- if (((PCodeLabel *) CTool_ResolveIndexToPointer(array[i]))->block == block28)
- array[i] = CTool_CreateIndexFromPointer(preheader->labels);
- }
- } else {
- CodeLabelList *cll;
- for (cll = codelabellist; cll; cll = cll->next) {
- if (cll->label->pclabel->block == block28)
- cll->label->pclabel = preheader->labels;
- }
- }
- } else {
- CError_ASSERT(505, link->block->nextBlock == block28);
- }
- }
-
- for (innerlink = link->block->successors; innerlink; innerlink = innerlink->nextLink) {
- if (innerlink->block == block28)
- innerlink->block = preheader;
- }
-
- *linkptr = link->nextLink;;
- link->nextLink = preheader->predecessors;
- preheader->predecessors = link;
- }
- }
-
- if (!bitvectorgetbit(block28->prevBlock->blockIndex, loop->memberblocks)) {
- insertpreheaderbefore(preheader, block28);
-
- if (
- (!block28->nextBlock || !bitvectorgetbit(block28->nextBlock->blockIndex, loop->memberblocks)) &&
- block28->lastPCode &&
- (block28->lastPCode->flags & fIsBranch) &&
- block28->lastPCode->op != PC_BDNZ
- ) {
- i = block28->lastPCode->argCount;
- arg = block28->lastPCode->args;
- while (i && arg->kind != PCOp_LABEL) {
- arg++;
- i--;
- }
-
- if (i && arg->kind == PCOp_LABEL && arg->data.label.label->block == block28) {
- block29 = makepreheaderblock();
- insertpreheaderbefore(block29, block28);
- newlabel = makepclabel();
- pclabel(block29, newlabel);
- arg->data.label.label = newlabel;
-
- link = lalloc(sizeof(PCLink));
- link->block = block28;
- link->nextLink = block29->predecessors;
- block29->predecessors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = block28;
- link->nextLink = block29->successors;
- block29->successors = link;
-
- for (link = block28->successors; link; link = link->nextLink) {
- if (link->block == block28)
- link->block = block29;
- }
- for (link = block28->predecessors; link; link = link->nextLink) {
- if (link->block == block28)
- link->block = block29;
- }
-
- bitvectorsetbit(block29->blockIndex, loop->vec2C);
- addblocktoloop(loop, block29);
- }
- }
- } else {
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (bitvectorgetbit(block->blockIndex, loop->memberblocks))
- break;
- }
- insertpreheaderbefore(preheader, block);
- }
-
- link = lalloc(sizeof(PCLink));
- link->block = preheader;
- link->nextLink = block28->predecessors;
- block28->predecessors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = block28;
- link->nextLink = preheader->successors;
- preheader->successors = link;
-
- for (loop = loop->parent; loop; loop = loop->parent) {
- addblocktoloop(loop, preheader);
- if (bitvectorgetbit(block28->blockIndex, loop->vec28)) {
- bitvectorsetbit(preheader->blockIndex, loop->vec28);
- if (block29)
- bitvectorsetbit(block29->blockIndex, loop->vec28);
- }
- if (bitvectorgetbit(block28->blockIndex, loop->vec2C)) {
- bitvectorsetbit(preheader->blockIndex, loop->vec2C);
- if (block29)
- bitvectorsetbit(block29->blockIndex, loop->vec2C);
- }
- }
-}
-
-static void insertpreheaderblocks(Loop *loop) {
- while (loop) {
- if (loop->children)
- insertpreheaderblocks(loop->children);
- insertpreheaderblock(loop);
- loop = loop->nextSibling;
- }
-}
-
-void findloopsinflowgraph(void) {
- loopsinflowgraph = NULL;
- computedominators();
- if (findloopheaders()) {
- findnaturalloops();
- insertpreheaderblocks(loopsinflowgraph);
- }
- freeoheap();
-}
-
-static int checklooplimits(SInt32 opcode, SInt32 condition, SInt32 c, SInt32 d, SInt32 addend, SInt32 *result) {
- if (opcode == PC_BT) {
- if (condition == 0) {
- if (addend <= 0)
- return 0;
- if (c < d)
- *result = (d - c + addend - 1) / addend;
- else
- *result = 0;
- } else if (condition == 1) {
- if (addend >= 0)
- return 0;
- if (c > d)
- *result = (c - d - addend - 1) / -addend;
- else
- *result = 0;
- } else {
- return 0;
- }
- } else {
- if (condition == 0) {
- if (addend >= 0)
- return 0;
- if (c >= d)
- *result = (c - d - addend) / -addend;
- else
- *result = 0;
- } else if (condition == 1) {
- if (addend <= 0)
- return 0;
- if (c <= d)
- *result = (d - c + addend) / addend;
- else
- *result = 0;
- } else if (c < d) {
- if (addend <= 0)
- return 0;
- if ((d - c) % addend)
- return 0;
- *result = (d - c) / addend;
- } else if (c > d) {
- if (addend >= 0)
- return 0;
- if ((c - d) % -addend)
- return 0;
- *result = (c - d) / -addend;
- } else {
- *result = 0;
- }
- }
-
- return 1;
-}
-
-static int checkunsignedlooplimits(SInt32 opcode, SInt32 condition, UInt32 c, UInt32 d, SInt32 addend, UInt32 *result) {
- if (opcode == PC_BT) {
- if (condition == 0) {
- if (addend <= 0)
- return 0;
- if (c < d)
- *result = (d - c + addend - 1) / addend;
- else
- *result = 0;
- } else if (condition == 1) {
- if (addend >= 0)
- return 0;
- if (c > d)
- *result = (c - d - addend - 1) / -addend;
- else
- *result = 0;
- } else {
- return 0;
- }
- } else {
- if (condition == 0) {
- if (addend >= 0)
- return 0;
- if (c >= d)
- *result = (c - d - addend) / -addend;
- else
- *result = 0;
- } else if (condition == 1) {
- if (addend <= 0)
- return 0;
- if (c <= d)
- *result = (d - c + addend) / addend;
- else
- *result = 0;
- } else if (c < d) {
- if (addend <= 0)
- return 0;
- if ((d - c) % addend)
- return 0;
- *result = (d - c) / addend;
- } else if (c > d) {
- if (addend >= 0)
- return 0;
- if ((c - d) % -addend)
- return 0;
- *result = (c - d) / -addend;
- } else {
- *result = 0;
- }
- }
-
- return (*result & 0x80000000) == 0;
-}
-
-static int checkunknownloop(int a, int b, int c, unsigned char *op) {
- if (a == PC_BT) {
- if (b == 0) {
- if (c <= 0)
- return 0;
- *op = ELESS;
- } else if (b == 1) {
- if (c >= 0)
- return 0;
- *op = EGREATER;
- } else {
- return 0;
- }
- } else {
- if (b == 0) {
- if (c >= 0)
- return 0;
- *op = EGREATEREQU;
- } else if (b == 1) {
- if (c <= 0)
- return 0;
- *op = ELESSEQU;
- } else if (c == 1) {
- *op = ENOTEQU;
- } else if (c == -1) {
- *op = ENOTEQU;
- } else {
- return 0;
- }
- }
-
- return 1;
-}
-
-static void checkcountingloop(Loop *loop) {
- RegUseOrDef *list;
- PCode *lastpcode;
- PCode *prevpcode;
- PCode *pc8;
- PCode *check;
- short op12;
- short reg11;
- SInt16 reg4;
- short reg11b;
- Loop *child;
-
- if (!(lastpcode = loop->body->lastPCode))
- return;
- if (lastpcode->op != PC_BT && lastpcode->op != PC_BF)
- return;
- if (lastpcode->args[2].kind != PCOp_LABEL)
- return;
-
- if (!bitvectorgetbit(lastpcode->args[2].data.label.label->block->blockIndex, loop->memberblocks))
- return;
- if (bitvectorgetbit(loop->body->nextBlock->blockIndex, loop->memberblocks))
- return;
-
- reg11 = lastpcode->args[0].data.reg.reg;
- reg4 = lastpcode->args[1].data.imm.value;
- prevpcode = lastpcode->prevPCode;
- if (!prevpcode)
- return;
-
- op12 = prevpcode->op;
- if (op12 == PC_ADDI && prevpcode->args[2].kind == PCOp_IMMEDIATE) {
- pc8 = prevpcode;
- prevpcode = prevpcode->prevPCode;
- if (!prevpcode)
- return;
-
- op12 = prevpcode->op;
- if (pc8->args[0].data.reg.reg != pc8->args[1].data.reg.reg)
- return;
- if (op12 != PC_CMP && op12 != PC_CMPL && op12 != PC_CMPI && op12 != PC_CMPLI)
- return;
- if (prevpcode->args[1].data.reg.reg != pc8->args[0].data.reg.reg)
- return;
- if ((loop->step = pc8->args[2].data.imm.value) == 0)
- return;
- }
-
- if (op12 != PC_CMP && op12 != PC_CMPL && op12 != PC_CMPI && op12 != PC_CMPLI)
- return;
-
- if (prevpcode->args[0].data.reg.reg != reg11)
- return;
-
- reg11b = prevpcode->args[1].data.reg.reg;
- if (reg11b < 32)
- return;
-
- if (loop->preheader->nextBlock != lastpcode->args[2].data.label.label->block)
- return;
-
- if (op12 == PC_CMPI) {
- if (prevpcode->prevPCode)
- return;
- loop->upper = prevpcode->args[2].data.imm.value;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (op12 == PC_CMPLI) {
- if (prevpcode->prevPCode)
- return;
- loop->upper = prevpcode->args[2].data.imm.value & 0xFFFF;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (op12 == PC_CMP || op12 == PC_CMPL) {
- if (prevpcode->prevPCode) {
- if (
- prevpcode->prevPCode->op == PC_LI &&
- prevpcode->prevPCode->args[1].kind == PCOp_IMMEDIATE &&
- prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- !prevpcode->prevPCode->prevPCode
- ) {
- loop->upper = prevpcode->prevPCode->args[1].data.imm.value;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (
- prevpcode->prevPCode->op == PC_LIS &&
- prevpcode->prevPCode->args[1].kind == PCOp_IMMEDIATE &&
- prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- !prevpcode->prevPCode->prevPCode
- ) {
- loop->upper = prevpcode->prevPCode->args[1].data.imm.value << 16;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (
- prevpcode->prevPCode->op == PC_ADDI &&
- prevpcode->prevPCode->args[2].kind == PCOp_IMMEDIATE &&
- prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- prevpcode->prevPCode->args[1].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- prevpcode->prevPCode->prevPCode &&
- prevpcode->prevPCode->prevPCode->op == PC_LIS &&
- prevpcode->prevPCode->prevPCode->args[1].kind == PCOp_IMMEDIATE &&
- prevpcode->prevPCode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- !prevpcode->prevPCode->prevPCode->prevPCode
- ) {
- loop->upper = prevpcode->prevPCode->args[2].data.imm.value +
- (prevpcode->prevPCode->prevPCode->args[1].data.imm.value << 16);
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else {
- return;
- }
- } else {
- pc8 = NULL;
- for (list = reg_Defs[RegClass_GPR][prevpcode->args[2].data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks))
- return;
- }
- for (list = reg_Defs[RegClass_GPR][prevpcode->args[2].data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].defvec8)) {
- if (!pc8) {
- pc8 = Defs[list->id].pcode;
- if (
- pc8->op == PC_LI &&
- pc8->args[1].kind == PCOp_IMMEDIATE
- ) {
- loop->upper = pc8->args[1].data.imm.value;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (
- pc8->op == PC_LIS &&
- pc8->args[1].kind == PCOp_IMMEDIATE
- ) {
- loop->upper = pc8->args[1].data.imm.value << 16;
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else if (
- pc8->op == PC_ADDI &&
- pc8->args[2].kind == PCOp_IMMEDIATE &&
- pc8->args[1].data.reg.reg == prevpcode->args[2].data.reg.reg &&
- pc8->prevPCode &&
- pc8->prevPCode->op == PC_LIS &&
- pc8->prevPCode->args[1].kind == PCOp_IMMEDIATE &&
- pc8->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg
- ) {
- loop->upper = pc8->args[2].data.imm.value +
- (pc8->prevPCode->args[1].data.imm.value << 16);
- loop->upperType = LOOP_BOUND_CONSTANT;
- } else {
- loop->upperType = LOOP_BOUND_VARIABLE;
- break;
- }
- } else {
- loop->upperType = LOOP_BOUND_VARIABLE;
- break;
- }
- }
- }
-
- if (loop->upperType == LOOP_BOUND_INDETERMINATE)
- loop->upperType = LOOP_BOUND_VARIABLE;
- }
- }
-
- pc8 = NULL;
-
- for (list = reg_Defs[RegClass_GPR][reg11b]; list; list = list->next) {
- check = Defs[list->id].pcode;
- if (bitvectorgetbit(check->block->blockIndex, loop->memberblocks)) {
- if (!pc8) {
- pc8 = check;
- if (check->op != PC_ADDI)
- return;
- if (check->args[1].data.reg.reg != reg11b)
- return;
- if (check->args[2].kind != PCOp_IMMEDIATE)
- return;
- if ((loop->step = check->args[2].data.imm.value) == 0)
- return;
- } else {
- return;
- }
- }
- }
-
- if (!pc8)
- return;
-
- if (pc8->block != prevpcode->block && !bitvectorgetbit(prevpcode->block->blockIndex, loop->vec2C))
- return;
-
- if (loop->children) {
- for (child = loop->children; child; child = child->nextSibling) {
- if (bitvectorgetbit(pc8->block->blockIndex, child->memberblocks))
- return;
- }
- }
-
- loop->pc18 = pc8;
-
- pc8 = NULL;
-
- for (list = reg_Defs[RegClass_GPR][reg11b]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].defvec8)) {
- if (!pc8) {
- pc8 = Defs[list->id].pcode;
- if (
- pc8->op == PC_LI &&
- pc8->args[1].kind == PCOp_IMMEDIATE
- ) {
- loop->lower = pc8->args[1].data.imm.value;
- loop->lowerType = LOOP_BOUND_CONSTANT;
- } else if (
- pc8->op == PC_LIS &&
- pc8->args[1].kind == PCOp_IMMEDIATE
- ) {
- loop->lower = pc8->args[1].data.imm.value << 16;
- loop->lowerType = LOOP_BOUND_CONSTANT;
- } else if (
- pc8->op == PC_ADDI &&
- pc8->args[2].kind == PCOp_IMMEDIATE &&
- pc8->args[1].data.reg.reg == reg11b &&
- pc8->prevPCode &&
- pc8->prevPCode->op == PC_LIS &&
- pc8->prevPCode->args[1].kind == PCOp_IMMEDIATE &&
- pc8->prevPCode->args[0].data.reg.reg == reg11b
- ) {
- loop->lower = pc8->args[2].data.imm.value +
- (pc8->prevPCode->args[1].data.imm.value << 16);
- loop->lowerType = LOOP_BOUND_CONSTANT;
- } else {
- loop->lowerType = LOOP_BOUND_VARIABLE;
- break;
- }
- } else {
- loop->lowerType = LOOP_BOUND_INDETERMINATE;
- break;
- }
- }
- }
-
- if (loop->lowerType == LOOP_BOUND_INDETERMINATE)
- loop->lowerType = LOOP_BOUND_VARIABLE;
-
- if (loop->lowerType == LOOP_BOUND_CONSTANT && loop->upperType == LOOP_BOUND_CONSTANT) {
- if (op12 == PC_CMP || op12 == PC_CMPI) {
- if (!checklooplimits(lastpcode->op, reg4, loop->lower, loop->upper, loop->step, &loop->iterationCount))
- return;
- } else {
- if (!checkunsignedlooplimits(lastpcode->op, reg4, loop->lower, loop->upper, loop->step, (UInt32 *) &loop->iterationCount))
- return;
- }
- loop->isKnownCountingLoop = 1;
- } else if (loop->lowerType != LOOP_BOUND_INDETERMINATE || loop->upperType != LOOP_BOUND_INDETERMINATE) {
- if (!checkunknownloop(lastpcode->op, reg4, loop->step, &loop->unknownCondition))
- return;
- loop->isUnknownCountingLoop = 1;
- }
-}
-
-void analyzeForCountableLoops(Loop *loop) {
- if (!loop)
- return;
-
- while (loop) {
- if (loop->children)
- analyzeForCountableLoops(loop->children);
- checkcountingloop(loop);
- loop = loop->nextSibling;
- }
-}
-
-void analyzeloop(Loop *loop) {
- BlockList *list;
- PCodeBlock *block;
- PCode *pcode;
-
- loop->bodySize = 0;
- loop->x4D = 0;
- loop->x4E = 0;
- loop->x4F = 1;
- loop->isKnownCountingLoop = 0;
- loop->isUnknownCountingLoop = 0;
- loop->lowerType = LOOP_BOUND_INDETERMINATE;
- loop->upperType = LOOP_BOUND_INDETERMINATE;
- loop->iterationCount = -1;
- loop->x57 = 0;
- loop->x52 = 0;
-
- for (list = loop->blocks; list; list = list->next) {
- block = list->block;
- if (!loop->children)
- block->flags |= fPCBlockFlag2000;
- loop->bodySize += block->pcodeCount;
-
- if (block != loop->body) {
- if (!block->successors || !block->predecessors || block->successors->nextLink || block->predecessors->nextLink)
- loop->x4F = 0;
- }
-
- if ((block->flags & fPCBlockFlag4000) == fPCBlockFlag4000)
- loop->x52 = 1;
-
- for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
- if (PCODE_FLAG_SET_T(pcode) & fLink)
- loop->x4D = 1;
-
- if (pcode->op == PC_BCTRL || pcode->op == PC_BCTR || pcode->op == PC_BCCTR || pcode->op == PC_MTCTR || pcode->op == PC_MFCTR) {
- loop->x4E = 1;
- } else if (pcode->flags & fIsRead) {
- if (pcode->op == PC_LBZX || pcode->op == PC_LHZX || pcode->op == PC_LHAX || pcode->op == PC_LWZX || pcode->op == PC_LFSX || pcode->op == PC_LFDX)
- loop->x53 = 1;
- } else if (pcode->flags & fIsWrite) {
- if (pcode->op == PC_STBX || pcode->op == PC_STHX || pcode->op == PC_STWX || pcode->op == PC_STFSX || pcode->op == PC_STFDX)
- loop->x54 = 1;
- } else {
- if (pcode->op == PC_EIEIO || pcode->op == PC_SYNC || pcode->op == PC_ISYNC)
- loop->x57 = 1;
- }
- }
- }
-
- if (!loop->children && !loop->x4D && loop->bodySize < 32) {
- for (list = loop->blocks; list; list = list->next)
- list->block->flags |= fPCBlockFlag2000;
- }
-}
-
-static void analyzeloops(Loop *loop) {
- while (loop) {
- if (loop->children)
- analyzeloops(loop->children);
- analyzeloop(loop);
- loop = loop->nextSibling;
- }
-}
-
-void analyzeloopsinflowgraph(void) {
- if (loopsinflowgraph)
- analyzeloops(loopsinflowgraph);
-}
diff --git a/compiler_and_linker/unsorted/LoopOptimization.c b/compiler_and_linker/unsorted/LoopOptimization.c
deleted file mode 100644
index b2aef1e..0000000
--- a/compiler_and_linker/unsorted/LoopOptimization.c
+++ /dev/null
@@ -1,1553 +0,0 @@
-#include "compiler/LoopOptimization.h"
-#include "compiler/CFunc.h"
-#include "compiler/CParser.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/LoopDetection.h"
-#include "compiler/PCode.h"
-#include "compiler/Registers.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-int optimizedloops;
-int optimizedloop_full_unroll;
-int optimizedloop_trans_regs;
-static UInt32 *liveonexit;
-static UInt32 *inductionvariables;
-static int last_virtual_GPR;
-
-static int ispowerof2(SInt32 value) {
- int bit = getbit(value);
- return (bit > 0 && bit < 31) ? bit : 0;
-}
-
-static void insertupdateinstructions(Loop *loop) {
- // nothing
-}
-
-static void computeliveonexit(Loop *loop) {
- UInt32 *usevec;
- UInt32 *defvec;
- BlockList *blocklist;
- RegUseOrDef *list;
- int gpr;
-
- bitvectorinitialize(usevec = oalloc(4 * ((number_of_Uses + 31) >> 5)), number_of_Uses, 0);
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- if (bitvectorgetbit(blocklist->block->blockIndex, loop->vec24))
- bitvectorunion(usevec, usedefinfo[blocklist->block->blockIndex].usevec1C, number_of_Uses);
- }
-
- bitvectorinitialize(defvec = oalloc(4 * ((number_of_Defs + 31) >> 5)), number_of_Defs, 0);
- if (loop->preheader)
- bitvectorunion(defvec, usedefinfo[loop->preheader->blockIndex].defvec8, number_of_Defs);
-
- bitvectorinitialize(liveonexit, last_virtual_GPR, 0);
-
- for (gpr = 32; gpr < last_virtual_GPR; gpr++) {
- for (list = reg_Defs[RegClass_GPR][gpr]; list; list = list->next) {
- if (bitvectorgetbit(list->id, defvec)) {
- if (!Defs[list->id].pcode->block || bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)) {
- bitvectorsetbit(gpr, liveonexit);
- break;
- }
- }
- }
-
- for (list = reg_Uses[RegClass_GPR][gpr]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usevec)) {
- if (!Uses[list->id].pcode->block || !bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)) {
- bitvectorsetbit(gpr, liveonexit);
- break;
- }
- }
- }
- }
-}
-
-static void eliminateinductionvariables(Loop *loop) {
- BlockList *blocklist;
- PCode *instr;
- PCode *nextInstr;
- PCodeArg *op;
- int i;
-
- bitvectorinitialize(inductionvariables, last_virtual_GPR, 0xFFFFFFFF);
-
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- for (instr = blocklist->block->firstPCode; instr; instr = instr->nextPCode) {
- if (
- instr->op != PC_ADDI ||
- instr->args[0].data.reg.reg < 32 ||
- instr->args[0].data.reg.reg >= last_virtual_GPR ||
- instr->args[1].data.reg.reg != instr->args[0].data.reg.reg
- ) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg >= n_real_registers[RegClass_GPR] &&
- op->data.reg.reg < last_virtual_GPR
- )
- bitvectorclearbit(op->data.reg.reg, inductionvariables);
- op++;
- }
- }
- }
- }
-
- if (loop->parent) {
- for (instr = loop->preheader->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg >= n_real_registers[RegClass_GPR] &&
- op->data.reg.reg < last_virtual_GPR
- )
- bitvectorsetbit(op->data.reg.reg, liveonexit);
- op++;
- }
- }
- }
-
- for (blocklist = loop->blocks; blocklist; blocklist = blocklist->next) {
- for (instr = blocklist->block->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- if (
- instr->op == PC_ADDI &&
- instr->args[0].data.reg.reg >= 32 &&
- instr->args[0].data.reg.reg < last_virtual_GPR &&
- instr->args[1].data.reg.reg == instr->args[0].data.reg.reg &&
- bitvectorgetbit(instr->args[0].data.reg.reg, inductionvariables) &&
- !bitvectorgetbit(instr->args[0].data.reg.reg, liveonexit)
- ) {
- deletepcode(instr);
- optimizedloops = 1;
- }
- }
- }
-}
-
-static void skiplooptest(Loop *loop) {
- PCodeBlock *preheader;
- PCodeLabel *label;
- PCLink **ptr;
- PCLink *link;
- PCode *lastInstr;
- PCode *instr;
-
- preheader = loop->preheader;
- lastInstr = loop->body->lastPCode;
- CError_ASSERT(340, lastInstr->args[2].kind == PCOp_LABEL);
-
- label = lastInstr->args[2].data.label.label;
- preheader->lastPCode->args[0].data.label.label = label;
- preheader->successors->block = label->block;
-
- ptr = &loop->body->predecessors;
- while ((link = *ptr)) {
- if (link->block == preheader) {
- *ptr = link->nextLink;
- break;
- }
- ptr = &link->nextLink;
- }
-
- link->nextLink = label->block->predecessors;
- label->block->predecessors = link;
-
- while (1) {
- instr = loop->body->firstPCode;
- CError_ASSERT(369, instr);
-
- if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
- break;
-
- deletepcode(instr);
- insertpcodebefore(loop->preheader->lastPCode, instr);
- loop->bodySize--;
- }
-
- for (instr = instr->nextPCode; instr && !(instr->flags & fIsBranch); instr = instr->nextPCode)
- insertpcodebefore(loop->preheader->lastPCode, copypcode(instr));
-}
-
-static void unrollloop(Loop *loop) {
- PCodeBlock *newBlock;
- int i;
- int factor;
- PCode *instr;
- PCodeBlock *block;
- PCode *firstInstr;
- PCode *nextInstr;
-
- for (factor = copts.unroll_factor_limit; factor > 1; factor--) {
- if ((loop->iterationCount % factor) == 0 && (loop->bodySize - 2) * factor <= copts.unroll_instr_limit)
- break;
- }
-
- if (factor == 1)
- return;
- if ((loop->iterationCount / factor) != 1 && loop->bodySize < 4)
- return;
-
- newBlock = oalloc(sizeof(PCodeBlock));
- newBlock->firstPCode = newBlock->lastPCode = NULL;
- for (i = 0; i < factor - 1; i++) {
- firstInstr = loop->body->firstPCode;
- CError_ASSERT(448, firstInstr);
- if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI)
- CError_FATAL(450);
-
- for (instr = firstInstr->nextPCode; instr && !(instr->flags & fIsBranch); instr = instr->nextPCode)
- appendpcode(newBlock, copypcode(instr));
-
- for (block = loop->preheader->successors->block; block != loop->body; block = block->successors->block) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->op != PC_B)
- appendpcode(newBlock, copypcode(instr));
- }
- }
- }
-
- block = loop->body->predecessors->block;
- for (instr = newBlock->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- appendpcode(block, instr);
- }
- loop->iterationCount /= factor;
-}
-
-void pccomputepredecessors1(PCodeBlock *block) {
- PCLink *succ;
- PCLink *pred;
-
- for (succ = block->successors; succ; succ = succ->nextLink) {
- if (!succ->block) {
- CError_FATAL(496);
- } else {
- for (pred = succ->block->predecessors; pred; pred = pred->nextLink) {
- if (pred->block == block)
- break;
- }
-
- if (!pred) {
- pred = lalloc(sizeof(PCLink));
- pred->block = block;
- pred->nextLink = succ->block->predecessors;
- succ->block->predecessors = pred;
- }
- }
- }
-}
-
-static PCodeBlock *insertnewpcblock(PCodeBlock *block, int loopWeight) {
- PCodeBlock *newBlock;
- PCodeBlock *nextBlock;
- PCodeLabel *label;
- PCLink *prev;
- PCLink *link;
-
- label = makepclabel();
- newBlock = lalloc(sizeof(PCodeBlock));
-
- nextBlock = block->nextBlock;
- newBlock->nextBlock = nextBlock;
- block->nextBlock = newBlock;
-
- newBlock->prevBlock = block;
- nextBlock->prevBlock = newBlock;
-
- newBlock->labels = NULL;
- newBlock->predecessors = newBlock->successors = NULL;
- newBlock->firstPCode = newBlock->lastPCode = NULL;
- newBlock->pcodeCount = 0;
- newBlock->loopWeight = loopWeight;
- newBlock->flags = 0;
- newBlock->blockIndex = pcblockcount++;
- pclabel(newBlock, label);
-
- prev = NULL;
- for (link = block->successors; link; link = link->nextLink) {
- if (link->block == nextBlock) {
- if (!prev)
- block->successors = link->nextLink;
- else
- prev->nextLink = link->nextLink;
- link->nextLink = NULL;
- newBlock->successors = link;
- break;
- }
- prev = link;
- }
-
- prev = NULL;
- for (link = nextBlock->predecessors; link; link = link->nextLink) {
- if (link->block == block) {
- if (!prev)
- nextBlock->predecessors = link->nextLink;
- else
- prev->nextLink = link->nextLink;
- link->nextLink = NULL;
- newBlock->predecessors = link;
- break;
- }
- prev = link;
- }
-
- link = lalloc(sizeof(PCLink));
- link->block = newBlock;
- link->nextLink = block->successors;
- block->successors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = newBlock;
- link->nextLink = nextBlock->predecessors;
- nextBlock->predecessors = link;
-
- return newBlock;
-}
-
-static void unrollloopconditional(Loop *loop) {
- PCodeBlock *lastBlock;
- PCodeLabel *label24;
- PCode *instr;
- PCode *instrCopy;
- int outputBlockCount;
- int inputBlockCount;
- PCodeBlock **blocks;
- PCodeBlock **blocks2;
- PCodeBlock **blocks3;
- PCode *firstInstr;
- int factor;
- PCodeBlock *block;
- PCLink *link;
- PCLink *prev;
- int i;
- int j;
- int k;
- int instructionCount;
-
- label24 = NULL;
- outputBlockCount = 0;
- instructionCount = 0;
-
- for (factor = copts.unroll_factor_limit; factor > 1; factor--) {
- if ((loop->iterationCount % factor) == 0 && (loop->bodySize - 2) * factor <= copts.unroll_instr_limit)
- break;
- }
-
- if (factor == 1)
- return;
-
- inputBlockCount = 0;
- for (block = loop->preheader->successors->block; block != loop->body; block = block->nextBlock) {
- inputBlockCount++;
- if (!bitvectorgetbit(block->blockIndex, loop->memberblocks))
- instructionCount += block->pcodeCount;
- }
-
- if ((loop->bodySize - instructionCount - 2) < instructionCount || instructionCount > 8)
- return;
-
- blocks = oalloc(inputBlockCount * sizeof(PCodeBlock *));
- blocks2 = oalloc(inputBlockCount * sizeof(PCodeBlock *));
- blocks3 = oalloc(factor * (inputBlockCount * sizeof(PCodeBlock *)));
- memclrw(blocks, inputBlockCount * sizeof(PCodeBlock *));
- memclrw(blocks2, inputBlockCount * sizeof(PCodeBlock *));
- memclrw(blocks3, factor * (inputBlockCount * sizeof(PCodeBlock *)));
-
- block = loop->preheader->nextBlock;
- for (i = 0; i < inputBlockCount; i++) {
- blocks[i] = block;
- block = block->nextBlock;
- }
-
- lastBlock = blocks[inputBlockCount - 1];
- for (i = 0; i < factor - 1; i++) {
- for (j = 0; j < inputBlockCount; j++) {
- blocks2[j] = insertnewpcblock(lastBlock, loop->loopWeight);
- blocks3[outputBlockCount++] = blocks2[j];
- lastBlock = blocks2[j];
- }
- if (label24) {
- pclabel(blocks2[0], label24);
- label24 = NULL;
- }
-
- for (j = 0; j < inputBlockCount; j++) {
- for (instr = blocks[j]->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->flags & fIsBranch) {
- PCodeArg *op;
- int opID;
- instrCopy = copypcode(instr);
- op = NULL;
- for (opID = 0; opID < instr->argCount; opID++) {
- if (instr->args[opID].kind == PCOp_LABEL) {
- op = &instr->args[opID];
- break;
- }
- }
-
- if (op) {
- if (op->data.label.label->block == loop->body) {
- if (!label24)
- label24 = makepclabel();
- instrCopy->args[opID].data.label.label = label24;
- } else {
- for (k = 0; k < inputBlockCount; k++) {
- if (op->data.label.label->block == blocks[k]) {
- instrCopy->args[opID].data.label.label = blocks2[k]->labels;
- break;
- }
- }
- }
- }
-
- appendpcode(blocks2[j], instrCopy);
- if (op)
- pcbranch(blocks2[j], instrCopy->args[opID].data.label.label);
- } else {
- appendpcode(blocks2[j], copypcode(instr));
- }
- }
- }
-
- firstInstr = loop->body->firstPCode;
- CError_ASSERT(762, firstInstr != NULL);
- if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI)
- CError_FATAL(764);
-
- for (instr = firstInstr->nextPCode; instr && !(instr->flags & fIsBranch); instr = instr->nextPCode)
- appendpcode(blocks2[inputBlockCount - 1], copypcode(instr));
-
- for (j = 0; j < inputBlockCount; j++) {
- for (link = blocks[j]->successors; link; link = link->nextLink) {
- if (link->block == blocks[j]->nextBlock)
- break;
- }
-
- if (!link) {
- for (link = blocks2[j]->successors, prev = NULL; link; link = link->nextLink) {
- if (link->block == blocks2[j]->nextBlock) {
- if (prev)
- prev->nextLink = link->nextLink;
- else
- blocks2[j]->successors = link->nextLink;
- } else {
- prev = link;
- }
- }
-
- for (link = blocks2[j]->nextBlock->predecessors, prev = NULL; link; link = link->nextLink) {
- if (link->block == blocks2[j]) {
- if (prev)
- prev->nextLink = link->nextLink;
- else
- blocks2[j]->nextBlock->predecessors = link->nextLink;
- } else {
- prev = link;
- }
- }
- }
- }
- }
-
- if (label24)
- pclabel(loop->body, label24);
-
- for (i = 0; i < inputBlockCount; i++) {
- for (instr = blocks[i]->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->flags & fIsBranch) {
- PCodeArg *op;
- int opID;
- op = NULL;
- for (opID = 0; opID < instr->argCount; opID++) {
- if (instr->args[opID].kind == PCOp_LABEL) {
- op = &instr->args[opID];
- break;
- }
- }
-
- if (op && op->data.label.label->block == loop->body) {
- instr->args[opID].data.label.label = blocks3[0]->labels;
-
- for (link = blocks[i]->successors, prev = NULL; link; link = link->nextLink) {
- if (link->block == loop->body) {
- if (prev)
- prev->nextLink = link->nextLink;
- else
- blocks[i]->successors = link->nextLink;
- } else {
- prev = link;
- }
- }
-
- for (link = loop->body->predecessors, prev = NULL; link; link = link->nextLink) {
- if (link->block == blocks[i]) {
- if (prev)
- prev->nextLink = link->nextLink;
- else
- loop->body->predecessors = link->nextLink;
- } else {
- prev = link;
- }
- }
-
- link = blocks[i]->successors;
- while (link && link->block != blocks3[0])
- link = link->nextLink;
-
- if (!link) {
- pcbranch(blocks[i], op->data.label.label);
- pccomputepredecessors1(blocks[i]);
- }
- }
- }
- }
- }
-
- for (i = 0; i < outputBlockCount; i++)
- pccomputepredecessors1(blocks3[i]);
-
- loop->iterationCount /= factor;
-}
-
-static void unrollunknownBDNZ(Loop *loop) {
- int factor; // r29
- PCodeBlock *preheader; // r17
- PCodeBlock *blockA; // r23
- PCodeBlock *postheader; // r22
- PCodeBlock *newblock1; // r26
- PCodeBlock *newblock2; // r31
- PCodeBlock *newblock3; // r19
- PCodeBlock *newblock4; // r20
- PCodeBlock *newblock5; // r24
- PCode *mtctr; // r21
- int mtctr_reg; // r27
- PCode *instr28; // r28
- PCode *instr6; // r6
- PCodeBlock *block;
- PCode *instr;
- PCodeArg *op;
- int i;
- int val;
- short mtctr_shifted_reg; // r16
- short reg25; // r25
- PCLink *link;
-
- if (loop->bodySize < 4)
- return;
-
- factor = 128;
- while (factor > copts.unroll_factor_limit)
- factor >>= 1;
- while (factor > 1 && (loop->bodySize - 2) * factor > copts.unroll_instr_limit)
- factor >>= 1;
-
- if (factor < 2)
- return;
-
- preheader = loop->preheader;
- blockA = loop->body->nextBlock;
- postheader = preheader->nextBlock;
-
- newblock1 = insertnewpcblock(preheader, loop->loopWeight);
- newblock2 = insertnewpcblock(newblock1, loop->loopWeight);
- newblock3 = insertnewpcblock(newblock2, loop->loopWeight);
- newblock4 = insertnewpcblock(newblock3, loop->loopWeight);
- newblock5 = insertnewpcblock(newblock4, loop->loopWeight);
- addblocktoloop(loop, newblock1);
- addblocktoloop(loop, newblock2);
- addblocktoloop(loop, newblock3);
- addblocktoloop(loop, newblock4);
- addblocktoloop(loop, newblock5);
-
- for (instr = preheader->lastPCode; instr; instr = instr->prevPCode) {
- if (instr->op == PC_MTCTR) {
- mtctr = instr;
- mtctr_reg = instr->args[0].data.reg.reg;
- }
- }
-
- if (!mtctr)
- return;
-
- instr28 = NULL;
- for (block = postheader; block != loop->body; block = block->successors->block) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->op != PC_B) {
- appendpcode(newblock2, copypcode(instr));
- if (instr == loop->pc18)
- instr28 = newblock2->lastPCode;
- }
- }
- }
-
- if (!instr28) {
- appendpcode(newblock2, copypcode(loop->pc18));
- instr28 = newblock2->lastPCode;
- }
-
- instr6 = NULL;
- for (instr = newblock2->firstPCode; instr; instr = instr->nextPCode) {
- if (instr != instr28) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg == loop->pc18->args[0].data.reg.reg &&
- (op->data.reg.effect & (EffectRead | EffectWrite))
- ) {
- instr6 = instr;
- break;
- }
- op++;
- }
- }
- if (instr6)
- break;
- }
-
- if (!instr6) {
- deletepcode(instr28);
- deletepcode(loop->pc18);
- if (loop->footer)
- blockA = loop->footer;
- else
- blockA = insertnewpcblock(loop->body, loop->loopWeight);
- } else {
- instr28 = NULL;
- }
-
- for (i = 1; i < factor; i++) {
- for (block = postheader; block != loop->body; block = block->successors->block) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->op != PC_B)
- appendpcode(newblock2, copypcode(instr));
- }
- }
- }
-
- mtctr_shifted_reg = used_virtual_registers[RegClass_GPR]++;
- appendpcode(newblock1, makepcode(
- PC_RLWINM,
- mtctr_shifted_reg,
- mtctr_reg,
- 32 - ispowerof2(factor),
- ispowerof2(factor),
- 31));
-
- appendpcode(newblock1, makepcode(PC_CMPLI, 0, mtctr_shifted_reg, 0));
-
- if (instr28) {
- reg25 = used_virtual_registers[RegClass_GPR]++;
- if (loop->step == 1) {
- instr = makepcode(PC_MR, reg25, mtctr_reg);
- } else if (loop->step == -1) {
- instr = makepcode(PC_NEG, reg25, mtctr_reg);
- } else {
- val = ispowerof2(abs(loop->step));
- if (val > 0) {
- instr = makepcode(PC_RLWINM, reg25, mtctr_reg, val, 0, 31 - val);
- if (loop->step < 0) {
- appendpcode(newblock1, instr);
- instr = makepcode(PC_NEG, reg25, reg25);
- }
- } else {
- instr = makepcode(PC_MULLI, reg25, mtctr_reg, loop->step);
- }
- }
- appendpcode(newblock1, instr);
- }
-
- appendpcode(newblock1, makepcode(PC_MTCTR, mtctr_shifted_reg));
- appendpcode(newblock1, makepcode(PC_BT, 0, 2, newblock5->labels));
- pcbranch(newblock1, newblock5->labels);
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock1;
- link->nextLink = newblock5->predecessors;
- newblock5->predecessors = link;
-
- appendpcode(newblock3, makepcode(PC_BDNZ, newblock2->labels));
- pcbranch(newblock3, newblock2->labels);
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock3;
- link->nextLink = newblock2->predecessors;
- newblock2->predecessors = link;
-
- appendpcode(newblock4, makepcode(PC_ANDI, mtctr_reg, mtctr_reg, factor - 1));
- appendpcode(newblock4, makepcode(PC_BT, 0, 2, blockA->labels));
- pcbranch(newblock4, blockA->labels);
-
- link = lalloc(sizeof(PCLink));
- link->block = newblock4;
- link->nextLink = blockA->predecessors;
- blockA->predecessors = link;
-
- deletepcode(mtctr);
- appendpcode(newblock5, mtctr);
-
- if (instr28 && bitvectorgetbit(instr28->args[0].data.reg.reg, liveonexit)) {
- instr = makepcode(PC_ADD, instr28->args[0].data.reg.reg, instr28->args[0].data.reg.reg, reg25);
- if (blockA->firstPCode)
- insertpcodebefore(blockA->firstPCode, instr);
- else
- appendpcode(blockA, instr);
- }
-}
-
-static void deleteloop(Loop *loop) {
- PCodeBlock *body;
- PCodeBlock *preheader;
- PCodeBlock *nextblock;
- PCodeLabel *label;
- PCode *instr;
- PCLink **ptr;
- PCLink *link;
- PCodeBlock *block;
-
- body = loop->body;
- preheader = loop->preheader;
- nextblock = body->nextBlock;
- label = makepclabel();
-
- while (1) {
- instr = body->firstPCode;
- CError_ASSERT(1294, instr != NULL);
-
- if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
- break;
-
- deletepcode(instr);
- insertpcodebefore(loop->preheader->lastPCode, instr);
- loop->bodySize--;
- }
-
- pclabel(nextblock, label);
- preheader->lastPCode->args[0].data.label.label = label;
- preheader->successors->block = nextblock;
-
- ptr = &nextblock->predecessors;
- while ((link = *ptr)) {
- if (link->block == body) {
- link->block = preheader;
- break;
- }
- ptr = &link->nextLink;
- }
-
- block = pcbasicblocks;
- while ((nextblock = block->nextBlock)) {
- if (bitvectorgetbit(nextblock->blockIndex, loop->memberblocks))
- block->nextBlock = nextblock->nextBlock;
- else
- block = nextblock;
- }
-}
-
-static void deleteloopheader(Loop *loop) {
- PCLink *link;
- PCLink **ptr;
-
- ptr = &loop->body->successors;
- while ((link = *ptr)) {
- if (link->block == loop->body->lastPCode->args[2].data.label.label->block) {
- *ptr = link->nextLink;
- break;
- }
- ptr = &link->nextLink;
- }
-
- ptr = &loop->body->lastPCode->args[2].data.label.label->block->predecessors;
- while ((link = *ptr)) {
- if (link->block == loop->body) {
- *ptr = link->nextLink;
- break;
- }
- ptr = &link->nextLink;
- }
-
- deletepcode(loop->body->firstPCode);
- deletepcode(loop->body->lastPCode);
- optimizedloop_full_unroll = 1;
-}
-
-static void rewriteloopwithBDNZ(Loop *loop) {
- PCode *instr;
-
- if (!FITS_IN_SHORT(loop->iterationCount)) {
- instr = makepcode(PC_LIS, used_virtual_registers[RegClass_GPR]++, 0, HIGH_PART(loop->iterationCount));
- insertpcodebefore(loop->preheader->lastPCode, instr);
-
- if (loop->iterationCount != 0)
- insertpcodeafter(instr, makepcode(PC_ADDI, instr->args[0].data.reg.reg, instr->args[0].data.reg.reg, 0, LOW_PART(loop->iterationCount)));
- } else {
- instr = makepcode(PC_LI, used_virtual_registers[RegClass_GPR]++, loop->iterationCount);
- insertpcodebefore(loop->preheader->lastPCode, instr);
- }
-
- insertpcodebefore(loop->preheader->lastPCode, makepcode(PC_MTCTR, instr->args[0].data.reg.reg));
-
- instr = makepcode(PC_BDNZ, loop->body->lastPCode->args[2].data.label.label);
- deletepcode(loop->body->firstPCode);
- deletepcode(loop->body->lastPCode);
- appendpcode(loop->body, instr);
-
- for (loop = loop->parent; loop; loop = loop->parent)
- loop->x4E = 1;
-}
-
-static void rewriteunknownloopwithBDNZ(Loop *loop) {
- SInt32 value1; // r24
- SInt32 value2; // r30
- Opcode branchOpcode; // r19
- SInt32 absStep; // r28
- int branchCondition; // r20
- int counterReg; // r27
- int reg1; // r26
- int reg2; // r22
- unsigned char mode; // r23
- PCodeBlock *afterLoop; // r25
- PCode *addiInstr;
- PCode *instr;
- PCLink *link;
- PCLink **ptr;
-
- absStep = abs(loop->step);
- afterLoop = NULL;
-
- for (addiInstr = loop->body->lastPCode->prevPCode; addiInstr->op == PC_ADDI; addiInstr = loop->body->lastPCode->prevPCode) {
- deletepcode(addiInstr);
- if (loop->body->lastPCode->args[2].data.label.label->block->firstPCode)
- insertpcodebefore(loop->body->lastPCode->args[2].data.label.label->block->firstPCode, addiInstr);
- else
- appendpcode(loop->body->lastPCode->args[2].data.label.label->block, addiInstr);
-
- afterLoop = insertnewpcblock(loop->body, loop->loopWeight);
- appendpcode(afterLoop, copypcode(addiInstr));
- loop->footer = afterLoop;
- }
-
- if (loop->unknownCondition == ELESS) {
- branchOpcode = PC_BF;
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- branchCondition = 1; // GT
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1 - loop->lower;
- mode = 0;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- branchCondition = 0; // LT
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep - 1 + loop->upper;
- mode = 1;
- } else {
- branchCondition = 0; // LT
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1;
- mode = 2;
- }
- } else if (loop->unknownCondition == ELESSEQU) {
- branchOpcode = PC_BT;
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- branchCondition = 0; // LT
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - loop->lower;
- mode = 0;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- branchCondition = 1; // GT
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep + loop->upper;
- mode = 1;
- } else {
- branchCondition = 1; // GT
- value1 = 0;
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep;
- mode = 2;
- }
- } else if (loop->unknownCondition == EGREATER) {
- branchOpcode = PC_BF;
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- branchCondition = 0; // LT
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1 + loop->lower;
- mode = 1;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- branchCondition = 1; // GT
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep - 1 - loop->upper;
- mode = 0;
- } else {
- branchCondition = 1; // GT
- value1 = 0;
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1;
- mode = 3;
- }
- } else if (loop->unknownCondition == EGREATEREQU) {
- branchOpcode = PC_BT;
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- branchCondition = 1; // GT
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep + loop->lower;
- mode = 1;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- branchCondition = 0; // LT
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep - loop->upper;
- mode = 0;
- } else {
- branchCondition = 0; // LT
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep;
- mode = 3;
- }
- } else if (loop->unknownCondition == ENOTEQU) {
- branchOpcode = PC_BT;
- branchCondition = 2; // EQ
- if (loop->step > 0) {
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1 - loop->lower;
- mode = 0;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep - 1 + loop->upper;
- mode = 1;
- } else {
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1;
- mode = 2;
- }
- } else {
- if (loop->lowerType == LOOP_BOUND_CONSTANT) {
- value1 = loop->lower;
- reg1 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1 + loop->lower;
- mode = 1;
- } else if (loop->upperType == LOOP_BOUND_CONSTANT) {
- value1 = loop->upper;
- reg1 = addiInstr->args[1].data.reg.reg;
- value2 = absStep - 1 - loop->upper;
- mode = 0;
- } else {
- reg1 = addiInstr->args[1].data.reg.reg;
- reg2 = addiInstr->args[2].data.reg.reg;
- value2 = absStep - 1;
- mode = 3;
- }
- }
- }
-
- while (1) {
- instr = loop->body->firstPCode;
- CError_ASSERT(1857, instr);
-
- if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
- break;
-
- deletepcode(instr);
- insertpcodebefore(loop->preheader->lastPCode, instr);
- loop->bodySize--;
- }
-
- // build a value for mtctr
- counterReg = used_virtual_registers[RegClass_GPR]++;
-
- if (mode == 1) {
- if (value2 == 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_NEG, counterReg, reg1));
- } else if (FITS_IN_SHORT(value2)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBFIC, counterReg, reg1, value2));
- } else {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_LIS, counterReg, 0, HIGH_PART(value2)));
- if (value2 != 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, counterReg, 0, LOW_PART(value2)));
- }
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg1, counterReg));
- }
- } else if (mode == 0) {
- if (value2 == 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_MR, counterReg, reg1));
- } else if (FITS_IN_SHORT(value2)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, reg1, 0, value2));
- } else {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDIS, counterReg, reg1, 0, HIGH_PART(value2)));
- if (value2 != 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, counterReg, 0, LOW_PART(value2)));
- }
- }
- } else if (mode == 2) {
- if (value2 == 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg1, reg2));
- } else if (FITS_IN_SHORT(value2)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, reg2, 0, value2));
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg1, counterReg));
- } else {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDIS, counterReg, reg2, 0, HIGH_PART(value2)));
- if (value2 != 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, counterReg, 0, LOW_PART(value2)));
- }
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg1, counterReg));
- }
- } else {
- if (value2 == 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg2, reg1));
- } else {
- if (FITS_IN_SHORT(value2)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, reg1, 0, value2));
- } else {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDIS, counterReg, reg1, 0, HIGH_PART(value2)));
- if (value2 != 0) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_ADDI, counterReg, counterReg, 0, LOW_PART(value2)));
- }
- }
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_SUBF, counterReg, reg2, counterReg));
- }
- }
-
- if (absStep > 1) {
- unsigned char bits;
- if ((bits = ispowerof2(absStep))) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_RLWINM, counterReg, counterReg, 32 - bits, bits, 31));
- } else {
- int reg = used_virtual_registers[RegClass_GPR]++;
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_LI, reg, absStep));
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_DIVWU, counterReg, counterReg, reg));
- }
- }
-
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_MTCTR, counterReg));
-
- if (mode < 2) {
- if (addiInstr->op == PC_CMPL || addiInstr->op == PC_CMPLI) {
- if (FITS_IN_USHORT(value1)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMPLI, 0, reg1, value1));
- } else {
- PCode *tmp;
- tmp = makepcode(PC_LIS, used_virtual_registers[RegClass_GPR]++, 0, HIGH_PART(value1));
- insertpcodebefore(loop->preheader->lastPCode, tmp);
-
- if (loop->iterationCount != 0)
- insertpcodeafter(tmp,
- makepcode(PC_ADDI,
- tmp->args[0].data.reg.reg,
- tmp->args[0].data.reg.reg,
- 0, LOW_PART(value1)));
-
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMPL, 0, reg1, tmp->args[0].data.reg.reg));
- }
- } else {
- if (FITS_IN_SHORT(value1)) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMPI, 0, reg1, value1));
- } else {
- PCode *tmp;
- tmp = makepcode(PC_LIS, used_virtual_registers[RegClass_GPR]++, 0, HIGH_PART(value1));
- insertpcodebefore(loop->preheader->lastPCode, tmp);
-
- if (loop->iterationCount != 0)
- insertpcodeafter(tmp,
- makepcode(PC_ADDI,
- tmp->args[0].data.reg.reg,
- tmp->args[0].data.reg.reg,
- 0, LOW_PART(value1)));
-
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMP, 0, reg1, tmp->args[0].data.reg.reg));
- }
- }
- } else {
- if (addiInstr->op == PC_CMPL || addiInstr->op == PC_CMPLI) {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMPL, 0, reg1, reg2));
- } else {
- insertpcodebefore(loop->preheader->lastPCode,
- makepcode(PC_CMP, 0, reg1, reg2));
- }
- }
-
- if (!afterLoop)
- afterLoop = loop->body->nextBlock;
-
- instr = makepcode(branchOpcode, 0, branchCondition, afterLoop->labels);
- deletepcode(loop->preheader->lastPCode);
- appendpcode(loop->preheader, instr);
-
- instr = makepcode(PC_BDNZ, loop->body->lastPCode->args[2].data.label.label);
- deletepcode(loop->body->firstPCode);
- deletepcode(loop->body->lastPCode);
- appendpcode(loop->body, instr);
-
- loop->preheader->successors = NULL;
- ptr = &loop->body->predecessors;
- while ((link = *ptr)) {
- if (link->block == loop->preheader) {
- *ptr = link->nextLink;
- break;
- }
- ptr = &link->nextLink;
- }
-
- link = lalloc(sizeof(PCLink));
- link->block = loop->preheader->nextBlock;
- link->nextLink = loop->preheader->successors;
- loop->preheader->successors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = loop->preheader;
- link->nextLink = loop->preheader->nextBlock->predecessors;
- loop->preheader->nextBlock->predecessors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = afterLoop;
- link->nextLink = loop->preheader->successors;
- loop->preheader->successors = link;
-
- link = lalloc(sizeof(PCLink));
- link->block = loop->preheader;
- link->nextLink = afterLoop->predecessors;
- afterLoop->predecessors = link;
-
- for (loop = loop->parent; loop; loop = loop->parent)
- loop->x4E = 1;
-}
-
-static void optimizeloop(Loop *loop) {
- computeliveonexit(loop);
-
- if (loop->x53 || loop->x54)
- insertupdateinstructions(loop);
-
- if (loop->isKnownCountingLoop) {
- if (loop->iterationCount > 0) {
- skiplooptest(loop);
- if (!copts.optimizesize && !loop->x4D && !loop->x57) {
- if (loop->x4F)
- unrollloop(loop);
- else if (!loop->x4E)
- unrollloopconditional(loop);
- }
- }
-
- if (loop->iterationCount != 0) {
- if (loop->iterationCount == 1)
- deleteloopheader(loop);
- else if (!loop->x4E && !loop->x4D)
- rewriteloopwithBDNZ(loop);
- }
-
- optimizedloops = 1;
- } else if (loop->isUnknownCountingLoop && !loop->x4E && !loop->x4D) {
- rewriteunknownloopwithBDNZ(loop);
- if (copts.unroll_speculative && !copts.optimizesize) {
- if (loop->x4F && !loop->x57 && !loop->x52)
- unrollunknownBDNZ(loop);
- }
- optimizedloops = 1;
- }
-
- eliminateinductionvariables(loop);
-}
-
-typedef struct LocalArray {
- struct LocalArray *next;
- Object *object;
- unsigned int invalid:1;
- unsigned int isFloat:1;
- unsigned int isSigned:1;
- SInt32 elementSize;
- SInt32 arraySize;
- SInt32 elementCount;
- int totalUses;
- int elements[1];
-} LocalArray;
-
-static LocalArray *scanforlocalarrays(void) {
- SInt32 elementCount;
- LocalArray *head;
- LocalArray *array;
- ObjectList *list;
- int i;
- SInt32 arraySize;
- SInt32 elementSize;
-
- head = NULL;
-
- for (list = locals; list; list = list->next) {
- if (
- list->object &&
- !(IS_TYPE_POINTER(list->object->type) ? (TPTR_QUAL(list->object->type) & Q_VOLATILE) : (list->object->qual & Q_VOLATILE)) &&
- list->object->type &&
- IS_TYPE_ARRAY(list->object->type) &&
- TPTR_TARGET(list->object->type) &&
- TPTR_TARGET(list->object->type)->type < TYPESTRUCT
- ) {
- arraySize = list->object->type->size;
- elementSize = TPTR_TARGET(list->object->type)->size;
- elementCount = arraySize / elementSize;
- if (elementCount > 0 && elementCount <= 8) {
- array = oalloc(sizeof(int) * (elementCount - 1) + sizeof(LocalArray));
- array->next = head;
- head = array;
-
- array->object = list->object;
- array->elementSize = elementSize;
- array->arraySize = arraySize;
- array->elementCount = elementCount;
- array->totalUses = 0;
- array->isSigned = 1;
- array->isFloat = IS_TYPE_FLOAT(TPTR_TARGET(list->object->type));
- array->invalid = 0;
- array->isSigned = 1;
- if (!array->isFloat && is_unsigned(TPTR_TARGET(list->object->type)))
- array->isSigned = 0;
-
- for (i = 0; i < elementCount; i++) {
- array->elements[i] = 0;
- }
- }
- }
- }
-
- return head;
-}
-
-static LocalArray *lookup_array_object(LocalArray *arrays, Object *object) {
- while (arrays) {
- if (arrays->object == object)
- return arrays;
- arrays = arrays->next;
- }
- return NULL;
-}
-
-void changearraytoregisters(void) {
- LocalArray *arrays;
- PCodeBlock *block;
- PCode *instr;
- int i;
- PCodeArg *op;
- LocalArray **ptr;
- LocalArray *array;
- int intCounter;
- int floatCounter;
- int reg;
- int reg2;
- PCode *newInstr;
-
- arrays = NULL;
- if ((arrays = scanforlocalarrays())) {
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (!(instr->flags & fIsBranch) && instr->argCount) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_MEMORY &&
- (PCOpMemoryArg) op->arg == PCOpMemory1 &&
- (array = lookup_array_object(arrays, op->data.mem.obj)) &&
- !array->invalid
- ) {
- if (
- (instr->flags & (fIsRead | fIsWrite)) &&
- (op->data.mem.offset % array->elementSize) == 0 &&
- op->data.mem.offset < array->arraySize
- ) {
- switch (instr->op) {
- case PC_LBZ:
- case PC_STB:
- if (array->elementSize != 1)
- array->invalid = 1;
- break;
- case PC_LHZ:
- case PC_LHA:
- case PC_STH:
- if (array->elementSize != 2)
- array->invalid = 1;
- break;
- case PC_LWZ:
- case PC_STW:
- if (array->elementSize != 4)
- array->invalid = 1;
- break;
- case PC_LFD:
- case PC_STFD:
- if (array->elementSize != 8)
- array->invalid = 1;
- break;
- default:
- array->invalid = 1;
- break;
- }
-
- if (!array->invalid)
- array->elements[op->data.mem.offset / array->elementSize]++;
- } else {
- array->invalid = 1;
- }
- }
- op++;
- }
- }
- }
- }
-
- intCounter = 0;
- floatCounter = 0;
- ptr = &arrays;
- array = *ptr;
- while (array) {
- if (array->invalid) {
- *ptr = array = array->next;
- continue;
- }
-
- if (array->isFloat)
- floatCounter += array->elementCount;
- if (!array->isFloat)
- intCounter += array->elementCount;
-
- for (i = 0; i < array->elementCount; i++)
- array->totalUses += array->elements[i];
-
- array = array->next;
- }
-
- if (arrays) {
- while (intCounter > 8) {
- LocalArray *best;
- int score;
- score = 0;
- best = NULL;
- for (array = arrays; array; array = array->next) {
- if (!array->isFloat) {
- if (best) {
- if (array->totalUses < score) {
- score = array->totalUses;
- best = array;
- }
- } else {
- best = array;
- score = array->totalUses;
- }
- }
- }
-
- if (!best)
- break;
-
- if (best == arrays) {
- arrays = best->next;
- } else {
- for (array = arrays; array; array = array->next) {
- if (array->next == best) {
- array->next = best->next;
- break;
- }
- }
- }
-
- intCounter -= best->elementCount;
- }
-
- while (floatCounter > 8) {
- LocalArray *best;
- int score;
- score = 0;
- best = NULL;
- for (array = arrays; array; array = array->next) {
- if (array->isFloat) {
- if (best) {
- if (array->totalUses < score) {
- score = array->totalUses;
- best = array;
- }
- } else {
- best = array;
- score = array->totalUses;
- }
- }
- }
-
- if (!best)
- break;
-
- if (best == arrays) {
- arrays = best->next;
- } else {
- for (array = arrays; array; array = array->next) {
- if (array->next == best) {
- array->next = best->next;
- break;
- }
- }
- }
-
- floatCounter -= best->elementCount;
- }
-
- CError_ASSERT(2394, intCounter <= 8 && floatCounter <= 8);
-
- if (!arrays)
- return;
-
- optimizedloop_trans_regs = 1;
-
- for (array = arrays; array; array = array->next) {
- for (i = 0; i < array->elementCount; i++) {
- if (array->isFloat)
- array->elements[i] = used_virtual_registers[RegClass_FPR]++;
- else
- array->elements[i] = used_virtual_registers[RegClass_GPR]++;
- }
- }
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (
- !(instr->flags & fIsBranch) &&
- instr->argCount &&
- (instr->flags & (fIsRead | fIsWrite)) &&
- instr->args[2].kind == PCOp_MEMORY &&
- (PCOpMemoryArg) instr->args[2].arg == PCOpMemory1 &&
- (array = lookup_array_object(arrays, instr->args[2].data.mem.obj)) &&
- !(array->invalid)
- )
- {
- reg2 = instr->args[0].data.reg.reg;
- reg = array->elements[instr->args[2].data.mem.offset / array->elementSize];
- newInstr = NULL;
- switch (instr->op) {
- case PC_LBZ:
- if (array->isSigned)
- newInstr = makepcode(PC_MR, reg2, reg);
- else
- newInstr = makepcode(PC_RLWINM, reg2, reg, 0, 24, 31);
- break;
- case PC_STB:
- if (array->isSigned)
- newInstr = makepcode(PC_EXTSB, reg, reg2);
- else
- newInstr = makepcode(PC_RLWINM, reg, reg2, 0, 24, 31);
- break;
- case PC_LHZ:
- newInstr = makepcode(PC_RLWINM, reg2, reg, 0, 16, 31);
- break;
- case PC_LHA:
- newInstr = makepcode(PC_EXTSH, reg2, reg);
- break;
- case PC_STH:
- if (array->isSigned)
- newInstr = makepcode(PC_EXTSH, reg, reg2);
- else
- newInstr = makepcode(PC_RLWINM, reg, reg2, 0, 16, 31);
- break;
- case PC_LWZ:
- newInstr = makepcode(PC_MR, reg2, reg);
- break;
- case PC_STW:
- newInstr = makepcode(PC_MR, reg, reg2);
- break;
- case PC_LFD:
- newInstr = makepcode(PC_FMR, reg2, reg);
- break;
- case PC_STFD:
- newInstr = makepcode(PC_FMR, reg, reg2);
- break;
- default:
- CError_FATAL(2494);
- break;
- }
-
- if (newInstr) {
- insertpcodebefore(instr, newInstr);
- deletepcode(instr);
- instr = newInstr;
- }
- }
- }
- }
- }
- }
-
- freeoheap();
-}
-
-static void optimizenestedloops(Loop *loop) {
- while (loop) {
- if (loop->children)
- optimizenestedloops(loop->children);
- optimizeloop(loop);
- loop = loop->nextSibling;
- }
-}
-
-void optimizeloops(void) {
- optimizedloops = 0;
- optimizedloop_full_unroll = 0;
- optimizedloop_trans_regs = 0;
- if (loopsinflowgraph) {
- computeusedefchains(0);
- last_virtual_GPR = used_virtual_registers[RegClass_GPR];
- liveonexit = oalloc(4 * ((used_virtual_registers[RegClass_GPR] + 31) >> 5));
- inductionvariables = oalloc(4 * ((last_virtual_GPR + 31) >> 5));
- optimizenestedloops(loopsinflowgraph);
- freeoheap();
- }
-}
-
diff --git a/compiler_and_linker/unsorted/MachineSimulation601.c b/compiler_and_linker/unsorted/MachineSimulation601.c
deleted file mode 100644
index 2d54678..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation601.c
+++ /dev/null
@@ -1,552 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://stuff.mit.edu/afs/sipb/contrib/doc/specs/ic/cpu/powerpc/mpc601.pdf
-// https://www.nxp.com/docs/en/user-guide/MPC601UMAD.pdf
-
-typedef enum Stage {
- IU, // Integer Unit
- FD, // FP Decode
- FPM, // FP Multiply
- FPA, // FP Add
- FWA, // FP Arithmetic Writeback
- BPU, // Branch Processing Unit
- NumStages,
- Serialize, // special form for instructions that use IU but are serialised
- Unsupported // instructions not supported by this processor
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[4];
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 1, // PC_B
- BPU, 0, 0, 0, 0, 1, // PC_BL
- BPU, 0, 0, 0, 0, 1, // PC_BC
- BPU, 0, 0, 0, 0, 1, // PC_BCLR
- BPU, 0, 0, 0, 0, 1, // PC_BCCTR
- BPU, 0, 0, 0, 0, 1, // PC_BT
- BPU, 0, 0, 0, 0, 1, // PC_BTLR
- BPU, 0, 0, 0, 0, 1, // PC_BTCTR
- BPU, 0, 0, 0, 0, 1, // PC_BF
- BPU, 0, 0, 0, 0, 1, // PC_BFLR
- BPU, 0, 0, 0, 0, 1, // PC_BFCTR
- BPU, 0, 0, 0, 0, 1, // PC_BDNZ
- BPU, 0, 0, 0, 0, 1, // PC_BDNZT
- BPU, 0, 0, 0, 0, 1, // PC_BDNZF
- BPU, 0, 0, 0, 0, 1, // PC_BDZ
- BPU, 0, 0, 0, 0, 1, // PC_BDZT
- BPU, 0, 0, 0, 0, 1, // PC_BDZF
- BPU, 0, 0, 0, 0, 1, // PC_BLR
- BPU, 0, 0, 0, 0, 1, // PC_BCTR
- BPU, 0, 0, 0, 0, 1, // PC_BCTRL
- BPU, 0, 0, 0, 0, 1, // PC_BLRL
- IU, 2, 1, 0, 0, 0, // PC_LBZ
- IU, 2, 1, 0, 0, 0, // PC_LBZU
- IU, 2, 1, 0, 0, 0, // PC_LBZX
- IU, 2, 1, 0, 0, 0, // PC_LBZUX
- IU, 2, 1, 0, 0, 0, // PC_LHZ
- IU, 2, 1, 0, 0, 0, // PC_LHZU
- IU, 2, 1, 0, 0, 0, // PC_LHZX
- IU, 2, 1, 0, 0, 0, // PC_LHZUX
- IU, 2, 1, 0, 0, 0, // PC_LHA
- IU, 2, 1, 0, 0, 0, // PC_LHAU
- IU, 2, 1, 0, 0, 0, // PC_LHAX
- IU, 2, 1, 0, 0, 0, // PC_LHAUX
- IU, 2, 1, 0, 0, 0, // PC_LHBRX
- IU, 2, 1, 0, 0, 0, // PC_LWZ
- IU, 2, 1, 0, 0, 0, // PC_LWZU
- IU, 2, 1, 0, 0, 0, // PC_LWZX
- IU, 2, 1, 0, 0, 0, // PC_LWZUX
- IU, 2, 1, 0, 0, 0, // PC_LWBRX
- IU, 1, 1, 0, 0, 0, // PC_LMW
- IU, 1, 1, 0, 0, 0, // PC_STB
- IU, 1, 1, 0, 0, 0, // PC_STBU
- IU, 1, 1, 0, 0, 0, // PC_STBX
- IU, 1, 1, 0, 0, 0, // PC_STBUX
- IU, 1, 1, 0, 0, 0, // PC_STH
- IU, 1, 1, 0, 0, 0, // PC_STHU
- IU, 1, 1, 0, 0, 0, // PC_STHX
- IU, 1, 1, 0, 0, 0, // PC_STHUX
- IU, 1, 1, 0, 0, 0, // PC_STHBRX
- IU, 1, 1, 0, 0, 0, // PC_STW
- IU, 1, 1, 0, 0, 0, // PC_STWU
- IU, 1, 1, 0, 0, 0, // PC_STWX
- IU, 1, 1, 0, 0, 0, // PC_STWUX
- IU, 1, 1, 0, 0, 0, // PC_STWBRX
- IU, 1, 1, 0, 0, 0, // PC_STMW
- IU, 2, 1, 0, 0, 0, // PC_DCBF
- IU, 2, 1, 0, 0, 0, // PC_DCBST
- IU, 2, 1, 0, 0, 0, // PC_DCBT
- IU, 2, 1, 0, 0, 0, // PC_DCBTST
- IU, 2, 1, 0, 0, 0, // PC_DCBZ
- IU, 1, 1, 0, 0, 0, // PC_ADD
- IU, 1, 1, 0, 0, 0, // PC_ADDC
- IU, 1, 1, 0, 0, 0, // PC_ADDE
- IU, 1, 1, 0, 0, 0, // PC_ADDI
- IU, 1, 1, 0, 0, 0, // PC_ADDIC
- IU, 1, 1, 0, 0, 0, // PC_ADDICR
- IU, 1, 1, 0, 0, 0, // PC_ADDIS
- IU, 1, 1, 0, 0, 0, // PC_ADDME
- IU, 1, 1, 0, 0, 0, // PC_ADDZE
- IU, 36, 36, 0, 0, 0, // PC_DIVW
- IU, 36, 36, 0, 0, 0, // PC_DIVWU
- IU, 5, 5, 0, 0, 0, // PC_MULHW
- IU, 5, 5, 0, 0, 0, // PC_MULHWU
- IU, 5, 5, 0, 0, 0, // PC_MULLI
- IU, 5, 5, 0, 0, 0, // PC_MULLW
- IU, 1, 1, 0, 0, 0, // PC_NEG
- IU, 1, 1, 0, 0, 0, // PC_SUBF
- IU, 1, 1, 0, 0, 0, // PC_SUBFC
- IU, 1, 1, 0, 0, 0, // PC_SUBFE
- IU, 1, 1, 0, 0, 0, // PC_SUBFIC
- IU, 1, 1, 0, 0, 0, // PC_SUBFME
- IU, 1, 1, 0, 0, 0, // PC_SUBFZE
- IU, 3, 1, 0, 0, 0, // PC_CMPI
- IU, 3, 1, 0, 0, 0, // PC_CMP
- IU, 3, 1, 0, 0, 0, // PC_CMPLI
- IU, 3, 1, 0, 0, 0, // PC_CMPL
- IU, 1, 1, 0, 0, 0, // PC_ANDI
- IU, 1, 1, 0, 0, 0, // PC_ANDIS
- IU, 1, 1, 0, 0, 0, // PC_ORI
- IU, 1, 1, 0, 0, 0, // PC_ORIS
- IU, 1, 1, 0, 0, 0, // PC_XORI
- IU, 1, 1, 0, 0, 0, // PC_XORIS
- IU, 1, 1, 0, 0, 0, // PC_AND
- IU, 1, 1, 0, 0, 0, // PC_OR
- IU, 1, 1, 0, 0, 0, // PC_XOR
- IU, 1, 1, 0, 0, 0, // PC_NAND
- IU, 1, 1, 0, 0, 0, // PC_NOR
- IU, 1, 1, 0, 0, 0, // PC_EQV
- IU, 1, 1, 0, 0, 0, // PC_ANDC
- IU, 1, 1, 0, 0, 0, // PC_ORC
- IU, 1, 1, 0, 0, 0, // PC_EXTSB
- IU, 1, 1, 0, 0, 0, // PC_EXTSH
- IU, 1, 1, 0, 0, 0, // PC_CNTLZW
- IU, 1, 1, 0, 0, 0, // PC_RLWINM
- IU, 1, 1, 0, 0, 0, // PC_RLWNM
- IU, 1, 1, 0, 0, 0, // PC_RLWIMI
- IU, 1, 1, 0, 0, 0, // PC_SLW
- IU, 1, 1, 0, 0, 0, // PC_SRW
- IU, 1, 1, 0, 0, 0, // PC_SRAWI
- IU, 1, 1, 0, 0, 0, // PC_SRAW
- IU, 1, 1, 0, 0, 0, // PC_CRAND
- IU, 1, 1, 0, 0, 0, // PC_CRANDC
- IU, 1, 1, 0, 0, 0, // PC_CREQV
- IU, 1, 1, 0, 0, 0, // PC_CRNAND
- IU, 1, 1, 0, 0, 0, // PC_CRNOR
- IU, 1, 1, 0, 0, 0, // PC_CROR
- IU, 1, 1, 0, 0, 0, // PC_CRORC
- IU, 1, 1, 0, 0, 0, // PC_CRXOR
- IU, 1, 1, 0, 0, 0, // PC_MCRF
- IU, 4, 1, 0, 0, 0, // PC_MTXER
- IU, 4, 1, 0, 0, 0, // PC_MTCTR
- IU, 4, 1, 0, 0, 0, // PC_MTLR
- IU, 2, 1, 0, 0, 0, // PC_MTCRF
- IU, 1, 0, 0, 0, 0, // PC_MTMSR
- IU, 1, 0, 0, 0, 0, // PC_MTSPR
- IU, 1, 0, 0, 0, 0, // PC_MFMSR
- IU, 1, 0, 0, 0, 0, // PC_MFSPR
- IU, 1, 1, 0, 0, 0, // PC_MFXER
- IU, 1, 1, 0, 0, 0, // PC_MFCTR
- IU, 1, 1, 0, 0, 0, // PC_MFLR
- IU, 1, 1, 0, 0, 0, // PC_MFCR
- FD, 4, 1, 1, 1, 1, // PC_MFFS
- FD, 4, 1, 1, 1, 1, // PC_MTFSF
- Serialize, 1, 1, 0, 0, 1, // PC_EIEIO
- Serialize, 1, 1, 0, 0, 1, // PC_ISYNC
- Serialize, 1, 1, 0, 0, 1, // PC_SYNC
- Serialize, 0, 0, 0, 0, 1, // PC_RFI
- IU, 1, 1, 0, 0, 0, // PC_LI
- IU, 1, 1, 0, 0, 0, // PC_LIS
- IU, 1, 1, 0, 0, 0, // PC_MR
- IU, 1, 1, 0, 0, 0, // PC_NOP
- IU, 1, 1, 0, 0, 0, // PC_NOT
- IU, 3, 1, 0, 0, 0, // PC_LFS
- IU, 3, 1, 0, 0, 0, // PC_LFSU
- IU, 3, 1, 0, 0, 0, // PC_LFSX
- IU, 3, 1, 0, 0, 0, // PC_LFSUX
- IU, 3, 1, 0, 0, 0, // PC_LFD
- IU, 3, 1, 0, 0, 0, // PC_LFDU
- IU, 3, 1, 0, 0, 0, // PC_LFDX
- IU, 3, 1, 0, 0, 0, // PC_LFDUX
- IU, 1, 1, 0, 0, 0, // PC_STFS
- IU, 1, 1, 0, 0, 0, // PC_STFSU
- IU, 1, 1, 0, 0, 0, // PC_STFSX
- IU, 1, 1, 0, 0, 0, // PC_STFSUX
- IU, 1, 1, 0, 0, 0, // PC_STFD
- IU, 1, 1, 0, 0, 0, // PC_STFDU
- IU, 1, 1, 0, 0, 0, // PC_STFDX
- IU, 1, 1, 0, 0, 0, // PC_STFDUX
- FD, 4, 1, 1, 1, 1, // PC_FMR
- FD, 4, 1, 1, 1, 1, // PC_FABS
- FD, 4, 1, 1, 1, 1, // PC_FNEG
- FD, 4, 1, 1, 1, 1, // PC_FNABS
- FD, 4, 1, 1, 1, 1, // PC_FADD
- FD, 4, 1, 1, 1, 1, // PC_FADDS
- FD, 4, 1, 1, 1, 1, // PC_FSUB
- FD, 4, 1, 1, 1, 1, // PC_FSUBS
- FD, 5, 1, 1, 2, 1, // PC_FMUL
- FD, 4, 1, 1, 1, 1, // PC_FMULS
- FD, 31, 1, 1, 28, 1, // PC_FDIV
- FD, 17, 1, 1, 14, 1, // PC_FDIVS
- FD, 5, 1, 1, 2, 1, // PC_FMADD
- FD, 4, 1, 1, 1, 1, // PC_FMADDS
- FD, 5, 1, 1, 2, 1, // PC_FMSUB
- FD, 4, 1, 1, 1, 1, // PC_FMSUBS
- FD, 5, 1, 1, 2, 1, // PC_FNMADD
- FD, 4, 1, 1, 1, 1, // PC_FNMADDS
- FD, 5, 1, 1, 2, 1, // PC_FNMSUB
- FD, 4, 1, 1, 1, 1, // PC_FNMSUBS
- FD, 4, 1, 1, 1, 1, // PC_FRES
- FD, 4, 1, 1, 1, 1, // PC_FRSQRTE
- FD, 4, 1, 1, 1, 1, // PC_FSEL
- FD, 4, 1, 1, 1, 1, // PC_FRSP
- FD, 4, 1, 1, 1, 1, // PC_FCTIW
- FD, 4, 1, 1, 1, 1, // PC_FCTIWZ
- FD, 6, 1, 1, 1, 1, // PC_FCMPU
- FD, 6, 1, 1, 1, 1, // PC_FCMPO
- IU, 0, 0, 0, 0, 0, // PC_LWARX
- IU, 0, 0, 0, 0, 0, // PC_LSWI
- IU, 0, 0, 0, 0, 0, // PC_LSWX
- IU, 0, 0, 0, 0, 0, // PC_STFIWX
- IU, 0, 0, 0, 0, 0, // PC_STSWI
- IU, 0, 0, 0, 0, 0, // PC_STSWX
- IU, 0, 0, 0, 0, 0, // PC_STWCX
- IU, 0, 0, 0, 0, 0, // PC_ECIWX
- IU, 0, 0, 0, 0, 0, // PC_ECOWX
- IU, 0, 0, 0, 0, 0, // PC_DCBI
- IU, 0, 0, 0, 0, 0, // PC_ICBI
- IU, 0, 0, 0, 0, 0, // PC_MCRFS
- IU, 0, 0, 0, 0, 0, // PC_MCRXR
- IU, 0, 0, 0, 0, 0, // PC_MFTB
- IU, 0, 0, 0, 0, 0, // PC_MFSR
- IU, 0, 0, 0, 0, 0, // PC_MTSR
- IU, 0, 0, 0, 0, 0, // PC_MFSRIN
- IU, 0, 0, 0, 0, 0, // PC_MTSRIN
- IU, 0, 0, 0, 0, 0, // PC_MTFSB0
- IU, 0, 0, 0, 0, 0, // PC_MTFSB1
- IU, 0, 0, 0, 0, 0, // PC_MTFSFI
- Serialize, 0, 0, 0, 0, 0, // PC_SC
- IU, 0, 0, 0, 0, 0, // PC_FSQRT
- IU, 0, 0, 0, 0, 0, // PC_FSQRTS
- IU, 0, 0, 0, 0, 0, // PC_TLBIA
- IU, 0, 0, 0, 0, 0, // PC_TLBIE
- IU, 0, 0, 0, 0, 0, // PC_TLBLD
- IU, 0, 0, 0, 0, 0, // PC_TLBLI
- IU, 0, 0, 0, 0, 0, // PC_TLBSYNC
- Serialize, 0, 0, 0, 0, 0, // PC_TW
- Serialize, 0, 0, 0, 0, 0, // PC_TRAP
- Serialize, 0, 0, 0, 0, 0, // PC_TWI
- Serialize, 0, 0, 0, 0, 0, // PC_OPWORD
- IU, 0, 0, 0, 0, 0, // PC_MFROM
- IU, 0, 0, 0, 0, 0, // PC_DSA
- IU, 0, 0, 0, 0, 0, // PC_ESA
- IU, 0, 0, 0, 0, 0, // PC_DCCCI
- IU, 0, 0, 0, 0, 0, // PC_DCREAD
- IU, 0, 0, 0, 0, 0, // PC_ICBT
- IU, 0, 0, 0, 0, 0, // PC_ICCCI
- IU, 0, 0, 0, 0, 0, // PC_ICREAD
- IU, 0, 0, 0, 0, 0, // PC_RFCI
- IU, 0, 0, 0, 0, 0, // PC_TLBRE
- IU, 0, 0, 0, 0, 0, // PC_TLBSX
- IU, 0, 0, 0, 0, 0, // PC_TLBWE
- IU, 0, 0, 0, 0, 0, // PC_WRTEE
- IU, 0, 0, 0, 0, 0, // PC_WRTEEI
- IU, 0, 0, 0, 0, 0, // PC_MFDCR
- IU, 0, 0, 0, 0, 0, // PC_MTDCR
- Unsupported, 0, 0, 0, 0, 0, // PC_DCBA
- Unsupported, 0, 0, 0, 0, 0, // PC_DSS
- Unsupported, 0, 0, 0, 0, 0, // PC_DSSALL
- Unsupported, 0, 0, 0, 0, 0, // PC_DST
- Unsupported, 0, 0, 0, 0, 0, // PC_DSTT
- Unsupported, 0, 0, 0, 0, 0, // PC_DSTST
- Unsupported, 0, 0, 0, 0, 0, // PC_DSTSTT
- Unsupported, 0, 0, 0, 0, 0, // PC_LVEBX
- Unsupported, 0, 0, 0, 0, 0, // PC_LVEHX
- Unsupported, 0, 0, 0, 0, 0, // PC_LVEWX
- Unsupported, 0, 0, 0, 0, 0, // PC_LVSL
- Unsupported, 0, 0, 0, 0, 0, // PC_LVSR
- Unsupported, 0, 0, 0, 0, 0, // PC_LVX
- Unsupported, 0, 0, 0, 0, 0, // PC_LVXL
- Unsupported, 0, 0, 0, 0, 0, // PC_STVEBX
- Unsupported, 0, 0, 0, 0, 0, // PC_STVEHX
- Unsupported, 0, 0, 0, 0, 0, // PC_STVEWX
- Unsupported, 0, 0, 0, 0, 0, // PC_STVX
- Unsupported, 0, 0, 0, 0, 0, // PC_STVXL
- Unsupported, 0, 0, 0, 0, 0, // PC_MFVSCR
- Unsupported, 0, 0, 0, 0, 0, // PC_MTVSCR
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDCUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDSBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDSHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDSWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUBM
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUHM
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUWM
- Unsupported, 0, 0, 0, 0, 0, // PC_VADDUWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VAND
- Unsupported, 0, 0, 0, 0, 0, // PC_VANDC
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSW
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VCFSX
- Unsupported, 0, 0, 0, 0, 0, // PC_VCFUX
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPBFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VCTSXS
- Unsupported, 0, 0, 0, 0, 0, // PC_VCTUXS
- Unsupported, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VLOGEFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINSW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMINUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLW
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULESB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULESH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULEUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULEUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULOSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULOSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULOUB
- Unsupported, 0, 0, 0, 0, 0, // PC_VMULOUH
- Unsupported, 0, 0, 0, 0, 0, // PC_VNOR
- Unsupported, 0, 0, 0, 0, 0, // PC_VOR
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKPX
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKSHSS
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKSHUS
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKSWSS
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKSWUS
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKUHUM
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKUHUS
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKUWUM
- Unsupported, 0, 0, 0, 0, 0, // PC_VPKUWUS
- Unsupported, 0, 0, 0, 0, 0, // PC_VREFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VRFIM
- Unsupported, 0, 0, 0, 0, 0, // PC_VRFIN
- Unsupported, 0, 0, 0, 0, 0, // PC_VRFIP
- Unsupported, 0, 0, 0, 0, 0, // PC_VRFIZ
- Unsupported, 0, 0, 0, 0, 0, // PC_VRLB
- Unsupported, 0, 0, 0, 0, 0, // PC_VRLH
- Unsupported, 0, 0, 0, 0, 0, // PC_VRLW
- Unsupported, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VSL
- Unsupported, 0, 0, 0, 0, 0, // PC_VSLB
- Unsupported, 0, 0, 0, 0, 0, // PC_VSLH
- Unsupported, 0, 0, 0, 0, 0, // PC_VSLO
- Unsupported, 0, 0, 0, 0, 0, // PC_VSLW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTB
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTH
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISB
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISH
- Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSR
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRAB
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRAH
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRAW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRB
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRH
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRO
- Unsupported, 0, 0, 0, 0, 0, // PC_VSRW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBCUW
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUBM
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUHM
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUWM
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUMSWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUFPMSWS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWASBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWASHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWAUBS
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHPX
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLPX
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLSB
- Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLSH
- Unsupported, 0, 0, 0, 0, 0, // PC_VXOR
- Unsupported, 0, 0, 0, 0, 0, // PC_VMADDFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- Unsupported, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- Unsupported, 0, 0, 0, 0, 0, // PC_VPERM
- Unsupported, 0, 0, 0, 0, 0, // PC_VSEL
- Unsupported, 0, 0, 0, 0, 0, // PC_VSLDOI
- Unsupported, 0, 0, 0, 0, 0, // PC_VMR
- Unsupported, 0, 0, 0, 0, 0, // PC_VMRP
- IU, 0, 0, 0, 0, 0, // PC_SLE
- IU, 0, 0, 0, 0, 0, // PC_SLEQ
- IU, 0, 0, 0, 0, 0, // PC_SLIQ
- IU, 0, 0, 0, 0, 0, // PC_SLLIQ
- IU, 0, 0, 0, 0, 0, // PC_SLLQ
- IU, 0, 0, 0, 0, 0, // PC_SLQ
- IU, 0, 0, 0, 0, 0, // PC_SRAIQ
- IU, 0, 0, 0, 0, 0, // PC_SRAQ
- IU, 0, 0, 0, 0, 0, // PC_SRE
- IU, 0, 0, 0, 0, 0, // PC_SREA
- IU, 0, 0, 0, 0, 0, // PC_SREQ
- IU, 0, 0, 0, 0, 0, // PC_SRIQ
- IU, 0, 0, 0, 0, 0, // PC_SRLIQ
- IU, 0, 0, 0, 0, 0, // PC_SRLQ
- IU, 0, 0, 0, 0, 0, // PC_SRQ
- IU, 0, 0, 0, 0, 0, // PC_MASKG
- IU, 0, 0, 0, 0, 0, // PC_MASKIR
- IU, 0, 0, 0, 0, 0, // PC_LSCBX
- IU, 0, 0, 0, 0, 0, // PC_DIV
- IU, 0, 0, 0, 0, 0, // PC_DIVS
- IU, 0, 0, 0, 0, 0, // PC_DOZ
- IU, 0, 0, 0, 0, 0, // PC_MUL
- IU, 0, 0, 0, 0, 0, // PC_NABS
- IU, 0, 0, 0, 0, 0, // PC_ABS
- IU, 0, 0, 0, 0, 0, // PC_CLCS
- IU, 0, 0, 0, 0, 0, // PC_DOZI
- IU, 0, 0, 0, 0, 0, // PC_RLMI
- IU, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int stageCount, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - stageCount];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void complete_instruction(int stage) {
- pipeline[stage].instr = NULL;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-}
-
-static int can_issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- if (stage == Serialize)
- stage = IU;
- if (pipeline[stage].instr)
- return 0;
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[IU];
- if (stage == Serialize)
- stage = IU;
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (pipeline[IU].instr && pipeline[IU].remaining == 0)
- complete_instruction(IU);
- if (pipeline[FWA].instr && pipeline[FWA].remaining == 0)
- complete_instruction(FWA);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
-
- if (pipeline[FPA].instr && pipeline[FPA].remaining == 0 && !pipeline[FWA].instr)
- advance(1, FPA, FWA);
- if (pipeline[FPM].instr && pipeline[FPM].remaining == 0 && !pipeline[FPA].instr)
- advance(1, FPM, FPA);
- if (pipeline[FD].instr && pipeline[FD].remaining == 0 && !pipeline[FPM].instr)
- advance(1, FD, FPM);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].stage == Serialize;
-}
-
-MachineInfo machine601 = {
- 2,
- 0,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation603.c b/compiler_and_linker/unsorted/MachineSimulation603.c
deleted file mode 100644
index 49d1ea0..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation603.c
+++ /dev/null
@@ -1,626 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// this is actually for 603e, but i couldn't find the 603 doc
-// https://www.nxp.com/docs/en/reference-manual/MPC603EUM.pdf
-
-typedef enum Stage {
- BPU, // Branch Prediction Unit
- IU, // Integer Unit
- LSU1, // Load/Store Unit
- LSU2,
- FPU1, // Floating Point Unit
- FPU2,
- FPU3,
- SRU, // System Register Unit
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-enum {
- MaxEntries = 5
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[3];
-
- // does this instruction serialise?
- char serializes;
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 1, // PC_B
- BPU, 0, 0, 0, 0, 1, // PC_BL
- BPU, 0, 0, 0, 0, 1, // PC_BC
- BPU, 0, 0, 0, 0, 1, // PC_BCLR
- BPU, 0, 0, 0, 0, 1, // PC_BCCTR
- BPU, 0, 0, 0, 0, 1, // PC_BT
- BPU, 0, 0, 0, 0, 1, // PC_BTLR
- BPU, 0, 0, 0, 0, 1, // PC_BTCTR
- BPU, 0, 0, 0, 0, 1, // PC_BF
- BPU, 0, 0, 0, 0, 1, // PC_BFLR
- BPU, 0, 0, 0, 0, 1, // PC_BFCTR
- BPU, 0, 0, 0, 0, 1, // PC_BDNZ
- BPU, 0, 0, 0, 0, 1, // PC_BDNZT
- BPU, 0, 0, 0, 0, 1, // PC_BDNZF
- BPU, 0, 0, 0, 0, 1, // PC_BDZ
- BPU, 0, 0, 0, 0, 1, // PC_BDZT
- BPU, 0, 0, 0, 0, 1, // PC_BDZF
- BPU, 0, 0, 0, 0, 1, // PC_BLR
- BPU, 0, 0, 0, 0, 1, // PC_BCTR
- BPU, 0, 0, 0, 0, 1, // PC_BCTRL
- BPU, 0, 0, 0, 0, 1, // PC_BLRL
- LSU1, 2, 1, 1, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LMW
- LSU1, 2, 1, 1, 0, 0, // PC_STB
- LSU1, 2, 1, 1, 0, 0, // PC_STBU
- LSU1, 2, 1, 1, 0, 0, // PC_STBX
- LSU1, 2, 1, 1, 0, 0, // PC_STBUX
- LSU1, 2, 1, 1, 0, 0, // PC_STH
- LSU1, 2, 1, 1, 0, 0, // PC_STHU
- LSU1, 2, 1, 1, 0, 0, // PC_STHX
- LSU1, 2, 1, 1, 0, 0, // PC_STHUX
- LSU1, 2, 1, 1, 0, 0, // PC_STHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STW
- LSU1, 2, 1, 1, 0, 0, // PC_STWU
- LSU1, 2, 1, 1, 0, 0, // PC_STWX
- LSU1, 2, 1, 1, 0, 0, // PC_STWUX
- LSU1, 2, 1, 1, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STMW
- LSU1, 2, 1, 1, 0, 0, // PC_DCBF
- LSU1, 2, 1, 1, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBZ
- IU, 1, 1, 0, 0, 0, // PC_ADD
- IU, 1, 1, 0, 0, 0, // PC_ADDC
- IU, 1, 1, 0, 0, 0, // PC_ADDE
- IU, 1, 1, 0, 0, 0, // PC_ADDI
- IU, 1, 1, 0, 0, 0, // PC_ADDIC
- IU, 1, 1, 0, 0, 0, // PC_ADDICR
- IU, 1, 1, 0, 0, 0, // PC_ADDIS
- IU, 1, 1, 0, 0, 0, // PC_ADDME
- IU, 1, 1, 0, 0, 0, // PC_ADDZE
- IU, 37, 37, 0, 0, 0, // PC_DIVW
- IU, 37, 37, 0, 0, 0, // PC_DIVWU
- IU, 5, 5, 0, 0, 0, // PC_MULHW
- IU, 5, 5, 0, 0, 0, // PC_MULHWU
- IU, 3, 3, 0, 0, 0, // PC_MULLI
- IU, 5, 5, 0, 0, 0, // PC_MULLW
- IU, 1, 1, 0, 0, 0, // PC_NEG
- IU, 1, 1, 0, 0, 0, // PC_SUBF
- IU, 1, 1, 0, 0, 0, // PC_SUBFC
- IU, 1, 1, 0, 0, 0, // PC_SUBFE
- IU, 1, 1, 0, 0, 0, // PC_SUBFIC
- IU, 1, 1, 0, 0, 0, // PC_SUBFME
- IU, 1, 1, 0, 0, 0, // PC_SUBFZE
- IU, 3, 1, 0, 0, 0, // PC_CMPI
- IU, 3, 1, 0, 0, 0, // PC_CMP
- IU, 3, 1, 0, 0, 0, // PC_CMPLI
- IU, 3, 1, 0, 0, 0, // PC_CMPL
- IU, 1, 1, 0, 0, 0, // PC_ANDI
- IU, 1, 1, 0, 0, 0, // PC_ANDIS
- IU, 1, 1, 0, 0, 0, // PC_ORI
- IU, 1, 1, 0, 0, 0, // PC_ORIS
- IU, 1, 1, 0, 0, 0, // PC_XORI
- IU, 1, 1, 0, 0, 0, // PC_XORIS
- IU, 1, 1, 0, 0, 0, // PC_AND
- IU, 1, 1, 0, 0, 0, // PC_OR
- IU, 1, 1, 0, 0, 0, // PC_XOR
- IU, 1, 1, 0, 0, 0, // PC_NAND
- IU, 1, 1, 0, 0, 0, // PC_NOR
- IU, 1, 1, 0, 0, 0, // PC_EQV
- IU, 1, 1, 0, 0, 0, // PC_ANDC
- IU, 1, 1, 0, 0, 0, // PC_ORC
- IU, 1, 1, 0, 0, 0, // PC_EXTSB
- IU, 1, 1, 0, 0, 0, // PC_EXTSH
- IU, 1, 1, 0, 0, 0, // PC_CNTLZW
- IU, 1, 1, 0, 0, 0, // PC_RLWINM
- IU, 1, 1, 0, 0, 0, // PC_RLWNM
- IU, 1, 1, 0, 0, 0, // PC_RLWIMI
- IU, 1, 1, 0, 0, 0, // PC_SLW
- IU, 1, 1, 0, 0, 0, // PC_SRW
- IU, 1, 1, 0, 0, 0, // PC_SRAWI
- IU, 1, 1, 0, 0, 0, // PC_SRAW
- SRU, 1, 1, 0, 0, 0, // PC_CRAND
- SRU, 1, 1, 0, 0, 0, // PC_CRANDC
- SRU, 1, 1, 0, 0, 0, // PC_CREQV
- SRU, 1, 1, 0, 0, 0, // PC_CRNAND
- SRU, 1, 1, 0, 0, 0, // PC_CRNOR
- SRU, 1, 1, 0, 0, 0, // PC_CROR
- SRU, 1, 1, 0, 0, 0, // PC_CRORC
- SRU, 1, 1, 0, 0, 0, // PC_CRXOR
- SRU, 1, 1, 0, 0, 0, // PC_MCRF
- SRU, 2, 2, 0, 0, 0, // PC_MTXER
- SRU, 2, 2, 0, 0, 0, // PC_MTCTR
- SRU, 2, 2, 0, 0, 0, // PC_MTLR
- SRU, 1, 1, 0, 0, 0, // PC_MTCRF
- SRU, 1, 1, 0, 0, 1, // PC_MTMSR
- SRU, 1, 1, 0, 0, 1, // PC_MTSPR
- SRU, 1, 1, 0, 0, 1, // PC_MFMSR
- SRU, 1, 1, 0, 0, 1, // PC_MFSPR
- SRU, 1, 1, 0, 0, 0, // PC_MFXER
- SRU, 1, 1, 0, 0, 0, // PC_MFCTR
- SRU, 1, 1, 0, 0, 0, // PC_MFLR
- SRU, 1, 1, 0, 0, 0, // PC_MFCR
- FPU1, 3, 1, 1, 1, 0, // PC_MFFS
- FPU1, 3, 1, 1, 1, 0, // PC_MTFSF
- SRU, 1, 1, 0, 0, 1, // PC_EIEIO
- SRU, 1, 1, 0, 0, 1, // PC_ISYNC
- SRU, 1, 1, 0, 0, 1, // PC_SYNC
- SRU, 1, 1, 0, 0, 1, // PC_RFI
- IU, 1, 1, 0, 0, 0, // PC_LI
- IU, 1, 1, 0, 0, 0, // PC_LIS
- IU, 1, 1, 0, 0, 0, // PC_MR
- IU, 1, 1, 0, 0, 0, // PC_NOP
- IU, 1, 1, 0, 0, 0, // PC_NOT
- LSU1, 2, 1, 1, 0, 0, // PC_LFS
- LSU1, 2, 1, 1, 0, 0, // PC_LFSU
- LSU1, 2, 1, 1, 0, 0, // PC_LFSX
- LSU1, 2, 1, 1, 0, 0, // PC_LFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_LFD
- LSU1, 2, 1, 1, 0, 0, // PC_LFDU
- LSU1, 2, 1, 1, 0, 0, // PC_LFDX
- LSU1, 2, 1, 1, 0, 0, // PC_LFDUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFS
- LSU1, 2, 1, 1, 0, 0, // PC_STFSU
- LSU1, 2, 1, 1, 0, 0, // PC_STFSX
- LSU1, 2, 1, 1, 0, 0, // PC_STFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFD
- LSU1, 2, 1, 1, 0, 0, // PC_STFDU
- LSU1, 2, 1, 1, 0, 0, // PC_STFDX
- LSU1, 2, 1, 1, 0, 0, // PC_STFDUX
- FPU1, 3, 1, 1, 1, 0, // PC_FMR
- FPU1, 3, 1, 1, 1, 0, // PC_FABS
- FPU1, 3, 1, 1, 1, 0, // PC_FNEG
- FPU1, 3, 1, 1, 1, 0, // PC_FNABS
- FPU1, 3, 1, 1, 1, 0, // PC_FADD
- FPU1, 3, 1, 1, 1, 0, // PC_FADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FMUL
- FPU1, 3, 1, 1, 1, 0, // PC_FMULS
- FPU1, 33, 33, 0, 0, 0, // PC_FDIV
- FPU1, 18, 18, 0, 0, 0, // PC_FDIVS
- FPU1, 4, 2, 1, 1, 0, // PC_FMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS
- FPU1, 18, 18, 0, 0, 0, // PC_FRES
- FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE
- FPU1, 3, 1, 1, 1, 0, // PC_FSEL
- FPU1, 3, 1, 1, 1, 0, // PC_FRSP
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIW
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPU
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPO
- LSU1, 1, 1, 0, 0, 0, // PC_LWARX
- LSU1, 1, 1, 0, 0, 0, // PC_LSWI
- LSU1, 1, 1, 0, 0, 0, // PC_LSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STFIWX
- LSU1, 1, 1, 0, 0, 0, // PC_STSWI
- LSU1, 1, 1, 0, 0, 0, // PC_STSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STWCX
- IU, 1, 1, 0, 0, 1, // PC_ECIWX
- IU, 1, 1, 0, 0, 1, // PC_ECOWX
- IU, 1, 1, 0, 0, 0, // PC_DCBI
- IU, 1, 1, 0, 0, 0, // PC_ICBI
- IU, 1, 1, 0, 0, 0, // PC_MCRFS
- IU, 1, 1, 0, 0, 0, // PC_MCRXR
- IU, 1, 1, 0, 0, 0, // PC_MFTB
- IU, 1, 1, 0, 0, 0, // PC_MFSR
- IU, 1, 1, 0, 0, 0, // PC_MTSR
- IU, 1, 1, 0, 0, 0, // PC_MFSRIN
- IU, 1, 1, 0, 0, 0, // PC_MTSRIN
- IU, 1, 1, 0, 0, 0, // PC_MTFSB0
- IU, 1, 1, 0, 0, 0, // PC_MTFSB1
- IU, 1, 1, 0, 0, 0, // PC_MTFSFI
- IU, 1, 1, 0, 0, 1, // PC_SC
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRT
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS
- IU, 1, 1, 0, 0, 0, // PC_TLBIA
- IU, 1, 1, 0, 0, 0, // PC_TLBIE
- IU, 1, 1, 0, 0, 0, // PC_TLBLD
- IU, 1, 1, 0, 0, 0, // PC_TLBLI
- IU, 1, 1, 0, 0, 0, // PC_TLBSYNC
- IU, 1, 1, 0, 0, 1, // PC_TW
- IU, 1, 1, 0, 0, 1, // PC_TRAP
- IU, 1, 1, 0, 0, 1, // PC_TWI
- IU, 1, 1, 0, 0, 1, // PC_OPWORD
- IU, 1, 1, 0, 0, 0, // PC_MFROM
- IU, 1, 1, 0, 0, 1, // PC_DSA
- IU, 1, 1, 0, 0, 1, // PC_ESA
- IU, 0, 0, 0, 0, 0, // PC_DCCCI
- IU, 0, 0, 0, 0, 0, // PC_DCREAD
- IU, 0, 0, 0, 0, 0, // PC_ICBT
- IU, 0, 0, 0, 0, 0, // PC_ICCCI
- IU, 0, 0, 0, 0, 0, // PC_ICREAD
- IU, 0, 0, 0, 0, 0, // PC_RFCI
- IU, 0, 0, 0, 0, 0, // PC_TLBRE
- IU, 0, 0, 0, 0, 0, // PC_TLBSX
- IU, 0, 0, 0, 0, 0, // PC_TLBWE
- IU, 0, 0, 0, 0, 0, // PC_WRTEE
- IU, 0, 0, 0, 0, 0, // PC_WRTEEI
- IU, 0, 0, 0, 0, 0, // PC_MFDCR
- IU, 0, 0, 0, 0, 0, // PC_MTDCR
- IU, 0, 0, 0, 0, 0, // PC_DCBA
- BPU, 0, 0, 0, 0, 0, // PC_DSS
- BPU, 0, 0, 0, 0, 0, // PC_DSSALL
- BPU, 0, 0, 0, 0, 0, // PC_DST
- BPU, 0, 0, 0, 0, 0, // PC_DSTT
- BPU, 0, 0, 0, 0, 0, // PC_DSTST
- BPU, 0, 0, 0, 0, 0, // PC_DSTSTT
- BPU, 0, 0, 0, 0, 0, // PC_LVEBX
- BPU, 0, 0, 0, 0, 0, // PC_LVEHX
- BPU, 0, 0, 0, 0, 0, // PC_LVEWX
- BPU, 0, 0, 0, 0, 0, // PC_LVSL
- BPU, 0, 0, 0, 0, 0, // PC_LVSR
- BPU, 0, 0, 0, 0, 0, // PC_LVX
- BPU, 0, 0, 0, 0, 0, // PC_LVXL
- BPU, 0, 0, 0, 0, 0, // PC_STVEBX
- BPU, 0, 0, 0, 0, 0, // PC_STVEHX
- BPU, 0, 0, 0, 0, 0, // PC_STVEWX
- BPU, 0, 0, 0, 0, 0, // PC_STVX
- BPU, 0, 0, 0, 0, 0, // PC_STVXL
- BPU, 0, 0, 0, 0, 0, // PC_MFVSCR
- BPU, 0, 0, 0, 0, 0, // PC_MTVSCR
- BPU, 0, 0, 0, 0, 0, // PC_VADDCUW
- BPU, 0, 0, 0, 0, 0, // PC_VADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VADDSBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSWS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWS
- BPU, 0, 0, 0, 0, 0, // PC_VAND
- BPU, 0, 0, 0, 0, 0, // PC_VANDC
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSW
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUW
- BPU, 0, 0, 0, 0, 0, // PC_VCFSX
- BPU, 0, 0, 0, 0, 0, // PC_VCFUX
- BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- BPU, 0, 0, 0, 0, 0, // PC_VCTSXS
- BPU, 0, 0, 0, 0, 0, // PC_VCTUXS
- BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSW
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUW
- BPU, 0, 0, 0, 0, 0, // PC_VMINFP
- BPU, 0, 0, 0, 0, 0, // PC_VMINSB
- BPU, 0, 0, 0, 0, 0, // PC_VMINSH
- BPU, 0, 0, 0, 0, 0, // PC_VMINSW
- BPU, 0, 0, 0, 0, 0, // PC_VMINUB
- BPU, 0, 0, 0, 0, 0, // PC_VMINUH
- BPU, 0, 0, 0, 0, 0, // PC_VMINUW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLW
- BPU, 0, 0, 0, 0, 0, // PC_VMULESB
- BPU, 0, 0, 0, 0, 0, // PC_VMULESH
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUH
- BPU, 0, 0, 0, 0, 0, // PC_VNOR
- BPU, 0, 0, 0, 0, 0, // PC_VOR
- BPU, 0, 0, 0, 0, 0, // PC_VPKPX
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS
- BPU, 0, 0, 0, 0, 0, // PC_VREFP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIM
- BPU, 0, 0, 0, 0, 0, // PC_VRFIN
- BPU, 0, 0, 0, 0, 0, // PC_VRFIP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIZ
- BPU, 0, 0, 0, 0, 0, // PC_VRLB
- BPU, 0, 0, 0, 0, 0, // PC_VRLH
- BPU, 0, 0, 0, 0, 0, // PC_VRLW
- BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VSL
- BPU, 0, 0, 0, 0, 0, // PC_VSLB
- BPU, 0, 0, 0, 0, 0, // PC_VSLH
- BPU, 0, 0, 0, 0, 0, // PC_VSLO
- BPU, 0, 0, 0, 0, 0, // PC_VSLW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW
- BPU, 0, 0, 0, 0, 0, // PC_VSR
- BPU, 0, 0, 0, 0, 0, // PC_VSRAB
- BPU, 0, 0, 0, 0, 0, // PC_VSRAH
- BPU, 0, 0, 0, 0, 0, // PC_VSRAW
- BPU, 0, 0, 0, 0, 0, // PC_VSRB
- BPU, 0, 0, 0, 0, 0, // PC_VSRH
- BPU, 0, 0, 0, 0, 0, // PC_VSRO
- BPU, 0, 0, 0, 0, 0, // PC_VSRW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH
- BPU, 0, 0, 0, 0, 0, // PC_VXOR
- BPU, 0, 0, 0, 0, 0, // PC_VMADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VPERM
- BPU, 0, 0, 0, 0, 0, // PC_VSEL
- BPU, 0, 0, 0, 0, 0, // PC_VSLDOI
- BPU, 0, 0, 0, 0, 0, // PC_VMR
- BPU, 0, 0, 0, 0, 0, // PC_VMRP
- BPU, 0, 0, 0, 0, 0, // PC_SLE
- BPU, 0, 0, 0, 0, 0, // PC_SLEQ
- BPU, 0, 0, 0, 0, 0, // PC_SLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLQ
- BPU, 0, 0, 0, 0, 0, // PC_SLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAQ
- BPU, 0, 0, 0, 0, 0, // PC_SRE
- BPU, 0, 0, 0, 0, 0, // PC_SREA
- BPU, 0, 0, 0, 0, 0, // PC_SREQ
- BPU, 0, 0, 0, 0, 0, // PC_SRIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRQ
- BPU, 0, 0, 0, 0, 0, // PC_MASKG
- BPU, 0, 0, 0, 0, 0, // PC_MASKIR
- BPU, 0, 0, 0, 0, 0, // PC_LSCBX
- BPU, 0, 0, 0, 0, 0, // PC_DIV
- BPU, 0, 0, 0, 0, 0, // PC_DIVS
- BPU, 0, 0, 0, 0, 0, // PC_DOZ
- BPU, 0, 0, 0, 0, 0, // PC_MUL
- BPU, 0, 0, 0, 0, 0, // PC_NABS
- BPU, 0, 0, 0, 0, 0, // PC_ABS
- BPU, 0, 0, 0, 0, 0, // PC_CLCS
- BPU, 0, 0, 0, 0, 0, // PC_DOZI
- BPU, 0, 0, 0, 0, 0, // PC_RLMI
- BPU, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = 5;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-}
-
-static int can_issue(PCode *instr) {
- if (completionbuffers.free == 0)
- return 0;
- if (pipeline[instruction_timing[instr->op].stage].instr)
- return 0;
- if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
- return 0;
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- assign_completion_buffer(instr);
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- }
- }
-
- if (pipeline[IU].instr && pipeline[IU].remaining == 0)
- complete_instruction(IU);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
- complete_instruction(FPU3);
- if (pipeline[SRU].instr && pipeline[SRU].remaining == 0)
- complete_instruction(SRU);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
-
- if (
- pipeline[FPU1].instr &&
- pipeline[FPU1].remaining == 0 &&
- (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
- )
- complete_instruction(FPU1);
-
- if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
- advance(FPU1, FPU2, FPU3);
- if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
- advance(FPU1, FPU1, FPU2);
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-MachineInfo machine603 = {
- 2,
- 1,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation603e.c b/compiler_and_linker/unsorted/MachineSimulation603e.c
deleted file mode 100644
index d3e1e47..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation603e.c
+++ /dev/null
@@ -1,650 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://www.nxp.com/docs/en/reference-manual/MPC603EUM.pdf
-
-typedef enum Stage {
- BPU, // Branch Prediction Unit
- IU, // Integer Unit
- LSU1, // Load/Store Unit
- LSU2,
- FPU1, // Floating Point Unit
- FPU2,
- FPU3,
- SRU, // System Register Unit
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-enum {
- MaxEntries = 5
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[3];
-
- // does this instruction serialise?
- char serializes;
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 1, // PC_B
- BPU, 0, 0, 0, 0, 1, // PC_BL
- BPU, 0, 0, 0, 0, 1, // PC_BC
- BPU, 0, 0, 0, 0, 1, // PC_BCLR
- BPU, 0, 0, 0, 0, 1, // PC_BCCTR
- BPU, 0, 0, 0, 0, 1, // PC_BT
- BPU, 0, 0, 0, 0, 1, // PC_BTLR
- BPU, 0, 0, 0, 0, 1, // PC_BTCTR
- BPU, 0, 0, 0, 0, 1, // PC_BF
- BPU, 0, 0, 0, 0, 1, // PC_BFLR
- BPU, 0, 0, 0, 0, 1, // PC_BFCTR
- BPU, 0, 0, 0, 0, 1, // PC_BDNZ
- BPU, 0, 0, 0, 0, 1, // PC_BDNZT
- BPU, 0, 0, 0, 0, 1, // PC_BDNZF
- BPU, 0, 0, 0, 0, 1, // PC_BDZ
- BPU, 0, 0, 0, 0, 1, // PC_BDZT
- BPU, 0, 0, 0, 0, 1, // PC_BDZF
- BPU, 0, 0, 0, 0, 1, // PC_BLR
- BPU, 0, 0, 0, 0, 1, // PC_BCTR
- BPU, 0, 0, 0, 0, 1, // PC_BCTRL
- BPU, 0, 0, 0, 0, 1, // PC_BLRL
- LSU1, 2, 1, 1, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LMW
- LSU1, 2, 1, 1, 0, 0, // PC_STB
- LSU1, 2, 1, 1, 0, 0, // PC_STBU
- LSU1, 2, 1, 1, 0, 0, // PC_STBX
- LSU1, 2, 1, 1, 0, 0, // PC_STBUX
- LSU1, 2, 1, 1, 0, 0, // PC_STH
- LSU1, 2, 1, 1, 0, 0, // PC_STHU
- LSU1, 2, 1, 1, 0, 0, // PC_STHX
- LSU1, 2, 1, 1, 0, 0, // PC_STHUX
- LSU1, 2, 1, 1, 0, 0, // PC_STHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STW
- LSU1, 2, 1, 1, 0, 0, // PC_STWU
- LSU1, 2, 1, 1, 0, 0, // PC_STWX
- LSU1, 2, 1, 1, 0, 0, // PC_STWUX
- LSU1, 2, 1, 1, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STMW
- LSU1, 2, 1, 1, 0, 0, // PC_DCBF
- LSU1, 2, 1, 1, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBZ
- IU, 1, 1, 0, 0, 0, // PC_ADD
- IU, 1, 1, 0, 0, 0, // PC_ADDC
- IU, 1, 1, 0, 0, 0, // PC_ADDE
- IU, 1, 1, 0, 0, 0, // PC_ADDI
- IU, 1, 1, 0, 0, 0, // PC_ADDIC
- IU, 1, 1, 0, 0, 0, // PC_ADDICR
- IU, 1, 1, 0, 0, 0, // PC_ADDIS
- IU, 1, 1, 0, 0, 0, // PC_ADDME
- IU, 1, 1, 0, 0, 0, // PC_ADDZE
- IU, 37, 37, 0, 0, 0, // PC_DIVW
- IU, 37, 37, 0, 0, 0, // PC_DIVWU
- IU, 5, 5, 0, 0, 0, // PC_MULHW
- IU, 5, 5, 0, 0, 0, // PC_MULHWU
- IU, 3, 3, 0, 0, 0, // PC_MULLI
- IU, 5, 5, 0, 0, 0, // PC_MULLW
- IU, 1, 1, 0, 0, 0, // PC_NEG
- IU, 1, 1, 0, 0, 0, // PC_SUBF
- IU, 1, 1, 0, 0, 0, // PC_SUBFC
- IU, 1, 1, 0, 0, 0, // PC_SUBFE
- IU, 1, 1, 0, 0, 0, // PC_SUBFIC
- IU, 1, 1, 0, 0, 0, // PC_SUBFME
- IU, 1, 1, 0, 0, 0, // PC_SUBFZE
- IU, 3, 1, 0, 0, 0, // PC_CMPI
- IU, 3, 1, 0, 0, 0, // PC_CMP
- IU, 3, 1, 0, 0, 0, // PC_CMPLI
- IU, 3, 1, 0, 0, 0, // PC_CMPL
- IU, 1, 1, 0, 0, 0, // PC_ANDI
- IU, 1, 1, 0, 0, 0, // PC_ANDIS
- IU, 1, 1, 0, 0, 0, // PC_ORI
- IU, 1, 1, 0, 0, 0, // PC_ORIS
- IU, 1, 1, 0, 0, 0, // PC_XORI
- IU, 1, 1, 0, 0, 0, // PC_XORIS
- IU, 1, 1, 0, 0, 0, // PC_AND
- IU, 1, 1, 0, 0, 0, // PC_OR
- IU, 1, 1, 0, 0, 0, // PC_XOR
- IU, 1, 1, 0, 0, 0, // PC_NAND
- IU, 1, 1, 0, 0, 0, // PC_NOR
- IU, 1, 1, 0, 0, 0, // PC_EQV
- IU, 1, 1, 0, 0, 0, // PC_ANDC
- IU, 1, 1, 0, 0, 0, // PC_ORC
- IU, 1, 1, 0, 0, 0, // PC_EXTSB
- IU, 1, 1, 0, 0, 0, // PC_EXTSH
- IU, 1, 1, 0, 0, 0, // PC_CNTLZW
- IU, 1, 1, 0, 0, 0, // PC_RLWINM
- IU, 1, 1, 0, 0, 0, // PC_RLWNM
- IU, 1, 1, 0, 0, 0, // PC_RLWIMI
- IU, 1, 1, 0, 0, 0, // PC_SLW
- IU, 1, 1, 0, 0, 0, // PC_SRW
- IU, 1, 1, 0, 0, 0, // PC_SRAWI
- IU, 1, 1, 0, 0, 0, // PC_SRAW
- SRU, 1, 1, 0, 0, 0, // PC_CRAND
- SRU, 1, 1, 0, 0, 0, // PC_CRANDC
- SRU, 1, 1, 0, 0, 0, // PC_CREQV
- SRU, 1, 1, 0, 0, 0, // PC_CRNAND
- SRU, 1, 1, 0, 0, 0, // PC_CRNOR
- SRU, 1, 1, 0, 0, 0, // PC_CROR
- SRU, 1, 1, 0, 0, 0, // PC_CRORC
- SRU, 1, 1, 0, 0, 0, // PC_CRXOR
- SRU, 1, 1, 0, 0, 0, // PC_MCRF
- SRU, 2, 2, 0, 0, 0, // PC_MTXER
- SRU, 2, 2, 0, 0, 0, // PC_MTCTR
- SRU, 2, 2, 0, 0, 0, // PC_MTLR
- SRU, 1, 1, 0, 0, 0, // PC_MTCRF
- SRU, 1, 1, 0, 0, 1, // PC_MTMSR
- SRU, 1, 1, 0, 0, 1, // PC_MTSPR
- SRU, 1, 1, 0, 0, 1, // PC_MFMSR
- SRU, 1, 1, 0, 0, 1, // PC_MFSPR
- SRU, 1, 1, 0, 0, 0, // PC_MFXER
- SRU, 1, 1, 0, 0, 0, // PC_MFCTR
- SRU, 1, 1, 0, 0, 0, // PC_MFLR
- SRU, 1, 1, 0, 0, 0, // PC_MFCR
- FPU1, 3, 1, 1, 1, 0, // PC_MFFS
- FPU1, 3, 1, 1, 1, 0, // PC_MTFSF
- SRU, 1, 1, 0, 0, 1, // PC_EIEIO
- SRU, 1, 1, 0, 0, 1, // PC_ISYNC
- SRU, 1, 1, 0, 0, 1, // PC_SYNC
- SRU, 1, 1, 0, 0, 1, // PC_RFI
- IU, 1, 1, 0, 0, 0, // PC_LI
- IU, 1, 1, 0, 0, 0, // PC_LIS
- IU, 1, 1, 0, 0, 0, // PC_MR
- IU, 1, 1, 0, 0, 0, // PC_NOP
- IU, 1, 1, 0, 0, 0, // PC_NOT
- LSU1, 2, 1, 1, 0, 0, // PC_LFS
- LSU1, 2, 1, 1, 0, 0, // PC_LFSU
- LSU1, 2, 1, 1, 0, 0, // PC_LFSX
- LSU1, 2, 1, 1, 0, 0, // PC_LFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_LFD
- LSU1, 2, 1, 1, 0, 0, // PC_LFDU
- LSU1, 2, 1, 1, 0, 0, // PC_LFDX
- LSU1, 2, 1, 1, 0, 0, // PC_LFDUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFS
- LSU1, 2, 1, 1, 0, 0, // PC_STFSU
- LSU1, 2, 1, 1, 0, 0, // PC_STFSX
- LSU1, 2, 1, 1, 0, 0, // PC_STFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFD
- LSU1, 2, 1, 1, 0, 0, // PC_STFDU
- LSU1, 2, 1, 1, 0, 0, // PC_STFDX
- LSU1, 2, 1, 1, 0, 0, // PC_STFDUX
- FPU1, 3, 1, 1, 1, 0, // PC_FMR
- FPU1, 3, 1, 1, 1, 0, // PC_FABS
- FPU1, 3, 1, 1, 1, 0, // PC_FNEG
- FPU1, 3, 1, 1, 1, 0, // PC_FNABS
- FPU1, 3, 1, 1, 1, 0, // PC_FADD
- FPU1, 3, 1, 1, 1, 0, // PC_FADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FMUL
- FPU1, 3, 1, 1, 1, 0, // PC_FMULS
- FPU1, 33, 33, 0, 0, 0, // PC_FDIV
- FPU1, 18, 18, 0, 0, 0, // PC_FDIVS
- FPU1, 4, 2, 1, 1, 0, // PC_FMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS
- FPU1, 18, 18, 0, 0, 0, // PC_FRES
- FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE
- FPU1, 3, 1, 1, 1, 0, // PC_FSEL
- FPU1, 3, 1, 1, 1, 0, // PC_FRSP
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIW
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPU
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPO
- LSU1, 1, 1, 0, 0, 0, // PC_LWARX
- LSU1, 1, 1, 0, 0, 0, // PC_LSWI
- LSU1, 1, 1, 0, 0, 0, // PC_LSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STFIWX
- LSU1, 1, 1, 0, 0, 0, // PC_STSWI
- LSU1, 1, 1, 0, 0, 0, // PC_STSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STWCX
- IU, 1, 1, 0, 0, 1, // PC_ECIWX
- IU, 1, 1, 0, 0, 1, // PC_ECOWX
- IU, 1, 1, 0, 0, 0, // PC_DCBI
- IU, 1, 1, 0, 0, 0, // PC_ICBI
- IU, 1, 1, 0, 0, 0, // PC_MCRFS
- IU, 1, 1, 0, 0, 0, // PC_MCRXR
- IU, 1, 1, 0, 0, 0, // PC_MFTB
- IU, 1, 1, 0, 0, 0, // PC_MFSR
- IU, 1, 1, 0, 0, 0, // PC_MTSR
- IU, 1, 1, 0, 0, 0, // PC_MFSRIN
- IU, 1, 1, 0, 0, 0, // PC_MTSRIN
- IU, 1, 1, 0, 0, 0, // PC_MTFSB0
- IU, 1, 1, 0, 0, 0, // PC_MTFSB1
- IU, 1, 1, 0, 0, 0, // PC_MTFSFI
- IU, 1, 1, 0, 0, 1, // PC_SC
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRT
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS
- IU, 1, 1, 0, 0, 0, // PC_TLBIA
- IU, 1, 1, 0, 0, 0, // PC_TLBIE
- IU, 1, 1, 0, 0, 0, // PC_TLBLD
- IU, 1, 1, 0, 0, 0, // PC_TLBLI
- IU, 1, 1, 0, 0, 0, // PC_TLBSYNC
- IU, 1, 1, 0, 0, 1, // PC_TW
- IU, 1, 1, 0, 0, 1, // PC_TRAP
- IU, 1, 1, 0, 0, 1, // PC_TWI
- IU, 1, 1, 0, 0, 1, // PC_OPWORD
- IU, 1, 1, 0, 0, 0, // PC_MFROM
- IU, 1, 1, 0, 0, 1, // PC_DSA
- IU, 1, 1, 0, 0, 1, // PC_ESA
- IU, 0, 0, 0, 0, 0, // PC_DCCCI
- IU, 0, 0, 0, 0, 0, // PC_DCREAD
- IU, 0, 0, 0, 0, 0, // PC_ICBT
- IU, 0, 0, 0, 0, 0, // PC_ICCCI
- IU, 0, 0, 0, 0, 0, // PC_ICREAD
- IU, 0, 0, 0, 0, 0, // PC_RFCI
- IU, 0, 0, 0, 0, 0, // PC_TLBRE
- IU, 0, 0, 0, 0, 0, // PC_TLBSX
- IU, 0, 0, 0, 0, 0, // PC_TLBWE
- IU, 0, 0, 0, 0, 0, // PC_WRTEE
- IU, 0, 0, 0, 0, 0, // PC_WRTEEI
- IU, 0, 0, 0, 0, 0, // PC_MFDCR
- IU, 0, 0, 0, 0, 0, // PC_MTDCR
- IU, 0, 0, 0, 0, 0, // PC_DCBA
- BPU, 0, 0, 0, 0, 0, // PC_DSS
- BPU, 0, 0, 0, 0, 0, // PC_DSSALL
- BPU, 0, 0, 0, 0, 0, // PC_DST
- BPU, 0, 0, 0, 0, 0, // PC_DSTT
- BPU, 0, 0, 0, 0, 0, // PC_DSTST
- BPU, 0, 0, 0, 0, 0, // PC_DSTSTT
- BPU, 0, 0, 0, 0, 0, // PC_LVEBX
- BPU, 0, 0, 0, 0, 0, // PC_LVEHX
- BPU, 0, 0, 0, 0, 0, // PC_LVEWX
- BPU, 0, 0, 0, 0, 0, // PC_LVSL
- BPU, 0, 0, 0, 0, 0, // PC_LVSR
- BPU, 0, 0, 0, 0, 0, // PC_LVX
- BPU, 0, 0, 0, 0, 0, // PC_LVXL
- BPU, 0, 0, 0, 0, 0, // PC_STVEBX
- BPU, 0, 0, 0, 0, 0, // PC_STVEHX
- BPU, 0, 0, 0, 0, 0, // PC_STVEWX
- BPU, 0, 0, 0, 0, 0, // PC_STVX
- BPU, 0, 0, 0, 0, 0, // PC_STVXL
- BPU, 0, 0, 0, 0, 0, // PC_MFVSCR
- BPU, 0, 0, 0, 0, 0, // PC_MTVSCR
- BPU, 0, 0, 0, 0, 0, // PC_VADDCUW
- BPU, 0, 0, 0, 0, 0, // PC_VADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VADDSBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSWS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWS
- BPU, 0, 0, 0, 0, 0, // PC_VAND
- BPU, 0, 0, 0, 0, 0, // PC_VANDC
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSW
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUW
- BPU, 0, 0, 0, 0, 0, // PC_VCFSX
- BPU, 0, 0, 0, 0, 0, // PC_VCFUX
- BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- BPU, 0, 0, 0, 0, 0, // PC_VCTSXS
- BPU, 0, 0, 0, 0, 0, // PC_VCTUXS
- BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSW
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUW
- BPU, 0, 0, 0, 0, 0, // PC_VMINFP
- BPU, 0, 0, 0, 0, 0, // PC_VMINSB
- BPU, 0, 0, 0, 0, 0, // PC_VMINSH
- BPU, 0, 0, 0, 0, 0, // PC_VMINSW
- BPU, 0, 0, 0, 0, 0, // PC_VMINUB
- BPU, 0, 0, 0, 0, 0, // PC_VMINUH
- BPU, 0, 0, 0, 0, 0, // PC_VMINUW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLW
- BPU, 0, 0, 0, 0, 0, // PC_VMULESB
- BPU, 0, 0, 0, 0, 0, // PC_VMULESH
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUH
- BPU, 0, 0, 0, 0, 0, // PC_VNOR
- BPU, 0, 0, 0, 0, 0, // PC_VOR
- BPU, 0, 0, 0, 0, 0, // PC_VPKPX
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS
- BPU, 0, 0, 0, 0, 0, // PC_VREFP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIM
- BPU, 0, 0, 0, 0, 0, // PC_VRFIN
- BPU, 0, 0, 0, 0, 0, // PC_VRFIP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIZ
- BPU, 0, 0, 0, 0, 0, // PC_VRLB
- BPU, 0, 0, 0, 0, 0, // PC_VRLH
- BPU, 0, 0, 0, 0, 0, // PC_VRLW
- BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VSL
- BPU, 0, 0, 0, 0, 0, // PC_VSLB
- BPU, 0, 0, 0, 0, 0, // PC_VSLH
- BPU, 0, 0, 0, 0, 0, // PC_VSLO
- BPU, 0, 0, 0, 0, 0, // PC_VSLW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW
- BPU, 0, 0, 0, 0, 0, // PC_VSR
- BPU, 0, 0, 0, 0, 0, // PC_VSRAB
- BPU, 0, 0, 0, 0, 0, // PC_VSRAH
- BPU, 0, 0, 0, 0, 0, // PC_VSRAW
- BPU, 0, 0, 0, 0, 0, // PC_VSRB
- BPU, 0, 0, 0, 0, 0, // PC_VSRH
- BPU, 0, 0, 0, 0, 0, // PC_VSRO
- BPU, 0, 0, 0, 0, 0, // PC_VSRW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH
- BPU, 0, 0, 0, 0, 0, // PC_VXOR
- BPU, 0, 0, 0, 0, 0, // PC_VMADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VPERM
- BPU, 0, 0, 0, 0, 0, // PC_VSEL
- BPU, 0, 0, 0, 0, 0, // PC_VSLDOI
- BPU, 0, 0, 0, 0, 0, // PC_VMR
- BPU, 0, 0, 0, 0, 0, // PC_VMRP
- BPU, 0, 0, 0, 0, 0, // PC_SLE
- BPU, 0, 0, 0, 0, 0, // PC_SLEQ
- BPU, 0, 0, 0, 0, 0, // PC_SLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLQ
- BPU, 0, 0, 0, 0, 0, // PC_SLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAQ
- BPU, 0, 0, 0, 0, 0, // PC_SRE
- BPU, 0, 0, 0, 0, 0, // PC_SREA
- BPU, 0, 0, 0, 0, 0, // PC_SREQ
- BPU, 0, 0, 0, 0, 0, // PC_SRIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRQ
- BPU, 0, 0, 0, 0, 0, // PC_MASKG
- BPU, 0, 0, 0, 0, 0, // PC_MASKIR
- BPU, 0, 0, 0, 0, 0, // PC_LSCBX
- BPU, 0, 0, 0, 0, 0, // PC_DIV
- BPU, 0, 0, 0, 0, 0, // PC_DIVS
- BPU, 0, 0, 0, 0, 0, // PC_DOZ
- BPU, 0, 0, 0, 0, 0, // PC_MUL
- BPU, 0, 0, 0, 0, 0, // PC_NABS
- BPU, 0, 0, 0, 0, 0, // PC_ABS
- BPU, 0, 0, 0, 0, 0, // PC_CLCS
- BPU, 0, 0, 0, 0, 0, // PC_DOZI
- BPU, 0, 0, 0, 0, 0, // PC_RLMI
- BPU, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-}
-
-static int can_issue(PCode *instr) {
- int stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- stage = instruction_timing[instr->op].stage;
- if (pipeline[stage].instr) {
- if (stage == IU) {
- switch (instr->op) {
- case PC_ADD:
- case PC_ADDC:
- case PC_ADDI:
- case PC_ADDIS:
- case PC_CMPI:
- case PC_CMP:
- case PC_CMPLI:
- case PC_CMPL:
- if (is_dependent(instr, pipeline[IU].instr, RegClass_GPR))
- return 0;
- if (!pipeline[SRU].instr)
- return 1;
- }
- }
- return 0;
- }
-
- if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
- return 0;
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- if (stage == IU && pipeline[IU].instr)
- stage = SRU;
- assign_completion_buffer(instr);
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- }
- }
-
- if (pipeline[IU].instr && pipeline[IU].remaining == 0)
- complete_instruction(IU);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
- complete_instruction(FPU3);
- if (pipeline[SRU].instr && pipeline[SRU].remaining == 0)
- complete_instruction(SRU);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
-
- if (
- pipeline[FPU1].instr &&
- pipeline[FPU1].remaining == 0 &&
- (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
- )
- complete_instruction(FPU1);
-
- if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
- advance(FPU1, FPU2, FPU3);
- if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
- advance(FPU1, FPU1, FPU2);
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-MachineInfo machine603e = {
- 2,
- 1,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation604.c b/compiler_and_linker/unsorted/MachineSimulation604.c
deleted file mode 100644
index 9775c9e..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation604.c
+++ /dev/null
@@ -1,670 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://archive.org/details/bitsavers_motorolaPosManualNov94_22719504
-
-typedef enum Stage {
- SCIU, // Single-Cycle Integer Unit 1
- SCIU2, // Single-Cycle Integer Unit 2
- MCIU, // Multiple-Cycle Integer Unit
- FPU1, // Floating Point Unit
- FPU2,
- FPU3,
- LSU1, // Load/Store Unit
- LSU2,
- BPU, // Branch Prediction Unit
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-enum {
- MaxEntries = 16
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static PCode *sciu_completed_instruction;
-static PCode *sciu2_completed_instruction;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[3];
-
- // does this instruction serialise?
- char serializes;
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 1, // PC_B
- BPU, 0, 0, 0, 0, 1, // PC_BL
- BPU, 0, 0, 0, 0, 1, // PC_BC
- BPU, 0, 0, 0, 0, 1, // PC_BCLR
- BPU, 0, 0, 0, 0, 1, // PC_BCCTR
- BPU, 0, 0, 0, 0, 1, // PC_BT
- BPU, 0, 0, 0, 0, 1, // PC_BTLR
- BPU, 0, 0, 0, 0, 1, // PC_BTCTR
- BPU, 0, 0, 0, 0, 1, // PC_BF
- BPU, 0, 0, 0, 0, 1, // PC_BFLR
- BPU, 0, 0, 0, 0, 1, // PC_BFCTR
- BPU, 0, 0, 0, 0, 1, // PC_BDNZ
- BPU, 0, 0, 0, 0, 1, // PC_BDNZT
- BPU, 0, 0, 0, 0, 1, // PC_BDNZF
- BPU, 0, 0, 0, 0, 1, // PC_BDZ
- BPU, 0, 0, 0, 0, 1, // PC_BDZT
- BPU, 0, 0, 0, 0, 1, // PC_BDZF
- BPU, 0, 0, 0, 0, 1, // PC_BLR
- BPU, 0, 0, 0, 0, 1, // PC_BCTR
- BPU, 0, 0, 0, 0, 1, // PC_BCTRL
- BPU, 0, 0, 0, 0, 1, // PC_BLRL
- LSU1, 2, 1, 1, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LMW
- LSU1, 3, 1, 1, 0, 0, // PC_STB
- LSU1, 3, 1, 1, 0, 0, // PC_STBU
- LSU1, 3, 1, 1, 0, 0, // PC_STBX
- LSU1, 3, 1, 1, 0, 0, // PC_STBUX
- LSU1, 3, 1, 1, 0, 0, // PC_STH
- LSU1, 3, 1, 1, 0, 0, // PC_STHU
- LSU1, 3, 1, 1, 0, 0, // PC_STHX
- LSU1, 3, 1, 1, 0, 0, // PC_STHUX
- LSU1, 3, 1, 1, 0, 0, // PC_STHBRX
- LSU1, 3, 1, 1, 0, 0, // PC_STW
- LSU1, 3, 1, 1, 0, 0, // PC_STWU
- LSU1, 3, 1, 1, 0, 0, // PC_STWX
- LSU1, 3, 1, 1, 0, 0, // PC_STWUX
- LSU1, 3, 1, 1, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STMW
- LSU1, 2, 1, 1, 0, 0, // PC_DCBF
- LSU1, 2, 1, 1, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBZ
- SCIU, 1, 1, 0, 0, 0, // PC_ADD
- SCIU, 1, 1, 0, 0, 0, // PC_ADDC
- SCIU, 1, 1, 0, 0, 0, // PC_ADDE
- SCIU, 1, 1, 0, 0, 0, // PC_ADDI
- SCIU, 1, 1, 0, 0, 0, // PC_ADDIC
- SCIU, 1, 1, 0, 0, 0, // PC_ADDICR
- SCIU, 1, 1, 0, 0, 0, // PC_ADDIS
- SCIU, 1, 1, 0, 0, 0, // PC_ADDME
- SCIU, 1, 1, 0, 0, 0, // PC_ADDZE
- MCIU, 20, 20, 0, 0, 0, // PC_DIVW
- MCIU, 20, 20, 0, 0, 0, // PC_DIVWU
- MCIU, 4, 4, 0, 0, 0, // PC_MULHW
- MCIU, 4, 4, 0, 0, 0, // PC_MULHWU
- MCIU, 3, 3, 0, 0, 0, // PC_MULLI
- MCIU, 4, 4, 0, 0, 0, // PC_MULLW
- SCIU, 1, 1, 0, 0, 0, // PC_NEG
- SCIU, 1, 1, 0, 0, 0, // PC_SUBF
- SCIU, 1, 1, 0, 0, 0, // PC_SUBFC
- SCIU, 1, 1, 0, 0, 0, // PC_SUBFE
- SCIU, 1, 1, 0, 0, 0, // PC_SUBFIC
- SCIU, 1, 1, 0, 0, 0, // PC_SUBFME
- SCIU, 1, 1, 0, 0, 0, // PC_SUBFZE
- SCIU, 3, 1, 0, 0, 0, // PC_CMPI
- SCIU, 3, 1, 0, 0, 0, // PC_CMP
- SCIU, 3, 1, 0, 0, 0, // PC_CMPLI
- SCIU, 3, 1, 0, 0, 0, // PC_CMPL
- SCIU, 1, 1, 0, 0, 0, // PC_ANDI
- SCIU, 1, 1, 0, 0, 0, // PC_ANDIS
- SCIU, 1, 1, 0, 0, 0, // PC_ORI
- SCIU, 1, 1, 0, 0, 0, // PC_ORIS
- SCIU, 1, 1, 0, 0, 0, // PC_XORI
- SCIU, 1, 1, 0, 0, 0, // PC_XORIS
- SCIU, 1, 1, 0, 0, 0, // PC_AND
- SCIU, 1, 1, 0, 0, 0, // PC_OR
- SCIU, 1, 1, 0, 0, 0, // PC_XOR
- SCIU, 1, 1, 0, 0, 0, // PC_NAND
- SCIU, 1, 1, 0, 0, 0, // PC_NOR
- SCIU, 1, 1, 0, 0, 0, // PC_EQV
- SCIU, 1, 1, 0, 0, 0, // PC_ANDC
- SCIU, 1, 1, 0, 0, 0, // PC_ORC
- SCIU, 1, 1, 0, 0, 0, // PC_EXTSB
- SCIU, 1, 1, 0, 0, 0, // PC_EXTSH
- SCIU, 1, 1, 0, 0, 0, // PC_CNTLZW
- SCIU, 1, 1, 0, 0, 0, // PC_RLWINM
- SCIU, 1, 1, 0, 0, 0, // PC_RLWNM
- SCIU, 1, 1, 0, 0, 0, // PC_RLWIMI
- SCIU, 1, 1, 0, 0, 0, // PC_SLW
- SCIU, 1, 1, 0, 0, 0, // PC_SRW
- SCIU, 1, 1, 0, 0, 0, // PC_SRAWI
- SCIU, 1, 1, 0, 0, 0, // PC_SRAW
- BPU, 1, 1, 0, 0, 0, // PC_CRAND
- BPU, 1, 1, 0, 0, 0, // PC_CRANDC
- BPU, 1, 1, 0, 0, 0, // PC_CREQV
- BPU, 1, 1, 0, 0, 0, // PC_CRNAND
- BPU, 1, 1, 0, 0, 0, // PC_CRNOR
- BPU, 1, 1, 0, 0, 0, // PC_CROR
- BPU, 1, 1, 0, 0, 0, // PC_CRORC
- BPU, 1, 1, 0, 0, 0, // PC_CRXOR
- BPU, 1, 1, 0, 0, 0, // PC_MCRF
- MCIU, 1, 1, 0, 0, 0, // PC_MTXER
- MCIU, 1, 1, 0, 0, 0, // PC_MTCTR
- MCIU, 1, 1, 0, 0, 0, // PC_MTLR
- MCIU, 1, 1, 0, 0, 0, // PC_MTCRF
- MCIU, 1, 1, 0, 0, 0, // PC_MTMSR
- MCIU, 1, 1, 0, 0, 0, // PC_MTSPR
- MCIU, 1, 1, 0, 0, 0, // PC_MFMSR
- MCIU, 1, 1, 0, 0, 0, // PC_MFSPR
- MCIU, 3, 3, 0, 0, 0, // PC_MFXER
- MCIU, 3, 3, 0, 0, 0, // PC_MFCTR
- MCIU, 3, 3, 0, 0, 0, // PC_MFLR
- MCIU, 3, 3, 0, 0, 0, // PC_MFCR
- FPU1, 3, 1, 1, 1, 0, // PC_MFFS
- FPU1, 3, 1, 1, 1, 0, // PC_MTFSF
- LSU1, 1, 0, 0, 0, 1, // PC_EIEIO
- LSU1, 1, 0, 0, 0, 1, // PC_ISYNC
- LSU1, 1, 0, 0, 0, 1, // PC_SYNC
- LSU1, 1, 1, 0, 0, 1, // PC_RFI
- SCIU, 1, 1, 0, 0, 0, // PC_LI
- SCIU, 1, 1, 0, 0, 0, // PC_LIS
- SCIU, 1, 1, 0, 0, 0, // PC_MR
- SCIU, 1, 1, 0, 0, 0, // PC_NOP
- SCIU, 1, 1, 0, 0, 0, // PC_NOT
- LSU1, 3, 1, 1, 0, 0, // PC_LFS
- LSU1, 3, 1, 1, 0, 0, // PC_LFSU
- LSU1, 3, 1, 1, 0, 0, // PC_LFSX
- LSU1, 3, 1, 1, 0, 0, // PC_LFSUX
- LSU1, 3, 1, 1, 0, 0, // PC_LFD
- LSU1, 3, 1, 1, 0, 0, // PC_LFDU
- LSU1, 3, 1, 1, 0, 0, // PC_LFDX
- LSU1, 3, 1, 1, 0, 0, // PC_LFDUX
- LSU1, 3, 1, 1, 0, 0, // PC_STFS
- LSU1, 3, 1, 1, 0, 0, // PC_STFSU
- LSU1, 3, 1, 1, 0, 0, // PC_STFSX
- LSU1, 3, 1, 1, 0, 0, // PC_STFSUX
- LSU1, 3, 1, 1, 0, 0, // PC_STFD
- LSU1, 3, 1, 1, 0, 0, // PC_STFDU
- LSU1, 3, 1, 1, 0, 0, // PC_STFDX
- LSU1, 3, 1, 1, 0, 0, // PC_STFDUX
- FPU1, 3, 1, 1, 1, 0, // PC_FMR
- FPU1, 3, 1, 1, 1, 0, // PC_FABS
- FPU1, 3, 1, 1, 1, 0, // PC_FNEG
- FPU1, 3, 1, 1, 1, 0, // PC_FNABS
- FPU1, 3, 1, 1, 1, 0, // PC_FADD
- FPU1, 3, 1, 1, 1, 0, // PC_FADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FSUBS
- FPU1, 3, 1, 1, 1, 0, // PC_FMUL
- FPU1, 3, 1, 1, 1, 0, // PC_FMULS
- FPU1, 32, 32, 0, 0, 0, // PC_FDIV
- FPU1, 18, 18, 0, 0, 0, // PC_FDIVS
- FPU1, 3, 1, 1, 1, 0, // PC_FMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FMADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS
- FPU1, 3, 1, 1, 1, 0, // PC_FNMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FNMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS
- FPU1, 18, 18, 0, 0, 0, // PC_FRES
- FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE
- FPU1, 3, 1, 1, 1, 0, // PC_FSEL
- FPU1, 3, 1, 1, 1, 0, // PC_FRSP
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIW
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPU
- FPU1, 5, 1, 1, 1, 0, // PC_FCMPO
- LSU1, 1, 1, 0, 0, 0, // PC_LWARX
- LSU1, 1, 1, 0, 0, 0, // PC_LSWI
- LSU1, 1, 1, 0, 0, 0, // PC_LSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STFIWX
- LSU1, 1, 1, 0, 0, 0, // PC_STSWI
- LSU1, 1, 1, 0, 0, 0, // PC_STSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STWCX
- MCIU, 1, 1, 0, 0, 1, // PC_ECIWX
- MCIU, 1, 1, 0, 0, 1, // PC_ECOWX
- MCIU, 1, 1, 0, 0, 0, // PC_DCBI
- MCIU, 1, 1, 0, 0, 0, // PC_ICBI
- MCIU, 1, 1, 0, 0, 0, // PC_MCRFS
- MCIU, 1, 1, 0, 0, 0, // PC_MCRXR
- MCIU, 1, 1, 0, 0, 0, // PC_MFTB
- MCIU, 1, 1, 0, 0, 0, // PC_MFSR
- MCIU, 1, 1, 0, 0, 0, // PC_MTSR
- MCIU, 1, 1, 0, 0, 0, // PC_MFSRIN
- MCIU, 1, 1, 0, 0, 0, // PC_MTSRIN
- MCIU, 1, 1, 0, 0, 0, // PC_MTFSB0
- MCIU, 1, 1, 0, 0, 0, // PC_MTFSB1
- MCIU, 1, 1, 0, 0, 0, // PC_MTFSFI
- MCIU, 1, 1, 0, 0, 1, // PC_SC
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRT
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS
- MCIU, 1, 1, 0, 0, 0, // PC_TLBIA
- MCIU, 1, 1, 0, 0, 0, // PC_TLBIE
- MCIU, 1, 1, 0, 0, 0, // PC_TLBLD
- MCIU, 1, 1, 0, 0, 0, // PC_TLBLI
- MCIU, 1, 1, 0, 0, 0, // PC_TLBSYNC
- MCIU, 1, 1, 0, 0, 1, // PC_TW
- MCIU, 1, 1, 0, 0, 1, // PC_TRAP
- MCIU, 1, 1, 0, 0, 1, // PC_TWI
- MCIU, 1, 1, 0, 0, 1, // PC_OPWORD
- MCIU, 1, 1, 0, 0, 0, // PC_MFROM
- MCIU, 1, 1, 0, 0, 1, // PC_DSA
- MCIU, 1, 1, 0, 0, 1, // PC_ESA
- MCIU, 0, 0, 0, 0, 0, // PC_DCCCI
- MCIU, 0, 0, 0, 0, 0, // PC_DCREAD
- MCIU, 0, 0, 0, 0, 0, // PC_ICBT
- MCIU, 0, 0, 0, 0, 0, // PC_ICCCI
- MCIU, 0, 0, 0, 0, 0, // PC_ICREAD
- MCIU, 0, 0, 0, 0, 0, // PC_RFCI
- MCIU, 0, 0, 0, 0, 0, // PC_TLBRE
- MCIU, 0, 0, 0, 0, 0, // PC_TLBSX
- MCIU, 0, 0, 0, 0, 0, // PC_TLBWE
- MCIU, 0, 0, 0, 0, 0, // PC_WRTEE
- MCIU, 0, 0, 0, 0, 0, // PC_WRTEEI
- MCIU, 0, 0, 0, 0, 0, // PC_MFDCR
- MCIU, 0, 0, 0, 0, 0, // PC_MTDCR
- MCIU, 0, 0, 0, 0, 0, // PC_DCBA
- SCIU, 0, 0, 0, 0, 0, // PC_DSS
- SCIU, 0, 0, 0, 0, 0, // PC_DSSALL
- SCIU, 0, 0, 0, 0, 0, // PC_DST
- SCIU, 0, 0, 0, 0, 0, // PC_DSTT
- SCIU, 0, 0, 0, 0, 0, // PC_DSTST
- SCIU, 0, 0, 0, 0, 0, // PC_DSTSTT
- SCIU, 0, 0, 0, 0, 0, // PC_LVEBX
- SCIU, 0, 0, 0, 0, 0, // PC_LVEHX
- SCIU, 0, 0, 0, 0, 0, // PC_LVEWX
- SCIU, 0, 0, 0, 0, 0, // PC_LVSL
- SCIU, 0, 0, 0, 0, 0, // PC_LVSR
- SCIU, 0, 0, 0, 0, 0, // PC_LVX
- SCIU, 0, 0, 0, 0, 0, // PC_LVXL
- SCIU, 0, 0, 0, 0, 0, // PC_STVEBX
- SCIU, 0, 0, 0, 0, 0, // PC_STVEHX
- SCIU, 0, 0, 0, 0, 0, // PC_STVEWX
- SCIU, 0, 0, 0, 0, 0, // PC_STVX
- SCIU, 0, 0, 0, 0, 0, // PC_STVXL
- SCIU, 0, 0, 0, 0, 0, // PC_MFVSCR
- SCIU, 0, 0, 0, 0, 0, // PC_MTVSCR
- SCIU, 0, 0, 0, 0, 0, // PC_VADDCUW
- SCIU, 0, 0, 0, 0, 0, // PC_VADDFP
- SCIU, 0, 0, 0, 0, 0, // PC_VADDSBS
- SCIU, 0, 0, 0, 0, 0, // PC_VADDSHS
- SCIU, 0, 0, 0, 0, 0, // PC_VADDSWS
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUBM
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUBS
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUHM
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUHS
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUWM
- SCIU, 0, 0, 0, 0, 0, // PC_VADDUWS
- SCIU, 0, 0, 0, 0, 0, // PC_VAND
- SCIU, 0, 0, 0, 0, 0, // PC_VANDC
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGSB
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGSH
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGSW
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGUB
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGUH
- SCIU, 0, 0, 0, 0, 0, // PC_VAVGUW
- SCIU, 0, 0, 0, 0, 0, // PC_VCFSX
- SCIU, 0, 0, 0, 0, 0, // PC_VCFUX
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPBFP
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- SCIU, 0, 0, 0, 0, 0, // PC_VCTSXS
- SCIU, 0, 0, 0, 0, 0, // PC_VCTUXS
- SCIU, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- SCIU, 0, 0, 0, 0, 0, // PC_VLOGEFP
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXFP
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXSB
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXSH
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXSW
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXUB
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXUH
- SCIU, 0, 0, 0, 0, 0, // PC_VMAXUW
- SCIU, 0, 0, 0, 0, 0, // PC_VMINFP
- SCIU, 0, 0, 0, 0, 0, // PC_VMINSB
- SCIU, 0, 0, 0, 0, 0, // PC_VMINSH
- SCIU, 0, 0, 0, 0, 0, // PC_VMINSW
- SCIU, 0, 0, 0, 0, 0, // PC_VMINUB
- SCIU, 0, 0, 0, 0, 0, // PC_VMINUH
- SCIU, 0, 0, 0, 0, 0, // PC_VMINUW
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGHB
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGHH
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGHW
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGLB
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGLH
- SCIU, 0, 0, 0, 0, 0, // PC_VMRGLW
- SCIU, 0, 0, 0, 0, 0, // PC_VMULESB
- SCIU, 0, 0, 0, 0, 0, // PC_VMULESH
- SCIU, 0, 0, 0, 0, 0, // PC_VMULEUB
- SCIU, 0, 0, 0, 0, 0, // PC_VMULEUH
- SCIU, 0, 0, 0, 0, 0, // PC_VMULOSB
- SCIU, 0, 0, 0, 0, 0, // PC_VMULOSH
- SCIU, 0, 0, 0, 0, 0, // PC_VMULOUB
- SCIU, 0, 0, 0, 0, 0, // PC_VMULOUH
- SCIU, 0, 0, 0, 0, 0, // PC_VNOR
- SCIU, 0, 0, 0, 0, 0, // PC_VOR
- SCIU, 0, 0, 0, 0, 0, // PC_VPKPX
- SCIU, 0, 0, 0, 0, 0, // PC_VPKSHSS
- SCIU, 0, 0, 0, 0, 0, // PC_VPKSHUS
- SCIU, 0, 0, 0, 0, 0, // PC_VPKSWSS
- SCIU, 0, 0, 0, 0, 0, // PC_VPKSWUS
- SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUM
- SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUS
- SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUM
- SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUS
- SCIU, 0, 0, 0, 0, 0, // PC_VREFP
- SCIU, 0, 0, 0, 0, 0, // PC_VRFIM
- SCIU, 0, 0, 0, 0, 0, // PC_VRFIN
- SCIU, 0, 0, 0, 0, 0, // PC_VRFIP
- SCIU, 0, 0, 0, 0, 0, // PC_VRFIZ
- SCIU, 0, 0, 0, 0, 0, // PC_VRLB
- SCIU, 0, 0, 0, 0, 0, // PC_VRLH
- SCIU, 0, 0, 0, 0, 0, // PC_VRLW
- SCIU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- SCIU, 0, 0, 0, 0, 0, // PC_VSL
- SCIU, 0, 0, 0, 0, 0, // PC_VSLB
- SCIU, 0, 0, 0, 0, 0, // PC_VSLH
- SCIU, 0, 0, 0, 0, 0, // PC_VSLO
- SCIU, 0, 0, 0, 0, 0, // PC_VSLW
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTB
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTH
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTW
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISB
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISH
- SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISW
- SCIU, 0, 0, 0, 0, 0, // PC_VSR
- SCIU, 0, 0, 0, 0, 0, // PC_VSRAB
- SCIU, 0, 0, 0, 0, 0, // PC_VSRAH
- SCIU, 0, 0, 0, 0, 0, // PC_VSRAW
- SCIU, 0, 0, 0, 0, 0, // PC_VSRB
- SCIU, 0, 0, 0, 0, 0, // PC_VSRH
- SCIU, 0, 0, 0, 0, 0, // PC_VSRO
- SCIU, 0, 0, 0, 0, 0, // PC_VSRW
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBCUW
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBFP
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBSBS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBSHS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBSWS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBM
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHM
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWM
- SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUMSWS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUM2SWS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SBS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SHS
- SCIU, 0, 0, 0, 0, 0, // PC_VSUM4UBS
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKHPX
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSB
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSH
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKLPX
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSB
- SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSH
- SCIU, 0, 0, 0, 0, 0, // PC_VXOR
- SCIU, 0, 0, 0, 0, 0, // PC_VMADDFP
- SCIU, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- SCIU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- SCIU, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- SCIU, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- SCIU, 0, 0, 0, 0, 0, // PC_VPERM
- SCIU, 0, 0, 0, 0, 0, // PC_VSEL
- SCIU, 0, 0, 0, 0, 0, // PC_VSLDOI
- SCIU, 0, 0, 0, 0, 0, // PC_VMR
- SCIU, 0, 0, 0, 0, 0, // PC_VMRP
- SCIU, 0, 0, 0, 0, 0, // PC_SLE
- SCIU, 0, 0, 0, 0, 0, // PC_SLEQ
- SCIU, 0, 0, 0, 0, 0, // PC_SLIQ
- SCIU, 0, 0, 0, 0, 0, // PC_SLLIQ
- SCIU, 0, 0, 0, 0, 0, // PC_SLLQ
- SCIU, 0, 0, 0, 0, 0, // PC_SLQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRAIQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRAQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRE
- SCIU, 0, 0, 0, 0, 0, // PC_SREA
- SCIU, 0, 0, 0, 0, 0, // PC_SREQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRIQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRLIQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRLQ
- SCIU, 0, 0, 0, 0, 0, // PC_SRQ
- SCIU, 0, 0, 0, 0, 0, // PC_MASKG
- SCIU, 0, 0, 0, 0, 0, // PC_MASKIR
- SCIU, 0, 0, 0, 0, 0, // PC_LSCBX
- SCIU, 0, 0, 0, 0, 0, // PC_DIV
- SCIU, 0, 0, 0, 0, 0, // PC_DIVS
- SCIU, 0, 0, 0, 0, 0, // PC_DOZ
- SCIU, 0, 0, 0, 0, 0, // PC_MUL
- SCIU, 0, 0, 0, 0, 0, // PC_NABS
- SCIU, 0, 0, 0, 0, 0, // PC_ABS
- SCIU, 0, 0, 0, 0, 0, // PC_CLCS
- SCIU, 0, 0, 0, 0, 0, // PC_DOZI
- SCIU, 0, 0, 0, 0, 0, // PC_RLMI
- SCIU, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-
- if (stage == SCIU)
- sciu_completed_instruction = instr;
- else if (stage == SCIU2)
- sciu2_completed_instruction = instr;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-
- sciu_completed_instruction = NULL;
- sciu2_completed_instruction = NULL;
-}
-
-static int can_issue(PCode *instr) {
- PCode *check;
- int stage = instruction_timing[instr->op].stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- if (stage == SCIU) {
- int isClear1 = !pipeline[SCIU].instr;
- int isClear2 = !pipeline[SCIU2].instr;
- if (!isClear1 && !isClear2)
- return 0;
- if (isClear1 && isClear2)
- return 1;
-
- if (isClear1)
- check = pipeline[SCIU2].instr;
- else
- check = pipeline[SCIU].instr;
-
- if (is_dependent(instr, check, RegClass_GPR))
- return 0;
- if (is_dependent(instr, sciu_completed_instruction, RegClass_GPR))
- return 0;
- if (is_dependent(instr, sciu2_completed_instruction, RegClass_GPR))
- return 0;
- } else {
- if (pipeline[stage].instr)
- return 0;
- }
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- if (stage == SCIU && pipeline[SCIU].instr)
- stage = SCIU2;
- assign_completion_buffer(instr);
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
- int i;
-
- sciu_completed_instruction = NULL;
- sciu2_completed_instruction = NULL;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- for (i = 0; i < 5; i++) {
- if (completionbuffers.used == 0)
- break;
- if (completionbuffers.entries[completionbuffers.nextToRetire].completed == 0)
- break;
- retire_instruction();
- }
-
- if (pipeline[SCIU].instr && pipeline[SCIU].remaining == 0)
- complete_instruction(SCIU);
- if (pipeline[SCIU2].instr && pipeline[SCIU2].remaining == 0)
- complete_instruction(SCIU2);
- if (pipeline[MCIU].instr && pipeline[MCIU].remaining == 0)
- complete_instruction(MCIU);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
- complete_instruction(FPU3);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
-
- if (
- pipeline[FPU1].instr &&
- pipeline[FPU1].remaining == 0 &&
- (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
- )
- complete_instruction(FPU1);
-
- if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
- advance(FPU1, FPU2, FPU3);
- if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
- advance(FPU1, FPU1, FPU2);
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-MachineInfo machine604 = {
- 4,
- 1,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation7400.c b/compiler_and_linker/unsorted/MachineSimulation7400.c
deleted file mode 100644
index 56b375c..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation7400.c
+++ /dev/null
@@ -1,744 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://www.nxp.com/docs/en/reference-manual/MPC7410UM.pdf
-
-typedef enum Stage {
- BPU, // Branch Prediction Unit
- IU1, // Integer Unit 1
- IU2, // Integer Unit 2
-
- LSU1, // Load/Store Unit
- LSU2,
-
- FPU1, // Floating Point Unit
- FPU2,
- FPU3,
-
- SRU, // System Register Unit
- VSIU, // Vector Simple Integer Unit
- VPU, // AltiVec Permute Unit
-
- VCIU1, // Vector Complex Integer Unit
- VCIU2,
- VCIU3,
-
- VFPU1, // Vector Floating-Point Unit
- VFPU2,
- VFPU3,
- VFPU4,
-
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-static PCode *iu1_completed_instruction;
-static PCode *iu2_completed_instruction;
-
-enum {
- MaxEntries = 8
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[4];
-
- // does this instruction serialise?
- char serializes;
-
- char unused;
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_B
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BL
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BC
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCLR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCCTR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BT
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTLR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTCTR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BF
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFLR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFCTR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZT
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZF
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZT
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZF
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTRL
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLRL
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LMW
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STB
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STH
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHBRX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STW
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STMW
- LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBF
- LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DCBTST
- LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBZ
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADD
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDE
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDICR
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIS
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDME
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDZE
- IU1, 19, 19, 0, 0, 0, 0, 0, // PC_DIVW
- IU1, 19, 19, 0, 0, 0, 0, 0, // PC_DIVWU
- IU1, 5, 5, 0, 0, 0, 0, 0, // PC_MULHW
- IU1, 6, 5, 0, 0, 0, 0, 0, // PC_MULHWU
- IU1, 3, 3, 0, 0, 0, 0, 0, // PC_MULLI
- IU1, 5, 5, 0, 0, 0, 0, 0, // PC_MULLW
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NEG
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBF
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFE
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFIC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFME
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFZE
- IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPI
- IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMP
- IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPLI
- IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPL
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDIS
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORIS
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XORI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XORIS
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_AND
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_OR
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XOR
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NAND
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOR
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EQV
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSB
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSH
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_CNTLZW
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWINM
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWNM
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWIMI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SLW
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRW
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRAWI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRAW
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRAND
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRANDC
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CREQV
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRNAND
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRNOR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CROR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRORC
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRXOR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRF
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTXER
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTCTR
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTLR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MTCRF
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MTMSR
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSPR
- SRU, 1, 1, 0, 0, 0, 0, 0, // PC_MFMSR
- SRU, 3, 3, 0, 0, 0, 1, 0, // PC_MFSPR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFXER
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFCTR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFLR
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFCR
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_MFFS
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_MTFSF
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_EIEIO
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_ISYNC
- SRU, 3, 3, 0, 0, 0, 1, 0, // PC_SYNC
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_RFI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_LI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_LIS
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_MR
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOP
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOT
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFS
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFD
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFS
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSUX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFD
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDU
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDUX
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMR
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FABS
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNEG
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNABS
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FADD
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FADDS
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSUB
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSUBS
- FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMUL
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMULS
- FPU1, 31, 31, 0, 0, 0, 0, 0, // PC_FDIV
- FPU1, 17, 17, 0, 0, 0, 0, 0, // PC_FDIVS
- FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMADD
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMADDS
- FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMSUB
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMSUBS
- FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FNMADD
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNMADDS
- FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FNMSUB
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNMSUBS
- FPU1, 10, 10, 0, 0, 0, 0, 0, // PC_FRES
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FRSQRTE
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSEL
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FRSP
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCTIW
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCTIWZ
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCMPU
- FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCMPO
- LSU1, 2, 1, 1, 0, 0, 1, 0, // PC_LWARX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LSWI
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LSWX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFIWX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STSWI
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STSWX
- LSU1, 2, 1, 1, 0, 0, 1, 0, // PC_STWCX
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ECIWX
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ECOWX
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_DCBI
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ICBI
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRFS
- SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRXR
- SRU, 1, 1, 0, 0, 0, 0, 0, // PC_MFTB
- SRU, 3, 3, 0, 0, 0, 0, 0, // PC_MFSR
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSR
- SRU, 3, 3, 0, 0, 0, 0, 0, // PC_MFSRIN
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSRIN
- FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSB0
- FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSB1
- FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSFI
- SRU, 2, 2, 0, 0, 0, 1, 0, // PC_SC
- FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRT
- FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRTS
- LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIA
- LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIE
- LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBLD
- LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBLI
- LSU1, 1, 1, 0, 0, 0, 1, 0, // PC_TLBSYNC
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TW
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TRAP
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TWI
- IU2, 1, 1, 0, 0, 0, 1, 0, // PC_OPWORD
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_MFROM
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_DSA
- IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ESA
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_DCCCI
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_DCREAD
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICBT
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICCCI
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICREAD
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_RFCI
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBRE
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBSX
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBWE
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEE
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEEI
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_MFDCR
- IU2, 1, 0, 0, 0, 0, 0, 0, // PC_MTDCR
- LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBA
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSS
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSSALL
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DST
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTT
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTST
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTSTT
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEBX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEHX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEWX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVSL
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVSR
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVXL
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEBX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEHX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEWX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVX
- LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVXL
- VSIU, 1, 1, 0, 0, 0, 1, 0, // PC_MFVSCR
- VSIU, 1, 1, 0, 0, 0, 1, 0, // PC_MTVSCR
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDCUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VADDFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSBS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSHS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSWS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAND
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VANDC
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFSX
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFUX
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPBFP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPEQFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPGEFP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPGTFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTSXS
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTUXS
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VEXPTEFP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VLOGEFP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMAXFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMINFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUW
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHW
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLW
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULESB
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULESH
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULEUB
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULEUH
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOSB
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOSH
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOUB
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOUH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VNOR
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VOR
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKPX
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSHSS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSHUS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSWSS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSWUS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUHUM
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUHUS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUWUM
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUWUS
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VREFP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIM
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIN
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIP
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIZ
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRSQRTEFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSL
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLO
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLW
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTW
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSR
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRB
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRO
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRW
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBCUW
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUBFP
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSBS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSHS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSWS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHS
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUMSWS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM2SWS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4SBS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4SHS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4UBS
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHPX
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHSB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHSH
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLPX
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLSB
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLSH
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VXOR
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMADDFP
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMHADDSHS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMHRADDSHS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMLADDUHM
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMMBM
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMSHM
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMSHS
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUBM
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUHM
- VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUHS
- VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VNMSUBFP
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPERM
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSEL
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLDOI
- VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMR
- VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRP
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLE
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLEQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLIQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLLIQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLLQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRAIQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRAQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRE
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SREA
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SREQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRIQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRLIQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRLQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRQ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MASKG
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MASKIR
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_LSCBX
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DIV
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DIVS
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DOZ
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MUL
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_NABS
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_ABS
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_CLCS
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DOZI
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_RLMI
- BPU, 0, 0, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-
- if (stage == IU1)
- iu1_completed_instruction = instr;
- else if (stage == IU2)
- iu2_completed_instruction = instr;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-
- iu1_completed_instruction = NULL;
- iu2_completed_instruction = NULL;
-}
-
-static int can_issue(PCode *instr) {
- int stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- stage = instruction_timing[instr->op].stage;
-
- if (stage == IU2) {
- PCode *check;
- int isClear1 = !pipeline[IU1].instr;
- int isClear2 = !pipeline[IU2].instr;
- if (!isClear1 && !isClear2)
- return 0;
- if (isClear1 && isClear2)
- return 1;
-
- if (isClear1)
- check = pipeline[IU2].instr;
- else
- check = pipeline[IU1].instr;
-
- if (is_dependent(instr, check, RegClass_GPR))
- return 0;
- if (is_dependent(instr, iu1_completed_instruction, RegClass_GPR))
- return 0;
- if (is_dependent(instr, iu2_completed_instruction, RegClass_GPR))
- return 0;
- } else if (stage == VFPU1 || stage == VCIU1 || stage == VSIU || stage == VPU) {
- PCode *check;
- int isVpuClear = !pipeline[VPU].instr;
- int isVFpuClear = !pipeline[VFPU1].instr;
- int isVCiuClear = !pipeline[VCIU1].instr;
- int isVSiuClear = !pipeline[VSIU].instr;
-
- if (stage == VPU) {
- if (!isVpuClear)
- return 0;
-
- if (!isVFpuClear)
- check = pipeline[VFPU1].instr;
- else if (!isVCiuClear)
- check = pipeline[VCIU1].instr;
- else if (!isVSiuClear)
- check = pipeline[VSIU].instr;
- else
- check = NULL;
-
- if (is_dependent(instr, check, RegClass_VR))
- return 0;
- } else {
- if (!isVFpuClear || !isVCiuClear || !isVSiuClear)
- return 0;
-
- if (!isVpuClear && is_dependent(instr, pipeline[VPU].instr, RegClass_VR))
- return 0;
- }
- } else {
- if (pipeline[stage].instr)
- return 0;
- }
-
- if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
- return 0;
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- assign_completion_buffer(instr);
- if (stage == IU2 && !pipeline[IU1].instr)
- stage = IU1;
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- iu1_completed_instruction = NULL;
- iu2_completed_instruction = NULL;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- }
- }
-
- if (pipeline[IU1].instr && pipeline[IU1].remaining == 0)
- complete_instruction(IU1);
- if (pipeline[VPU].instr && pipeline[VPU].remaining == 0)
- complete_instruction(VPU);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
- complete_instruction(FPU3);
- if (pipeline[SRU].instr && pipeline[SRU].remaining == 0)
- complete_instruction(SRU);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
- if (pipeline[VSIU].instr && pipeline[VSIU].remaining == 0)
- complete_instruction(VSIU);
- if (pipeline[VCIU3].instr && pipeline[VCIU3].remaining == 0)
- complete_instruction(VCIU3);
- if (pipeline[VFPU4].instr && pipeline[VFPU4].remaining == 0)
- complete_instruction(VFPU4);
- if (pipeline[IU2].instr && pipeline[IU2].remaining == 0)
- complete_instruction(IU2);
-
- if (
- pipeline[FPU1].instr &&
- pipeline[FPU1].remaining == 0 &&
- (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
- )
- complete_instruction(FPU1);
-
- if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
- advance(FPU1, FPU2, FPU3);
- if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
- advance(FPU1, FPU1, FPU2);
-
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-
- if (pipeline[VCIU2].instr && pipeline[VCIU2].remaining == 0 && !pipeline[VCIU3].instr)
- advance(VCIU1, VCIU2, VCIU3);
- if (pipeline[VCIU1].instr && pipeline[VCIU1].remaining == 0 && !pipeline[VCIU2].instr)
- advance(VCIU1, VCIU1, VCIU2);
-
- if (pipeline[VFPU3].instr && pipeline[VFPU3].remaining == 0 && !pipeline[VFPU4].instr)
- advance(VFPU1, VFPU3, VFPU4);
- if (pipeline[VFPU2].instr && pipeline[VFPU2].remaining == 0 && !pipeline[VFPU3].instr)
- advance(VFPU1, VFPU2, VFPU3);
- if (pipeline[VFPU1].instr && pipeline[VFPU1].remaining == 0 && !pipeline[VFPU2].instr)
- advance(VFPU1, VFPU1, VFPU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-static int uses_vpermute_unit_7400(PCode *instr) {
- return instruction_timing[instr->op].stage == VPU;
-}
-
-MachineInfo machine7400 = {
- 2,
- 1,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &uses_vpermute_unit_7400
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation750.c b/compiler_and_linker/unsorted/MachineSimulation750.c
deleted file mode 100644
index d412df3..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation750.c
+++ /dev/null
@@ -1,678 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://www.nxp.com/docs/en/reference-manual/MPC750UM.pdf
-
-typedef enum Stage {
- BPU, // Branch Prediction Unit
- IU1, // Integer Unit 1
- IU2, // Integer Unit 2
-
- LSU1, // Load/Store Unit
- LSU2,
-
- FPU1, // Floating Point Unit
- FPU2,
- FPU3,
-
- SRU, // System Register Unit
-
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-static PCode *iu1_completed_instruction;
-static PCode *iu2_completed_instruction;
-
-enum {
- MaxEntries = 6
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[3];
-
- // does this instruction serialise?
- char serializes;
-} instruction_timing[OPCODE_MAX] = {
- BPU, 0, 0, 0, 0, 1, // PC_B
- BPU, 0, 0, 0, 0, 1, // PC_BL
- BPU, 0, 0, 0, 0, 1, // PC_BC
- BPU, 0, 0, 0, 0, 1, // PC_BCLR
- BPU, 0, 0, 0, 0, 1, // PC_BCCTR
- BPU, 0, 0, 0, 0, 1, // PC_BT
- BPU, 0, 0, 0, 0, 1, // PC_BTLR
- BPU, 0, 0, 0, 0, 1, // PC_BTCTR
- BPU, 0, 0, 0, 0, 1, // PC_BF
- BPU, 0, 0, 0, 0, 1, // PC_BFLR
- BPU, 0, 0, 0, 0, 1, // PC_BFCTR
- BPU, 0, 0, 0, 0, 1, // PC_BDNZ
- BPU, 0, 0, 0, 0, 1, // PC_BDNZT
- BPU, 0, 0, 0, 0, 1, // PC_BDNZF
- BPU, 0, 0, 0, 0, 1, // PC_BDZ
- BPU, 0, 0, 0, 0, 1, // PC_BDZT
- BPU, 0, 0, 0, 0, 1, // PC_BDZF
- BPU, 0, 0, 0, 0, 1, // PC_BLR
- BPU, 0, 0, 0, 0, 1, // PC_BCTR
- BPU, 0, 0, 0, 0, 1, // PC_BCTRL
- BPU, 0, 0, 0, 0, 1, // PC_BLRL
- LSU1, 2, 1, 1, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LMW
- LSU1, 2, 1, 1, 0, 0, // PC_STB
- LSU1, 2, 1, 1, 0, 0, // PC_STBU
- LSU1, 2, 1, 1, 0, 0, // PC_STBX
- LSU1, 2, 1, 1, 0, 0, // PC_STBUX
- LSU1, 2, 1, 1, 0, 0, // PC_STH
- LSU1, 2, 1, 1, 0, 0, // PC_STHU
- LSU1, 2, 1, 1, 0, 0, // PC_STHX
- LSU1, 2, 1, 1, 0, 0, // PC_STHUX
- LSU1, 2, 1, 1, 0, 0, // PC_STHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STW
- LSU1, 2, 1, 1, 0, 0, // PC_STWU
- LSU1, 2, 1, 1, 0, 0, // PC_STWX
- LSU1, 2, 1, 1, 0, 0, // PC_STWUX
- LSU1, 2, 1, 1, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STMW
- LSU1, 3, 1, 2, 0, 0, // PC_DCBF
- LSU1, 3, 1, 2, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
- LSU1, 3, 1, 2, 0, 0, // PC_DCBZ
- IU2, 1, 1, 0, 0, 0, // PC_ADD
- IU2, 1, 1, 0, 0, 0, // PC_ADDC
- IU2, 1, 1, 0, 0, 0, // PC_ADDE
- IU2, 1, 1, 0, 0, 0, // PC_ADDI
- IU2, 1, 1, 0, 0, 0, // PC_ADDIC
- IU2, 1, 1, 0, 0, 0, // PC_ADDICR
- IU2, 1, 1, 0, 0, 0, // PC_ADDIS
- IU2, 1, 1, 0, 0, 0, // PC_ADDME
- IU2, 1, 1, 0, 0, 0, // PC_ADDZE
- IU1, 19, 19, 0, 0, 0, // PC_DIVW
- IU1, 19, 19, 0, 0, 0, // PC_DIVWU
- IU1, 5, 5, 0, 0, 0, // PC_MULHW
- IU1, 6, 5, 0, 0, 0, // PC_MULHWU
- IU1, 3, 3, 0, 0, 0, // PC_MULLI
- IU1, 5, 5, 0, 0, 0, // PC_MULLW
- IU2, 1, 1, 0, 0, 0, // PC_NEG
- IU2, 1, 1, 0, 0, 0, // PC_SUBF
- IU2, 1, 1, 0, 0, 0, // PC_SUBFC
- IU2, 1, 1, 0, 0, 0, // PC_SUBFE
- IU2, 1, 1, 0, 0, 0, // PC_SUBFIC
- IU2, 1, 1, 0, 0, 0, // PC_SUBFME
- IU2, 1, 1, 0, 0, 0, // PC_SUBFZE
- IU2, 3, 1, 0, 0, 0, // PC_CMPI
- IU2, 3, 1, 0, 0, 0, // PC_CMP
- IU2, 3, 1, 0, 0, 0, // PC_CMPLI
- IU2, 3, 1, 0, 0, 0, // PC_CMPL
- IU2, 1, 1, 0, 0, 0, // PC_ANDI
- IU2, 1, 1, 0, 0, 0, // PC_ANDIS
- IU2, 1, 1, 0, 0, 0, // PC_ORI
- IU2, 1, 1, 0, 0, 0, // PC_ORIS
- IU2, 1, 1, 0, 0, 0, // PC_XORI
- IU2, 1, 1, 0, 0, 0, // PC_XORIS
- IU2, 1, 1, 0, 0, 0, // PC_AND
- IU2, 1, 1, 0, 0, 0, // PC_OR
- IU2, 1, 1, 0, 0, 0, // PC_XOR
- IU2, 1, 1, 0, 0, 0, // PC_NAND
- IU2, 1, 1, 0, 0, 0, // PC_NOR
- IU2, 1, 1, 0, 0, 0, // PC_EQV
- IU2, 1, 1, 0, 0, 0, // PC_ANDC
- IU2, 1, 1, 0, 0, 0, // PC_ORC
- IU2, 1, 1, 0, 0, 0, // PC_EXTSB
- IU2, 1, 1, 0, 0, 0, // PC_EXTSH
- IU2, 1, 1, 0, 0, 0, // PC_CNTLZW
- IU2, 1, 1, 0, 0, 0, // PC_RLWINM
- IU2, 1, 1, 0, 0, 0, // PC_RLWNM
- IU2, 1, 1, 0, 0, 0, // PC_RLWIMI
- IU2, 1, 1, 0, 0, 0, // PC_SLW
- IU2, 1, 1, 0, 0, 0, // PC_SRW
- IU2, 1, 1, 0, 0, 0, // PC_SRAWI
- IU2, 1, 1, 0, 0, 0, // PC_SRAW
- SRU, 1, 1, 0, 0, 1, // PC_CRAND
- SRU, 1, 1, 0, 0, 1, // PC_CRANDC
- SRU, 1, 1, 0, 0, 1, // PC_CREQV
- SRU, 1, 1, 0, 0, 1, // PC_CRNAND
- SRU, 1, 1, 0, 0, 1, // PC_CRNOR
- SRU, 1, 1, 0, 0, 1, // PC_CROR
- SRU, 1, 1, 0, 0, 1, // PC_CRORC
- SRU, 1, 1, 0, 0, 1, // PC_CRXOR
- SRU, 1, 1, 0, 0, 1, // PC_MCRF
- SRU, 2, 2, 0, 0, 1, // PC_MTXER
- SRU, 2, 2, 0, 0, 1, // PC_MTCTR
- SRU, 2, 2, 0, 0, 1, // PC_MTLR
- SRU, 1, 1, 0, 0, 1, // PC_MTCRF
- SRU, 1, 1, 0, 0, 0, // PC_MTMSR
- SRU, 1, 1, 0, 0, 1, // PC_MTSPR
- SRU, 1, 1, 0, 0, 1, // PC_MFMSR
- SRU, 1, 1, 0, 0, 1, // PC_MFSPR
- SRU, 1, 1, 0, 0, 1, // PC_MFXER
- SRU, 1, 1, 0, 0, 1, // PC_MFCTR
- SRU, 1, 1, 0, 0, 1, // PC_MFLR
- SRU, 1, 1, 0, 0, 1, // PC_MFCR
- FPU1, 3, 1, 1, 1, 0, // PC_MFFS
- FPU1, 3, 1, 1, 1, 0, // PC_MTFSF
- SRU, 1, 1, 0, 0, 1, // PC_EIEIO
- SRU, 2, 2, 0, 0, 1, // PC_ISYNC
- SRU, 3, 3, 0, 0, 1, // PC_SYNC
- SRU, 1, 1, 0, 0, 1, // PC_RFI
- IU2, 1, 1, 0, 0, 0, // PC_LI
- IU2, 1, 1, 0, 0, 0, // PC_LIS
- IU2, 1, 1, 0, 0, 0, // PC_MR
- IU2, 1, 1, 0, 0, 0, // PC_NOP
- IU2, 1, 1, 0, 0, 0, // PC_NOT
- LSU1, 2, 1, 1, 0, 0, // PC_LFS
- LSU1, 2, 1, 1, 0, 0, // PC_LFSU
- LSU1, 2, 1, 1, 0, 0, // PC_LFSX
- LSU1, 2, 1, 1, 0, 0, // PC_LFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_LFD
- LSU1, 2, 1, 1, 0, 0, // PC_LFDU
- LSU1, 2, 1, 1, 0, 0, // PC_LFDX
- LSU1, 2, 1, 1, 0, 0, // PC_LFDUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFS
- LSU1, 2, 1, 1, 0, 0, // PC_STFSU
- LSU1, 2, 1, 1, 0, 0, // PC_STFSX
- LSU1, 2, 1, 1, 0, 0, // PC_STFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFD
- LSU1, 2, 1, 1, 0, 0, // PC_STFDU
- LSU1, 2, 1, 1, 0, 0, // PC_STFDX
- LSU1, 2, 1, 1, 0, 0, // PC_STFDUX
- FPU1, 3, 1, 1, 1, 0, // PC_FMR
- FPU1, 3, 1, 1, 1, 0, // PC_FABS
- FPU1, 3, 1, 1, 1, 0, // PC_FNEG
- FPU1, 3, 1, 1, 1, 0, // PC_FNABS
- FPU1, 3, 1, 1, 1, 0, // PC_FADD
- FPU1, 3, 1, 1, 1, 0, // PC_FADDS
- FPU1, 3, 1, 1, 1, 0, // PC_FSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FMUL
- FPU1, 3, 1, 1, 1, 0, // PC_FMULS
- FPU1, 31, 31, 0, 0, 0, // PC_FDIV
- FPU1, 17, 17, 0, 0, 0, // PC_FDIVS
- FPU1, 4, 2, 1, 1, 0, // PC_FMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMADD
- FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS
- FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB
- FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS
- FPU1, 10, 10, 0, 0, 0, // PC_FRES
- FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE
- FPU1, 3, 1, 1, 1, 0, // PC_FSEL
- FPU1, 3, 1, 1, 1, 0, // PC_FRSP
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIW
- FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ
- FPU1, 3, 1, 1, 1, 0, // PC_FCMPU
- FPU1, 3, 1, 1, 1, 0, // PC_FCMPO
- LSU1, 1, 1, 0, 0, 0, // PC_LWARX
- LSU1, 1, 1, 0, 0, 0, // PC_LSWI
- LSU1, 1, 1, 0, 0, 0, // PC_LSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STFIWX
- LSU1, 1, 1, 0, 0, 0, // PC_STSWI
- LSU1, 1, 1, 0, 0, 0, // PC_STSWX
- LSU1, 1, 1, 0, 0, 0, // PC_STWCX
- IU1, 1, 1, 0, 0, 1, // PC_ECIWX
- IU1, 1, 1, 0, 0, 1, // PC_ECOWX
- IU1, 1, 1, 0, 0, 0, // PC_DCBI
- IU1, 1, 1, 0, 0, 0, // PC_ICBI
- IU1, 1, 1, 0, 0, 0, // PC_MCRFS
- IU1, 1, 1, 0, 0, 0, // PC_MCRXR
- IU1, 1, 1, 0, 0, 0, // PC_MFTB
- IU1, 1, 1, 0, 0, 0, // PC_MFSR
- IU1, 1, 1, 0, 0, 0, // PC_MTSR
- IU1, 1, 1, 0, 0, 0, // PC_MFSRIN
- IU1, 1, 1, 0, 0, 0, // PC_MTSRIN
- IU1, 1, 1, 0, 0, 0, // PC_MTFSB0
- IU1, 1, 1, 0, 0, 0, // PC_MTFSB1
- IU1, 1, 1, 0, 0, 0, // PC_MTFSFI
- IU1, 1, 1, 0, 0, 1, // PC_SC
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRT
- FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS
- IU1, 1, 1, 0, 0, 0, // PC_TLBIA
- IU1, 1, 1, 0, 0, 0, // PC_TLBIE
- IU1, 1, 1, 0, 0, 0, // PC_TLBLD
- IU1, 1, 1, 0, 0, 0, // PC_TLBLI
- IU1, 1, 1, 0, 0, 0, // PC_TLBSYNC
- IU1, 1, 1, 0, 0, 1, // PC_TW
- IU1, 1, 1, 0, 0, 1, // PC_TRAP
- IU1, 1, 1, 0, 0, 1, // PC_TWI
- IU1, 1, 1, 0, 0, 1, // PC_OPWORD
- IU1, 1, 1, 0, 0, 0, // PC_MFROM
- IU1, 1, 1, 0, 0, 1, // PC_DSA
- IU1, 1, 1, 0, 0, 1, // PC_ESA
- IU1, 0, 0, 0, 0, 0, // PC_DCCCI
- IU1, 0, 0, 0, 0, 0, // PC_DCREAD
- IU1, 0, 0, 0, 0, 0, // PC_ICBT
- IU1, 0, 0, 0, 0, 0, // PC_ICCCI
- IU1, 0, 0, 0, 0, 0, // PC_ICREAD
- IU1, 0, 0, 0, 0, 0, // PC_RFCI
- IU1, 0, 0, 0, 0, 0, // PC_TLBRE
- IU1, 0, 0, 0, 0, 0, // PC_TLBSX
- IU1, 0, 0, 0, 0, 0, // PC_TLBWE
- IU1, 0, 0, 0, 0, 0, // PC_WRTEE
- IU1, 0, 0, 0, 0, 0, // PC_WRTEEI
- IU1, 0, 0, 0, 0, 0, // PC_MFDCR
- IU1, 0, 0, 0, 0, 0, // PC_MTDCR
- IU1, 0, 0, 0, 0, 0, // PC_DCBA
- BPU, 0, 0, 0, 0, 0, // PC_DSS
- BPU, 0, 0, 0, 0, 0, // PC_DSSALL
- BPU, 0, 0, 0, 0, 0, // PC_DST
- BPU, 0, 0, 0, 0, 0, // PC_DSTT
- BPU, 0, 0, 0, 0, 0, // PC_DSTST
- BPU, 0, 0, 0, 0, 0, // PC_DSTSTT
- BPU, 0, 0, 0, 0, 0, // PC_LVEBX
- BPU, 0, 0, 0, 0, 0, // PC_LVEHX
- BPU, 0, 0, 0, 0, 0, // PC_LVEWX
- BPU, 0, 0, 0, 0, 0, // PC_LVSL
- BPU, 0, 0, 0, 0, 0, // PC_LVSR
- BPU, 0, 0, 0, 0, 0, // PC_LVX
- BPU, 0, 0, 0, 0, 0, // PC_LVXL
- BPU, 0, 0, 0, 0, 0, // PC_STVEBX
- BPU, 0, 0, 0, 0, 0, // PC_STVEHX
- BPU, 0, 0, 0, 0, 0, // PC_STVEWX
- BPU, 0, 0, 0, 0, 0, // PC_STVX
- BPU, 0, 0, 0, 0, 0, // PC_STVXL
- BPU, 0, 0, 0, 0, 0, // PC_MFVSCR
- BPU, 0, 0, 0, 0, 0, // PC_MTVSCR
- BPU, 0, 0, 0, 0, 0, // PC_VADDCUW
- BPU, 0, 0, 0, 0, 0, // PC_VADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VADDSBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDSWS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUBS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUHS
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWM
- BPU, 0, 0, 0, 0, 0, // PC_VADDUWS
- BPU, 0, 0, 0, 0, 0, // PC_VAND
- BPU, 0, 0, 0, 0, 0, // PC_VANDC
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGSW
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUB
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUH
- BPU, 0, 0, 0, 0, 0, // PC_VAVGUW
- BPU, 0, 0, 0, 0, 0, // PC_VCFSX
- BPU, 0, 0, 0, 0, 0, // PC_VCFUX
- BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- BPU, 0, 0, 0, 0, 0, // PC_VCTSXS
- BPU, 0, 0, 0, 0, 0, // PC_VCTUXS
- BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXFP
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXSW
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUB
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUH
- BPU, 0, 0, 0, 0, 0, // PC_VMAXUW
- BPU, 0, 0, 0, 0, 0, // PC_VMINFP
- BPU, 0, 0, 0, 0, 0, // PC_VMINSB
- BPU, 0, 0, 0, 0, 0, // PC_VMINSH
- BPU, 0, 0, 0, 0, 0, // PC_VMINSW
- BPU, 0, 0, 0, 0, 0, // PC_VMINUB
- BPU, 0, 0, 0, 0, 0, // PC_VMINUH
- BPU, 0, 0, 0, 0, 0, // PC_VMINUW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGHW
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLB
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLH
- BPU, 0, 0, 0, 0, 0, // PC_VMRGLW
- BPU, 0, 0, 0, 0, 0, // PC_VMULESB
- BPU, 0, 0, 0, 0, 0, // PC_VMULESH
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULEUH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOSH
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUB
- BPU, 0, 0, 0, 0, 0, // PC_VMULOUH
- BPU, 0, 0, 0, 0, 0, // PC_VNOR
- BPU, 0, 0, 0, 0, 0, // PC_VOR
- BPU, 0, 0, 0, 0, 0, // PC_VPKPX
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS
- BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM
- BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS
- BPU, 0, 0, 0, 0, 0, // PC_VREFP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIM
- BPU, 0, 0, 0, 0, 0, // PC_VRFIN
- BPU, 0, 0, 0, 0, 0, // PC_VRFIP
- BPU, 0, 0, 0, 0, 0, // PC_VRFIZ
- BPU, 0, 0, 0, 0, 0, // PC_VRLB
- BPU, 0, 0, 0, 0, 0, // PC_VRLH
- BPU, 0, 0, 0, 0, 0, // PC_VRLW
- BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- BPU, 0, 0, 0, 0, 0, // PC_VSL
- BPU, 0, 0, 0, 0, 0, // PC_VSLB
- BPU, 0, 0, 0, 0, 0, // PC_VSLH
- BPU, 0, 0, 0, 0, 0, // PC_VSLO
- BPU, 0, 0, 0, 0, 0, // PC_VSLW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTW
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH
- BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW
- BPU, 0, 0, 0, 0, 0, // PC_VSR
- BPU, 0, 0, 0, 0, 0, // PC_VSRAB
- BPU, 0, 0, 0, 0, 0, // PC_VSRAH
- BPU, 0, 0, 0, 0, 0, // PC_VSRAW
- BPU, 0, 0, 0, 0, 0, // PC_VSRB
- BPU, 0, 0, 0, 0, 0, // PC_VSRH
- BPU, 0, 0, 0, 0, 0, // PC_VSRO
- BPU, 0, 0, 0, 0, 0, // PC_VSRW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW
- BPU, 0, 0, 0, 0, 0, // PC_VSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM
- BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS
- BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB
- BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH
- BPU, 0, 0, 0, 0, 0, // PC_VXOR
- BPU, 0, 0, 0, 0, 0, // PC_VMADDFP
- BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- BPU, 0, 0, 0, 0, 0, // PC_VPERM
- BPU, 0, 0, 0, 0, 0, // PC_VSEL
- BPU, 0, 0, 0, 0, 0, // PC_VSLDOI
- BPU, 0, 0, 0, 0, 0, // PC_VMR
- BPU, 0, 0, 0, 0, 0, // PC_VMRP
- BPU, 0, 0, 0, 0, 0, // PC_SLE
- BPU, 0, 0, 0, 0, 0, // PC_SLEQ
- BPU, 0, 0, 0, 0, 0, // PC_SLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SLLQ
- BPU, 0, 0, 0, 0, 0, // PC_SLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRAQ
- BPU, 0, 0, 0, 0, 0, // PC_SRE
- BPU, 0, 0, 0, 0, 0, // PC_SREA
- BPU, 0, 0, 0, 0, 0, // PC_SREQ
- BPU, 0, 0, 0, 0, 0, // PC_SRIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLIQ
- BPU, 0, 0, 0, 0, 0, // PC_SRLQ
- BPU, 0, 0, 0, 0, 0, // PC_SRQ
- BPU, 0, 0, 0, 0, 0, // PC_MASKG
- BPU, 0, 0, 0, 0, 0, // PC_MASKIR
- BPU, 0, 0, 0, 0, 0, // PC_LSCBX
- BPU, 0, 0, 0, 0, 0, // PC_DIV
- BPU, 0, 0, 0, 0, 0, // PC_DIVS
- BPU, 0, 0, 0, 0, 0, // PC_DOZ
- BPU, 0, 0, 0, 0, 0, // PC_MUL
- BPU, 0, 0, 0, 0, 0, // PC_NABS
- BPU, 0, 0, 0, 0, 0, // PC_ABS
- BPU, 0, 0, 0, 0, 0, // PC_CLCS
- BPU, 0, 0, 0, 0, 0, // PC_DOZI
- BPU, 0, 0, 0, 0, 0, // PC_RLMI
- BPU, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-
- if (stage == IU1)
- iu1_completed_instruction = instr;
- else if (stage == IU2)
- iu2_completed_instruction = instr;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-
- iu1_completed_instruction = NULL;
- iu2_completed_instruction = NULL;
-}
-
-static int can_issue(PCode *instr) {
- int stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- stage = instruction_timing[instr->op].stage;
-
- if (stage == IU2) {
- PCode *check;
- int isClear1 = !pipeline[IU1].instr;
- int isClear2 = !pipeline[IU2].instr;
- if (!isClear1 && !isClear2)
- return 0;
- if (isClear1 && isClear2)
- return 1;
-
- if (isClear1)
- check = pipeline[IU2].instr;
- else
- check = pipeline[IU1].instr;
-
- if (is_dependent(instr, check, RegClass_GPR))
- return 0;
- if (is_dependent(instr, iu1_completed_instruction, RegClass_GPR))
- return 0;
- if (is_dependent(instr, iu2_completed_instruction, RegClass_GPR))
- return 0;
- } else {
- if (pipeline[stage].instr)
- return 0;
- }
-
- if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
- return 0;
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- assign_completion_buffer(instr);
- if (stage == IU2 && !pipeline[IU1].instr)
- stage = IU1;
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- iu1_completed_instruction = NULL;
- iu2_completed_instruction = NULL;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- }
- }
-
- if (pipeline[IU1].instr && pipeline[IU1].remaining == 0)
- complete_instruction(IU1);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
- complete_instruction(FPU3);
- if (pipeline[SRU].instr && pipeline[SRU].remaining == 0)
- complete_instruction(SRU);
- if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
- complete_instruction(BPU);
- if (pipeline[IU2].instr && pipeline[IU2].remaining == 0)
- complete_instruction(IU2);
-
- if (
- pipeline[FPU1].instr &&
- pipeline[FPU1].remaining == 0 &&
- (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
- )
- complete_instruction(FPU1);
-
- if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
- advance(FPU1, FPU2, FPU3);
- if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
- advance(FPU1, FPU1, FPU2);
-
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-MachineInfo machine750 = {
- 2,
- 1,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulation821.c b/compiler_and_linker/unsorted/MachineSimulation821.c
deleted file mode 100644
index bbf0509..0000000
--- a/compiler_and_linker/unsorted/MachineSimulation821.c
+++ /dev/null
@@ -1,615 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://www.nxp.com/docs/en/user-guide/MPC821UM.pdf
-
-typedef enum Stage {
- BranchUnit,
- Stage1,
- Stage2,
- LSU1,
- LSU2,
- CRUnit,
- NumStages,
- Stage7
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline[NumStages];
-
-enum {
- MaxEntries = 6
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[3];
-
- // does this instruction serialise?
- char serializes;
-} instruction_timing[OPCODE_MAX] = {
- BranchUnit, 0, 0, 0, 0, 0, // PC_B
- BranchUnit, 0, 0, 0, 0, 0, // PC_BL
- BranchUnit, 0, 0, 0, 0, 0, // PC_BC
- BranchUnit, 0, 0, 0, 0, 0, // PC_BCLR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BCCTR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BT
- BranchUnit, 0, 0, 0, 0, 0, // PC_BTLR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BTCTR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BF
- BranchUnit, 0, 0, 0, 0, 0, // PC_BFLR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BFCTR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZ
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZT
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZF
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDZ
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDZT
- BranchUnit, 0, 0, 0, 0, 0, // PC_BDZF
- BranchUnit, 0, 0, 0, 0, 0, // PC_BLR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BCTR
- BranchUnit, 0, 0, 0, 0, 0, // PC_BCTRL
- BranchUnit, 0, 0, 0, 0, 0, // PC_BLRL
- BranchUnit, 0, 0, 0, 0, 0, // PC_LBZ
- LSU1, 2, 1, 1, 0, 0, // PC_LBZU
- LSU1, 2, 1, 1, 0, 0, // PC_LBZX
- LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZ
- LSU1, 2, 1, 1, 0, 0, // PC_LHZU
- LSU1, 2, 1, 1, 0, 0, // PC_LHZX
- LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHA
- LSU1, 2, 1, 1, 0, 0, // PC_LHAU
- LSU1, 2, 1, 1, 0, 0, // PC_LHAX
- LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
- LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZ
- LSU1, 2, 1, 1, 0, 0, // PC_LWZU
- LSU1, 2, 1, 1, 0, 0, // PC_LWZX
- LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
- LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_LMW
- LSU1, 2, 1, 1, 0, 0, // PC_STB
- LSU1, 2, 1, 1, 0, 0, // PC_STBU
- LSU1, 2, 1, 1, 0, 0, // PC_STBX
- LSU1, 2, 1, 1, 0, 0, // PC_STBUX
- LSU1, 2, 1, 1, 0, 0, // PC_STH
- LSU1, 2, 1, 1, 0, 0, // PC_STHU
- LSU1, 2, 1, 1, 0, 0, // PC_STHX
- LSU1, 2, 1, 1, 0, 0, // PC_STHUX
- LSU1, 2, 1, 1, 0, 0, // PC_STHBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STW
- LSU1, 2, 1, 1, 0, 0, // PC_STWU
- LSU1, 2, 1, 1, 0, 0, // PC_STWX
- LSU1, 2, 1, 1, 0, 0, // PC_STWUX
- LSU1, 2, 1, 1, 0, 0, // PC_STWBRX
- LSU1, 2, 1, 1, 0, 0, // PC_STMW
- LSU1, 2, 1, 1, 0, 0, // PC_DCBF
- LSU1, 2, 1, 1, 0, 0, // PC_DCBST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBT
- LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
- LSU1, 2, 1, 1, 0, 0, // PC_DCBZ
- LSU1, 2, 1, 1, 0, 0, // PC_ADD
- Stage1, 1, 1, 0, 0, 0, // PC_ADDC
- Stage1, 1, 1, 0, 0, 0, // PC_ADDE
- Stage1, 1, 1, 0, 0, 0, // PC_ADDI
- Stage1, 1, 1, 0, 0, 0, // PC_ADDIC
- Stage1, 1, 1, 0, 0, 0, // PC_ADDICR
- Stage1, 1, 1, 0, 0, 0, // PC_ADDIS
- Stage1, 1, 1, 0, 0, 0, // PC_ADDME
- Stage1, 1, 1, 0, 0, 0, // PC_ADDZE
- Stage1, 1, 1, 0, 0, 0, // PC_DIVW
- Stage1, 37, 37, 0, 0, 0, // PC_DIVWU
- Stage1, 37, 37, 0, 0, 0, // PC_MULHW
- Stage1, 5, 5, 0, 0, 0, // PC_MULHWU
- Stage1, 5, 5, 0, 0, 0, // PC_MULLI
- Stage1, 3, 3, 0, 0, 0, // PC_MULLW
- Stage1, 5, 5, 0, 0, 0, // PC_NEG
- Stage1, 1, 1, 0, 0, 0, // PC_SUBF
- Stage1, 1, 1, 0, 0, 0, // PC_SUBFC
- Stage1, 1, 1, 0, 0, 0, // PC_SUBFE
- Stage1, 1, 1, 0, 0, 0, // PC_SUBFIC
- Stage1, 1, 1, 0, 0, 0, // PC_SUBFME
- Stage1, 1, 1, 0, 0, 0, // PC_SUBFZE
- Stage1, 1, 1, 0, 0, 0, // PC_CMPI
- Stage1, 3, 1, 0, 0, 0, // PC_CMP
- Stage1, 3, 1, 0, 0, 0, // PC_CMPLI
- Stage1, 3, 1, 0, 0, 0, // PC_CMPL
- Stage1, 3, 1, 0, 0, 0, // PC_ANDI
- Stage1, 1, 1, 0, 0, 0, // PC_ANDIS
- Stage1, 1, 1, 0, 0, 0, // PC_ORI
- Stage1, 1, 1, 0, 0, 0, // PC_ORIS
- Stage1, 1, 1, 0, 0, 0, // PC_XORI
- Stage1, 1, 1, 0, 0, 0, // PC_XORIS
- Stage1, 1, 1, 0, 0, 0, // PC_AND
- Stage1, 1, 1, 0, 0, 0, // PC_OR
- Stage1, 1, 1, 0, 0, 0, // PC_XOR
- Stage1, 1, 1, 0, 0, 0, // PC_NAND
- Stage1, 1, 1, 0, 0, 0, // PC_NOR
- Stage1, 1, 1, 0, 0, 0, // PC_EQV
- Stage1, 1, 1, 0, 0, 0, // PC_ANDC
- Stage1, 1, 1, 0, 0, 0, // PC_ORC
- Stage1, 1, 1, 0, 0, 0, // PC_EXTSB
- Stage1, 1, 1, 0, 0, 0, // PC_EXTSH
- Stage1, 1, 1, 0, 0, 0, // PC_CNTLZW
- Stage1, 1, 1, 0, 0, 0, // PC_RLWINM
- Stage1, 1, 1, 0, 0, 0, // PC_RLWNM
- Stage1, 1, 1, 0, 0, 0, // PC_RLWIMI
- Stage1, 1, 1, 0, 0, 0, // PC_SLW
- Stage1, 1, 1, 0, 0, 0, // PC_SRW
- Stage1, 1, 1, 0, 0, 0, // PC_SRAWI
- Stage1, 1, 1, 0, 0, 0, // PC_SRAW
- Stage1, 1, 1, 0, 0, 0, // PC_CRAND
- CRUnit, 1, 1, 0, 0, 0, // PC_CRANDC
- CRUnit, 1, 1, 0, 0, 0, // PC_CREQV
- CRUnit, 1, 1, 0, 0, 0, // PC_CRNAND
- CRUnit, 1, 1, 0, 0, 0, // PC_CRNOR
- CRUnit, 1, 1, 0, 0, 0, // PC_CROR
- CRUnit, 1, 1, 0, 0, 0, // PC_CRORC
- CRUnit, 1, 1, 0, 0, 0, // PC_CRXOR
- CRUnit, 1, 1, 0, 0, 0, // PC_MCRF
- CRUnit, 1, 1, 0, 0, 0, // PC_MTXER
- Stage1, 1, 1, 0, 0, 0, // PC_MTCTR
- BranchUnit, 2, 2, 0, 0, 0, // PC_MTLR
- BranchUnit, 2, 2, 0, 0, 0, // PC_MTCRF
- Stage1, 1, 1, 0, 0, 0, // PC_MTMSR
- Stage1, 1, 1, 0, 0, 0, // PC_MTSPR
- Stage1, 1, 1, 0, 0, 0, // PC_MFMSR
- Stage1, 1, 1, 0, 0, 0, // PC_MFSPR
- Stage1, 1, 1, 0, 0, 0, // PC_MFXER
- Stage7, 3, 1, 1, 1, 0, // PC_MFCTR
- Stage7, 3, 1, 1, 1, 0, // PC_MFLR
- Stage1, 1, 1, 0, 0, 0, // PC_MFCR
- Stage1, 1, 1, 0, 0, 0, // PC_MFFS
- Stage1, 1, 1, 0, 0, 0, // PC_MTFSF
- Stage1, 1, 1, 0, 0, 0, // PC_EIEIO
- Stage1, 1, 1, 0, 0, 0, // PC_ISYNC
- Stage1, 1, 1, 0, 0, 0, // PC_SYNC
- Stage1, 1, 1, 0, 0, 0, // PC_RFI
- Stage1, 1, 1, 0, 0, 0, // PC_LI
- LSU1, 2, 1, 1, 0, 0, // PC_LIS
- LSU1, 2, 1, 1, 0, 0, // PC_MR
- LSU1, 2, 1, 1, 0, 0, // PC_NOP
- LSU1, 2, 1, 1, 0, 0, // PC_NOT
- LSU1, 2, 1, 1, 0, 0, // PC_LFS
- LSU1, 2, 1, 1, 0, 0, // PC_LFSU
- LSU1, 2, 1, 1, 0, 0, // PC_LFSX
- LSU1, 2, 1, 1, 0, 0, // PC_LFSUX
- LSU1, 2, 1, 1, 0, 0, // PC_LFD
- LSU1, 2, 1, 1, 0, 0, // PC_LFDU
- LSU1, 2, 1, 1, 0, 0, // PC_LFDX
- LSU1, 2, 1, 1, 0, 0, // PC_LFDUX
- LSU1, 2, 1, 1, 0, 0, // PC_STFS
- LSU1, 2, 1, 1, 0, 0, // PC_STFSU
- LSU1, 2, 1, 1, 0, 0, // PC_STFSX
- LSU1, 2, 1, 1, 0, 0, // PC_STFSUX
- Stage7, 3, 1, 1, 1, 0, // PC_STFD
- Stage7, 3, 1, 1, 1, 0, // PC_STFDU
- Stage7, 3, 1, 1, 1, 0, // PC_STFDX
- Stage7, 3, 1, 1, 1, 0, // PC_STFDUX
- Stage7, 3, 1, 1, 1, 0, // PC_FMR
- Stage7, 3, 1, 1, 1, 0, // PC_FABS
- Stage7, 3, 1, 1, 1, 0, // PC_FNEG
- Stage7, 3, 1, 1, 1, 0, // PC_FNABS
- Stage7, 4, 2, 1, 1, 0, // PC_FADD
- Stage7, 3, 1, 1, 1, 0, // PC_FADDS
- Stage7, 33, 33, 0, 0, 0, // PC_FSUB
- Stage7, 18, 18, 0, 0, 0, // PC_FSUBS
- Stage7, 4, 2, 1, 1, 0, // PC_FMUL
- Stage7, 3, 1, 1, 1, 0, // PC_FMULS
- Stage7, 4, 2, 1, 1, 0, // PC_FDIV
- Stage7, 3, 1, 1, 1, 0, // PC_FDIVS
- Stage7, 4, 2, 1, 1, 0, // PC_FMADD
- Stage7, 3, 1, 1, 1, 0, // PC_FMADDS
- Stage7, 4, 2, 1, 1, 0, // PC_FMSUB
- Stage7, 3, 1, 1, 1, 0, // PC_FMSUBS
- Stage7, 18, 18, 0, 0, 0, // PC_FNMADD
- Stage7, 3, 1, 1, 1, 0, // PC_FNMADDS
- Stage7, 3, 1, 1, 1, 0, // PC_FNMSUB
- Stage7, 3, 1, 1, 1, 0, // PC_FNMSUBS
- Stage7, 3, 1, 1, 1, 0, // PC_FRES
- Stage7, 3, 1, 1, 1, 0, // PC_FRSQRTE
- Stage7, 5, 1, 1, 1, 0, // PC_FSEL
- Stage7, 5, 1, 1, 1, 0, // PC_FRSP
- LSU1, 1, 0, 0, 0, 0, // PC_FCTIW
- LSU1, 1, 0, 0, 0, 0, // PC_FCTIWZ
- LSU1, 1, 0, 0, 0, 0, // PC_FCMPU
- LSU1, 1, 0, 0, 0, 0, // PC_FCMPO
- LSU1, 1, 0, 0, 0, 0, // PC_LWARX
- LSU1, 1, 0, 0, 0, 0, // PC_LSWI
- LSU1, 1, 0, 0, 0, 0, // PC_LSWX
- Stage1, 1, 0, 0, 0, 0, // PC_STFIWX
- Stage1, 1, 0, 0, 0, 0, // PC_STSWI
- Stage1, 1, 0, 0, 0, 0, // PC_STSWX
- Stage1, 1, 0, 0, 0, 0, // PC_STWCX
- Stage1, 1, 0, 0, 0, 0, // PC_ECIWX
- Stage1, 1, 0, 0, 0, 0, // PC_ECOWX
- Stage1, 1, 0, 0, 0, 0, // PC_DCBI
- Stage1, 1, 0, 0, 0, 0, // PC_ICBI
- Stage1, 1, 0, 0, 0, 0, // PC_MCRFS
- Stage1, 1, 0, 0, 0, 0, // PC_MCRXR
- Stage1, 1, 0, 0, 0, 0, // PC_MFTB
- Stage1, 1, 0, 0, 0, 0, // PC_MFSR
- Stage1, 1, 0, 0, 0, 0, // PC_MTSR
- Stage1, 1, 0, 0, 0, 0, // PC_MFSRIN
- Stage1, 1, 0, 0, 0, 0, // PC_MTSRIN
- Stage1, 1, 0, 0, 0, 0, // PC_MTFSB0
- Stage1, 1, 0, 0, 0, 0, // PC_MTFSB1
- Stage1, 1, 0, 0, 0, 0, // PC_MTFSFI
- Stage1, 1, 0, 0, 0, 1, // PC_SC
- Stage1, 1, 0, 0, 0, 1, // PC_FSQRT
- Stage1, 1, 0, 0, 0, 0, // PC_FSQRTS
- Stage1, 1, 0, 0, 0, 0, // PC_TLBIA
- Stage1, 1, 0, 0, 0, 0, // PC_TLBIE
- Stage1, 1, 0, 0, 0, 0, // PC_TLBLD
- Stage1, 1, 0, 0, 0, 0, // PC_TLBLI
- Stage1, 1, 0, 0, 0, 0, // PC_TLBSYNC
- Stage1, 1, 0, 0, 0, 0, // PC_TW
- Stage1, 1, 0, 0, 0, 1, // PC_TRAP
- Stage1, 1, 0, 0, 0, 1, // PC_TWI
- Stage1, 1, 0, 0, 0, 1, // PC_OPWORD
- Stage1, 1, 0, 0, 0, 1, // PC_MFROM
- Stage1, 1, 0, 0, 0, 0, // PC_DSA
- Stage1, 1, 0, 0, 0, 0, // PC_ESA
- Stage1, 1, 0, 0, 0, 0, // PC_DCCCI
- Stage1, 0, 0, 0, 0, 0, // PC_DCREAD
- Stage1, 0, 0, 0, 0, 0, // PC_ICBT
- Stage1, 0, 0, 0, 0, 0, // PC_ICCCI
- Stage1, 0, 0, 0, 0, 0, // PC_ICREAD
- Stage1, 0, 0, 0, 0, 0, // PC_RFCI
- Stage1, 0, 0, 0, 0, 0, // PC_TLBRE
- Stage1, 0, 0, 0, 0, 0, // PC_TLBSX
- Stage1, 0, 0, 0, 0, 0, // PC_TLBWE
- Stage1, 0, 0, 0, 0, 0, // PC_WRTEE
- Stage1, 0, 0, 0, 0, 0, // PC_WRTEEI
- Stage1, 0, 0, 0, 0, 0, // PC_MFDCR
- Stage1, 0, 0, 0, 0, 0, // PC_MTDCR
- Stage1, 0, 0, 0, 0, 0, // PC_DCBA
- Stage1, 0, 0, 0, 0, 0, // PC_DSS
- BranchUnit, 0, 0, 0, 0, 0, // PC_DSSALL
- BranchUnit, 0, 0, 0, 0, 0, // PC_DST
- BranchUnit, 0, 0, 0, 0, 0, // PC_DSTT
- BranchUnit, 0, 0, 0, 0, 0, // PC_DSTST
- BranchUnit, 0, 0, 0, 0, 0, // PC_DSTSTT
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVEBX
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVEHX
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVEWX
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVSL
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVSR
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVX
- BranchUnit, 0, 0, 0, 0, 0, // PC_LVXL
- BranchUnit, 0, 0, 0, 0, 0, // PC_STVEBX
- BranchUnit, 0, 0, 0, 0, 0, // PC_STVEHX
- BranchUnit, 0, 0, 0, 0, 0, // PC_STVEWX
- BranchUnit, 0, 0, 0, 0, 0, // PC_STVX
- BranchUnit, 0, 0, 0, 0, 0, // PC_STVXL
- BranchUnit, 0, 0, 0, 0, 0, // PC_MFVSCR
- BranchUnit, 0, 0, 0, 0, 0, // PC_MTVSCR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDCUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAND
- BranchUnit, 0, 0, 0, 0, 0, // PC_VANDC
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCFSX
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCFUX
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPBFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGEFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCTSXS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VCTUXS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VEXPTEFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VLOGEFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VNOR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VOR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKPX
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHSS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHUS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWSS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWUS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VREFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIN
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIZ
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRLB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRLH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRLW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSL
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSLB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSLH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSLO
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSLW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRO
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSRW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBCUW
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUMSWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM2SWS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4UBS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHPX
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLPX
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSB
- BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSH
- BranchUnit, 0, 0, 0, 0, 0, // PC_VXOR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMADDFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMHADDSHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMLADDUHM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMMBM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUBM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHS
- BranchUnit, 0, 0, 0, 0, 0, // PC_VNMSUBFP
- BranchUnit, 0, 0, 0, 0, 0, // PC_VPERM
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSEL
- BranchUnit, 0, 0, 0, 0, 0, // PC_VSLDOI
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMR
- BranchUnit, 0, 0, 0, 0, 0, // PC_VMRP
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLE
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLEQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLIQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLLIQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLLQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SLQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRAIQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRAQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRE
- BranchUnit, 0, 0, 0, 0, 0, // PC_SREA
- BranchUnit, 0, 0, 0, 0, 0, // PC_SREQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRIQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRLIQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRLQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_SRQ
- BranchUnit, 0, 0, 0, 0, 0, // PC_MASKG
- BranchUnit, 0, 0, 0, 0, 0, // PC_MASKIR
- BranchUnit, 0, 0, 0, 0, 0, // PC_LSCBX
- BranchUnit, 0, 0, 0, 0, 0, // PC_DIV
- BranchUnit, 0, 0, 0, 0, 0, // PC_DIVS
- BranchUnit, 0, 0, 0, 0, 0, // PC_DOZ
- BranchUnit, 0, 0, 0, 0, 0, // PC_MUL
- BranchUnit, 0, 0, 0, 0, 0, // PC_NABS
- BranchUnit, 0, 0, 0, 0, 0, // PC_ABS
- BranchUnit, 0, 0, 0, 0, 0, // PC_CLCS
- BranchUnit, 0, 0, 0, 0, 0, // PC_DOZI
- BranchUnit, 0, 0, 0, 0, 0, // PC_RLMI
- BranchUnit, 0, 0, 0, 0, 0, // PC_RRIB
-};
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline[newStage].instr = instr;
- pipeline[newStage].remaining = cycles;
- pipeline[oldStage].instr = NULL;
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline[stage].instr = NULL;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 2;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++)
- completionbuffers.entries[i].instr = NULL;
-}
-
-static int can_issue(PCode *instr) {
- int stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- stage = instruction_timing[instr->op].stage;
- if (pipeline[stage].instr)
- return 0;
-
- if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
- return 0;
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- assign_completion_buffer(instr);
- pipeline[stage].instr = instr;
- pipeline[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int stage;
-
- for (stage = 0; stage < NumStages; stage++) {
- if (pipeline[stage].instr && pipeline[stage].remaining)
- --pipeline[stage].remaining;
- }
-
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
- retire_instruction();
- }
- }
-
- if (pipeline[Stage1].instr && pipeline[Stage1].remaining == 0)
- complete_instruction(Stage1);
- if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
- complete_instruction(LSU2);
- if (pipeline[BranchUnit].instr && pipeline[BranchUnit].remaining == 0)
- complete_instruction(BranchUnit);
-
- if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
- advance(LSU1, LSU1, LSU2);
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-MachineInfo machine821 = {
- 1,
- 0,
- 0,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &default_uses_vpermute_unit
-};
diff --git a/compiler_and_linker/unsorted/MachineSimulationAltiVec.c b/compiler_and_linker/unsorted/MachineSimulationAltiVec.c
deleted file mode 100644
index d261ee9..0000000
--- a/compiler_and_linker/unsorted/MachineSimulationAltiVec.c
+++ /dev/null
@@ -1,752 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/CError.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-
-// https://www.nxp.com/docs/en/reference-manual/MPC7450UM.pdf
-
-typedef enum Stage {
- BPU, // Branch Prediction Unit
-
- IU2_1, // Multiple-Cycle Integer Unit
- IU2_2,
- IU2_3,
-
- IU1a, // Single-Cycle Integer Unit
- IU1b, // Single-Cycle Integer Unit
- IU1c, // Single-Cycle Integer Unit
-
- LSU_1, // Load/Store Unit
- LSU_2,
- LSU_3,
- LSU_4,
-
- FPU_1, // Floating-Point Unit
- FPU_2,
- FPU_3,
- FPU_4,
-
- VIU1, // Vector Simple Integer Unit
-
- VPU_1, // Vector Permute Unit
- VPU_2,
-
- VIU2_1, // Vector Complex Integer Unit
- VIU2_2,
- VIU2_3,
- VIU2_4,
-
- VFPU_1, // Vector Floating-Point Unit
- VFPU_2,
- VFPU_3,
- VFPU_4,
-
- NumStages
-} Stage;
-
-static struct {
- // the instruction currently in this pipeline stage
- PCode *instr;
-
- // how many cycles are left for this instruction to finish
- int remaining;
-} pipeline_altivec[NumStages];
-
-enum {
- Queue0,
- Queue1,
- Queue2,
- Queue3,
- Queue4,
- Queue5,
- Queue6,
- Queue7,
- NumQueues
-};
-
-static int fetchqueues[NumQueues];
-
-enum {
- MaxEntries = 16
-};
-
-static struct {
- // how many entries remain unused in the queue
- unsigned int free;
-
- // how many entries are currently used in the queue
- unsigned int used;
-
- // the index of the next instruction that will be retired
- unsigned int nextToRetire;
-
- // the index of the next free slot that will be used when an instruction is dispatched
- unsigned int nextFreeSlot;
-
- // circular array of entries in the completion queue
- struct {
- PCode *instr;
- int completed;
- } entries[MaxEntries];
-} completionbuffers;
-
-static struct {
- short index;
-
- // the initial stage for this instruction
- Stage stage;
-
- // the total amount of cycles required by this instruction
- char latency;
-
- // how long it takes to finish each stage
- char cycles[4];
-
- // does this instruction serialise?
- char serializes;
-
- char unused;
-} instruction_timing[] = {
- 0, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_B
- 1, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BL
- 2, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BC
- 3, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCLR
- 4, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCCTR
- 5, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BT
- 6, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTLR
- 7, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTCTR
- 8, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BF
- 9, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFLR
- 10, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFCTR
- 11, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZ
- 12, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZT
- 13, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZF
- 14, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZ
- 15, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZT
- 16, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZF
- 17, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLR
- 18, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTR
- 19, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTRL
- 20, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLRL
- 21, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZ
- 22, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZU
- 23, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZX
- 24, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZUX
- 25, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZ
- 26, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZU
- 27, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZX
- 28, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZUX
- 29, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHA
- 30, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAU
- 31, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAX
- 32, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAUX
- 33, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHBRX
- 34, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZ
- 35, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZU
- 36, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZX
- 37, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZUX
- 38, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWBRX
- 39, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_LMW
- 40, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STB
- 41, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBU
- 42, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBX
- 43, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBUX
- 44, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STH
- 45, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHU
- 46, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHX
- 47, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHUX
- 48, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHBRX
- 49, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STW
- 50, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWU
- 51, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWX
- 52, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWUX
- 53, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWBRX
- 54, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STMW
- 55, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBF
- 56, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBST
- 57, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBT
- 58, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBTST
- 59, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBZ
- 60, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADD
- 61, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDC
- 62, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDE
- 63, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDI
- 64, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIC
- 65, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDICR
- 66, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIS
- 67, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDME
- 68, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDZE
- 69, IU2_1, 23, 23, 0, 0, 0, 0, 0, // PC_DIVW
- 70, IU2_1, 23, 23, 0, 0, 0, 0, 0, // PC_DIVWU
- 71, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULHW
- 72, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULHWU
- 73, IU2_1, 3, 1, 1, 1, 0, 0, 0, // PC_MULLI
- 74, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULLW
- 75, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NEG
- 76, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBF
- 77, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFC
- 78, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFE
- 79, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFIC
- 80, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFME
- 81, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFZE
- 82, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPI
- 83, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMP
- 84, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPLI
- 85, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPL
- 86, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDI
- 87, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDIS
- 88, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORI
- 89, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORIS
- 90, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XORI
- 91, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XORIS
- 92, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_AND
- 93, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_OR
- 94, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XOR
- 95, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NAND
- 96, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOR
- 97, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EQV
- 98, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDC
- 99, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORC
- 100, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSB
- 101, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSH
- 102, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CNTLZW
- 103, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWINM
- 104, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWNM
- 105, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWIMI
- 106, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SLW
- 107, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SRW
- 108, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_SRAWI
- 109, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_SRAW
- 110, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRAND
- 111, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRANDC
- 112, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CREQV
- 113, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRNAND
- 114, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRNOR
- 115, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CROR
- 116, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRORC
- 117, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRXOR
- 118, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MCRF
- 119, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTXER
- 120, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTCTR
- 121, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTLR
- 122, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MTCRF
- 123, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTMSR
- 124, IU2_1, 3, 3, 0, 0, 0, 1, 0, // PC_MTSPR
- 125, IU2_1, 3, 2, 1, 0, 0, 0, 0, // PC_MFMSR
- 126, IU2_1, 3, 3, 0, 0, 0, 1, 0, // PC_MFSPR
- 127, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFXER
- 128, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFCTR
- 129, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFLR
- 130, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MFCR
- 131, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MFFS
- 132, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSF
- 133, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_EIEIO
- 134, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_ISYNC
- 135, LSU_1, 35, 35, 0, 0, 0, 1, 0, // PC_SYNC
- 136, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_RFI
- 137, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_LI
- 138, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_LIS
- 139, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MR
- 140, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOP
- 141, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOT
- 142, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFS
- 143, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSU
- 144, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSX
- 145, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSUX
- 146, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFD
- 147, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDU
- 148, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDX
- 149, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDUX
- 150, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFS
- 151, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSU
- 152, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSX
- 153, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSUX
- 154, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFD
- 155, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDU
- 156, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDX
- 157, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDUX
- 158, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMR
- 159, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FABS
- 160, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNEG
- 161, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNABS
- 162, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FADD
- 163, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FADDS
- 164, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSUB
- 165, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSUBS
- 166, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMUL
- 167, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMULS
- 168, FPU_1, 35, 35, 0, 0, 0, 0, 0, // PC_FDIV
- 169, FPU_1, 21, 21, 0, 0, 0, 0, 0, // PC_FDIVS
- 170, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMADD
- 171, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMADDS
- 172, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMSUB
- 173, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMSUBS
- 174, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMADD
- 175, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMADDS
- 176, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMSUB
- 177, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMSUBS
- 178, FPU_1, 14, 14, 0, 0, 0, 0, 0, // PC_FRES
- 179, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FRSQRTE
- 180, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSEL
- 181, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FRSP
- 182, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCTIW
- 183, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCTIWZ
- 184, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCMPU
- 185, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCMPO
- 186, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_LWARX
- 187, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LSWI
- 188, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_LSWX
- 189, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STFIWX
- 190, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STSWI
- 191, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STSWX
- 192, LSU_1, 3, 1, 1, 1, 0, 1, 0, // PC_STWCX
- 193, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ECIWX
- 194, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ECOWX
- 195, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBI
- 196, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ICBI
- 197, IU2_1, 5, 5, 0, 0, 0, 1, 0, // PC_MCRFS
- 198, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MCRXR
- 199, IU2_1, 5, 5, 0, 0, 0, 0, 0, // PC_MFTB
- 200, IU2_1, 4, 1, 3, 0, 0, 0, 0, // PC_MFSR
- 201, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTSR
- 202, IU2_1, 4, 1, 3, 0, 0, 0, 0, // PC_MFSRIN
- 203, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTSRIN
- 204, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSB0
- 205, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSB1
- 206, FPU_1, 5, 5, 0, 0, 0, 0, 0, // PC_MTFSFI
- 207, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_SC
- 208, FPU_1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRT
- 209, FPU_1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRTS
- 210, LSU_1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIA
- 211, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_TLBIE
- 212, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_TLBLD
- 213, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_TLBLI
- 214, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_TLBSYNC
- 215, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_TW
- 216, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_TRAP
- 217, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_TWI
- 218, IU1a, 1, 1, 0, 0, 0, 1, 0, // PC_OPWORD
- 219, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MFROM
- 220, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_DSA
- 221, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ESA
- 222, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_DCCCI
- 223, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_DCREAD
- 224, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICBT
- 225, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICCCI
- 226, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICREAD
- 227, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_RFCI
- 228, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBRE
- 229, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBSX
- 230, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBWE
- 231, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEE
- 232, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEEI
- 233, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_MFDCR
- 234, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_MTDCR
- 235, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBA
- 236, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSS
- 237, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSSALL
- 238, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DST
- 239, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTT
- 240, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTST
- 241, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTSTT
- 242, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEBX
- 243, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEHX
- 244, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEWX
- 245, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVSL
- 246, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVSR
- 247, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVX
- 248, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVXL
- 249, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEBX
- 250, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEHX
- 251, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEWX
- 252, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVX
- 253, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVXL
- 254, VFPU_1, 2, 2, 0, 0, 0, 1, 0, // PC_MFVSCR
- 255, VFPU_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTVSCR
- 256, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDCUW
- 257, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VADDFP
- 258, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSBS
- 259, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSHS
- 260, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSWS
- 261, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBM
- 262, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBS
- 263, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHM
- 264, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHS
- 265, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWM
- 266, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWS
- 267, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAND
- 268, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VANDC
- 269, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSB
- 270, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSH
- 271, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSW
- 272, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUB
- 273, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUH
- 274, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUW
- 275, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFSX
- 276, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFUX
- 277, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPBFP
- 278, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPEQFP
- 279, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUB
- 280, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUH
- 281, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUW
- 282, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPGEFP
- 283, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPGTFP
- 284, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSB
- 285, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSH
- 286, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSW
- 287, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUB
- 288, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUH
- 289, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUW
- 290, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTSXS
- 291, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTUXS
- 292, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VEXPTEFP
- 293, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VLOGEFP
- 294, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMAXFP
- 295, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSB
- 296, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSH
- 297, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSW
- 298, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUB
- 299, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUH
- 300, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUW
- 301, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMINFP
- 302, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSB
- 303, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSH
- 304, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSW
- 305, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUB
- 306, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUH
- 307, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUW
- 308, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHB
- 309, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHH
- 310, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHW
- 311, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLB
- 312, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLH
- 313, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLW
- 314, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULESB
- 315, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULESH
- 316, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULEUB
- 317, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULEUH
- 318, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOSB
- 319, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOSH
- 320, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOUB
- 321, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOUH
- 322, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VNOR
- 323, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VOR
- 324, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKPX
- 325, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSHSS
- 326, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSHUS
- 327, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSWSS
- 328, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSWUS
- 329, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUHUM
- 330, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUHUS
- 331, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUWUM
- 332, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUWUS
- 333, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VREFP
- 334, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIM
- 335, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIN
- 336, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIP
- 337, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIZ
- 338, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLB
- 339, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLH
- 340, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLW
- 341, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRSQRTEFP
- 342, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSL
- 343, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLB
- 344, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLH
- 345, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSLO
- 346, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLW
- 347, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTB
- 348, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTH
- 349, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTW
- 350, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISB
- 351, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISH
- 352, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISW
- 353, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSR
- 354, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAB
- 355, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAH
- 356, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAW
- 357, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRB
- 358, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRH
- 359, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSRO
- 360, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRW
- 361, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBCUW
- 362, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUBFP
- 363, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSBS
- 364, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSHS
- 365, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSWS
- 366, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBM
- 367, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBS
- 368, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHM
- 369, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHS
- 370, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWM
- 371, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWS
- 372, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUMSWS
- 373, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM2SWS
- 374, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4SBS
- 375, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4SHS
- 376, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4UBS
- 377, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHPX
- 378, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHSB
- 379, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHSH
- 380, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLPX
- 381, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLSB
- 382, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLSH
- 383, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VXOR
- 384, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMADDFP
- 385, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMHADDSHS
- 386, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMHRADDSHS
- 387, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMLADDUHM
- 388, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMMBM
- 389, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMSHM
- 390, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMSHS
- 391, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUBM
- 392, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUHM
- 393, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUHS
- 394, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VNMSUBFP
- 395, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPERM
- 396, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSEL
- 397, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSLDOI
- 398, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMR
- 399, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRP
- -1, IU2_1, 1, 1, 0, 0, 0, 1, 0
-};
-
-enum { NumPipelineUnits = 6 };
-static struct {
- Stage start, end;
-} pipeline_units[8] = {
- IU2_1, IU2_3,
- LSU_1, LSU_4,
- FPU_1, FPU_4,
- VPU_1, VPU_2,
- VIU2_1, VIU2_4,
- VFPU_1, VFPU_4
-};
-
-enum { NumFinalStages = 11 };
-static Stage finalstages[16] = {
- BPU, IU2_3, IU1a, IU1b,
- IU1c, LSU_4, FPU_4, VIU1,
- VPU_2, VIU2_4, VFPU_4
-};
-
-// forward decl
-static void complete_instruction(int stage);
-
-static void advance(int firstStage, int oldStage, int newStage) {
- PCode *instr = pipeline_altivec[oldStage].instr;
- int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
- pipeline_altivec[newStage].instr = instr;
- pipeline_altivec[newStage].remaining = cycles;
- pipeline_altivec[oldStage].instr = NULL;
- pipeline_altivec[oldStage].remaining = 0;
- if (cycles == 0)
- complete_instruction(newStage);
-}
-
-static void assign_completion_buffer(PCode *instr) {
- completionbuffers.used++;
- completionbuffers.free--;
- completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
- completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
- completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
-}
-
-static void complete_instruction(int stage) {
- PCode *instr = pipeline_altivec[stage].instr;
- int buf = 0;
- while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
- buf++;
-
- completionbuffers.entries[buf].completed = 1;
- pipeline_altivec[stage].instr = NULL;
-}
-
-static void retire_instruction(void) {
- completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
- completionbuffers.entries[completionbuffers.nextToRetire].completed = 0;
- completionbuffers.used--;
- completionbuffers.free++;
- completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
-}
-
-static int latency(PCode *instr) {
- int cycles = instruction_timing[instr->op].latency;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- cycles += 1;
- if (instr->op == PC_LMW || instr->op == PC_STMW)
- cycles += instr->argCount - 2;
- return cycles;
-}
-
-static void initialize(void) {
- int stage;
- int i;
-
- fetchqueues[Queue0] = 1;
- for (i = 1; i < NumQueues; i++)
- fetchqueues[i] = 0;
-
- for (stage = 0; stage < NumStages; stage++)
- pipeline_altivec[stage].instr = NULL;
-
- completionbuffers.free = MaxEntries;
- completionbuffers.used = 0;
- completionbuffers.nextToRetire = 0;
- completionbuffers.nextFreeSlot = 0;
- for (i = 0; i < MaxEntries; i++) {
- completionbuffers.entries[i].instr = NULL;
- completionbuffers.entries[i].completed = 0;
- }
-}
-
-static int can_issue(PCode *instr) {
- int stage;
-
- if (completionbuffers.free == 0)
- return 0;
-
- stage = instruction_timing[instr->op].stage;
-
- if (stage == IU1a) {
- int isClear1 = !pipeline_altivec[IU1a].instr;
- int isClear2 = !pipeline_altivec[IU1b].instr;
- if (!isClear1 && !isClear2)
- return 0;
- } else {
- if (pipeline_altivec[stage].instr)
- return 0;
- }
-
- if (fetchqueues[Queue1] <= 0)
- return 0;
-
- if (stage == FPU_1) {
- if (fetchqueues[Queue2] < 1 || fetchqueues[Queue5] >= 1)
- return 0;
- } else if (stage >= VIU1 && stage <= VFPU_1) {
- if (fetchqueues[Queue4] < 1 || fetchqueues[Queue7] >= 2)
- return 0;
- } else if (stage != BPU) {
- if (fetchqueues[Queue3] < 1 || fetchqueues[Queue6] >= 3)
- return 0;
- }
-
- return 1;
-}
-
-static void issue(PCode *instr) {
- int stage = instruction_timing[instr->op].stage;
- int cycles = instruction_timing[instr->op].cycles[0];
- assign_completion_buffer(instr);
-
- CError_ASSERT(879, --fetchqueues[Queue1] >= 0);
-
- if (stage == FPU_1) {
- fetchqueues[Queue2]--;
- fetchqueues[Queue5]++;
- } else if (stage >= VIU1 && stage <= VFPU_1) {
- fetchqueues[Queue4]--;
- fetchqueues[Queue7]++;
- } else if (stage != BPU) {
- fetchqueues[Queue3]--;
- fetchqueues[Queue6]++;
- }
-
- fetchqueues[Queue2] = (fetchqueues[Queue1] < fetchqueues[Queue2]) ? fetchqueues[Queue1] : fetchqueues[Queue2];
- fetchqueues[Queue3] = (fetchqueues[Queue1] < fetchqueues[Queue3]) ? fetchqueues[Queue1] : fetchqueues[Queue3];
- fetchqueues[Queue4] = (fetchqueues[Queue1] < fetchqueues[Queue4]) ? fetchqueues[Queue1] : fetchqueues[Queue4];
-
- if (stage == IU1a) {
- if (!pipeline_altivec[IU1a].instr)
- stage = IU1a;
- else if (!pipeline_altivec[IU1b].instr)
- stage = IU1b;
- else if (!pipeline_altivec[IU1c].instr)
- stage = IU1c;
- }
-
- pipeline_altivec[stage].instr = instr;
- pipeline_altivec[stage].remaining = cycles;
-}
-
-static void advance_clock(void) {
- int num;
- int i;
- unsigned int unit;
-
- for (i = 0; i < NumStages; i++) {
- if (pipeline_altivec[i].instr && pipeline_altivec[i].remaining)
- --pipeline_altivec[i].remaining;
- }
-
- for (i = 0; i < 3; i++) {
- if (completionbuffers.used == 0)
- break;
- if (completionbuffers.entries[completionbuffers.nextToRetire].completed == 0)
- break;
- retire_instruction();
- }
-
- unit = 0;
- do {
- if (pipeline_altivec[finalstages[unit]].instr && pipeline_altivec[finalstages[unit]].remaining == 0)
- complete_instruction(finalstages[unit]);
- } while (++unit < NumFinalStages);
-
- unit = 0;
- do {
- Stage first;
- Stage current;
- first = pipeline_units[unit].start;
- for (current = first; current < pipeline_units[unit].end; current++) {
- if (pipeline_altivec[current].instr && pipeline_altivec[current].remaining == 0 && !pipeline_altivec[current + 1].instr)
- advance(first, current, current + 1);
- }
- } while (++unit < NumPipelineUnits);
-
- fetchqueues[Queue5] = 0;
- fetchqueues[Queue6] = 0;
- fetchqueues[Queue7] = 0;
-
-#define CHEAP_MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
- num = 2 - fetchqueues[Queue2];
- num += 6 - fetchqueues[Queue3];
- num += 4 - fetchqueues[Queue4];
- num = (num > 3) ? 3 : num;
- num = (completionbuffers.free < num) ? completionbuffers.free : num;
- if (fetchqueues[Queue0] < num)
- num = fetchqueues[Queue0];
-
- fetchqueues[Queue1] += num;
- fetchqueues[Queue0] -= num;
-
- fetchqueues[Queue2] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(2, fetchqueues[Queue2] + num));
- fetchqueues[Queue3] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(6, fetchqueues[Queue3] + num));
- fetchqueues[Queue4] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(4, fetchqueues[Queue4] + num));
-
- CError_ASSERT(991, fetchqueues[Queue1] <= (fetchqueues[Queue2] + fetchqueues[Queue3] + fetchqueues[Queue4]));
-
- if (fetchqueues[Queue0] <= 8)
- fetchqueues[Queue0] += 4;
-}
-
-static int serializes(PCode *instr) {
- return instruction_timing[instr->op].serializes;
-}
-
-static int uses_vpermute_unit_altivec(PCode *instr) {
- return instruction_timing[instr->op].stage == VPU_1;
-}
-
-MachineInfo machine7450 = {
- 6,
- 1,
- 4,
- &latency,
- &initialize,
- &can_issue,
- &issue,
- &advance_clock,
- &serializes,
- &uses_vpermute_unit_altivec
-};
diff --git a/compiler_and_linker/unsorted/ObjGenMachO.c b/compiler_and_linker/unsorted/ObjGenMachO.c
index 072824a..f6f6216 100644
--- a/compiler_and_linker/unsorted/ObjGenMachO.c
+++ b/compiler_and_linker/unsorted/ObjGenMachO.c
@@ -7,9 +7,9 @@
#include "compiler/CParser.h"
#include "compiler/CodeGen.h"
#include "compiler/CompilerTools.h"
-#include "compiler/uDump.h"
+#include "compiler/DumpIR.h"
#include "compiler/GenStabs.h"
-#include "compiler/IrOptimizer.h"
+#include "../FrontEnd/Optimizer/IrOptimizer.h"
#include "compiler/MachO.h"
#include "compiler/PCodeListing.h"
#include "compiler/TOC.h"
diff --git a/compiler_and_linker/unsorted/Operands.c b/compiler_and_linker/unsorted/Operands.c
deleted file mode 100644
index c5da285..0000000
--- a/compiler_and_linker/unsorted/Operands.c
+++ /dev/null
@@ -1,1040 +0,0 @@
-#include "compiler/Operands.h"
-#include "compiler/CError.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/Registers.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-
-unsigned long long uns_to_float_cc = 0x4330000000000000;
-unsigned long long int_to_float_cc = 0x4330000080000000;
-Float one_point_zero = {1.0};
-
-void load_immediate(short reg, SInt32 value) {
- short tmpreg = reg;
- short tmpreg2;
-
- if (!FITS_IN_SHORT(value)) {
- if (copts.optimizationlevel > 1 && LOW_PART_BUGGY(value))
- tmpreg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LIS, tmpreg2 = tmpreg, 0, (short) HIGH_PART(value));
- if (LOW_PART_BUGGY(value))
- emitpcode(PC_ADDI, reg, tmpreg2, 0, LOW_PART(value));
- } else {
- emitpcode(PC_LI, reg, value);
- }
-}
-
-static void set_op_flags(Operand *op, ENode *expr) {
- CError_ASSERT(118, op);
-
- if (expr) {
- if (expr->type == EINTCONST) {
- op->flags = 0;
- if (expr->flags & ENODE_FLAG_VOLATILE)
- op->flags |= OpndFlags_Volatile;
- if (expr->flags & ENODE_FLAG_CONST)
- op->flags |= OpndFlags_Const;
- } else {
- op->flags = CParserIsVolatileExpr(expr) ? OpndFlags_Volatile : 0;
- op->flags |= CParserIsConstExpr(expr) ? OpndFlags_Const : 0;
- }
- } else {
- op->flags = 0;
- }
-}
-
-void symbol_operand(Operand *op, Object *obj) {
- memclrw(op, sizeof(Operand));
- op->optype = OpndType_Symbol;
- op->object = obj;
-}
-
-void indirect(Operand *op, ENode *expr) {
- switch (op->optype) {
- case OpndType_GPRPair:
- CError_FATAL(163);
- case OpndType_CRField:
- case OpndType_IndirectGPR_ImmOffset:
- case OpndType_IndirectGPR_Indexed:
- case OpndType_IndirectSymbol:
- if (op->optype)
- Coerce_to_register(op, TYPE(&void_ptr), 0);
- case OpndType_GPR:
- op->immOffset = 0;
- op->object = NULL;
- case OpndType_GPR_ImmOffset:
- op->optype = OpndType_IndirectGPR_ImmOffset;
- set_op_flags(op, expr);
- break;
- case OpndType_GPR_Indexed:
- op->optype = OpndType_IndirectGPR_Indexed;
- set_op_flags(op, expr);
- break;
- case OpndType_Absolute:
- if (FITS_IN_SHORT(op->immediate)) {
- op->reg = 0;
- op->immOffset = op->immediate;
- } else {
- emitpcode(PC_LIS, op->reg = used_virtual_registers[RegClass_GPR]++, 0, (short) HIGH_PART(op->immediate));
- op->immOffset = LOW_PART(op->immediate);
- }
- op->object = NULL;
- op->optype = OpndType_IndirectGPR_ImmOffset;
- set_op_flags(op, expr);
- break;
- case OpndType_Symbol:
- op->optype = OpndType_IndirectSymbol;
- set_op_flags(op, expr);
- break;
- default:
- CError_FATAL(215);
- }
-}
-
-#define COMBO_OP(a, b) (b + (a * 11))
-
-void combine(Operand *opA, Operand *opB, short output_reg, Operand *opOut) {
- Operand *tmp_op;
- int tmp;
-
- if (opA->optype == OpndType_Symbol || opA->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(opA);
- if (opB->optype == OpndType_Symbol || opB->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(opB);
-
- switch (COMBO_OP(opA->optype, opB->optype)) {
- case COMBO_OP(OpndType_GPR, OpndType_GPR):
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = opA->reg;
- opOut->regOffset = opB->reg;
- break;
- case COMBO_OP(OpndType_GPR_ImmOffset, OpndType_GPR_ImmOffset):
- if (FITS_IN_SHORT(opA->immOffset + opB->immOffset) && (!opA->object || !opB->object)) {
- opB->immOffset += opA->immOffset;
- if (!opB->object)
- opB->object = opA->object;
- } else {
- tmp = (output_reg && (output_reg != opB->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- add_immediate(tmp, opA->reg, opA->object, opA->immOffset);
- opA->reg = tmp;
- }
- case COMBO_OP(OpndType_GPR, OpndType_GPR_ImmOffset):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_GPR_ImmOffset, OpndType_GPR):
- if (opA->reg == _FP_ || opA->reg == _CALLER_SP_) {
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = (output_reg && (output_reg != opB->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opOut->regOffset = opB->reg;
- add_immediate(opOut->reg, opA->reg, opA->object, LOW_PART(opA->immOffset));
- } else if (opB->reg == _FP_ || opB->reg == _CALLER_SP_) {
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = (output_reg && (output_reg != opA->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opOut->regOffset = opA->reg;
- add_immediate(opOut->reg, opB->reg, opA->object, LOW_PART(opA->immOffset));
- } else if (opA->object) {
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = (output_reg && (output_reg != opB->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opOut->regOffset = opB->reg;
- add_immediate(opOut->reg, opA->reg, opA->object, LOW_PART(opA->immOffset));
- } else {
- opOut->optype = OpndType_GPR_ImmOffset;
- opOut->reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opOut->immOffset = opA->immOffset;
- opOut->object = opA->object;
- emitpcode(PC_ADD, opOut->reg, opA->reg, opB->reg);
- }
- break;
- case COMBO_OP(OpndType_GPR, OpndType_GPR_Indexed):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_GPR_Indexed, OpndType_GPR):
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = opA->reg;
- opOut->regOffset = (output_reg && (output_reg != opA->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, opOut->regOffset, opA->regOffset, opB->reg);
- break;
- case COMBO_OP(OpndType_GPR_ImmOffset, OpndType_GPR_Indexed):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_GPR_Indexed, OpndType_GPR_ImmOffset):
- if (opB->object) {
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = (output_reg && (output_reg != opB->reg)) ? output_reg
- : used_virtual_registers[RegClass_GPR]++;
- opOut->regOffset = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, opOut->reg, opA->reg, opA->regOffset);
- add_immediate(opOut->regOffset, opB->reg, opB->object, opB->immOffset);
- } else {
- opOut->optype = OpndType_GPR_ImmOffset;
- opOut->immOffset = opB->immOffset;
- opOut->object = opB->object;
- opOut->reg = (output_reg && (output_reg != opB->reg)) ? output_reg
- : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, opOut->reg, opA->reg, opA->regOffset);
- emitpcode(PC_ADD, opOut->reg, opOut->reg, opB->reg);
- }
- break;
- case COMBO_OP(OpndType_GPR_Indexed, OpndType_GPR_Indexed):
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = opA->reg;
- opOut->regOffset = (output_reg && (output_reg != opA->regOffset)) ? output_reg
- : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, opOut->regOffset, opB->reg, opB->regOffset);
- emitpcode(PC_ADD, opOut->regOffset, opOut->regOffset, opA->regOffset);
- break;
- case COMBO_OP(OpndType_GPR_ImmOffset, OpndType_Absolute):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_Absolute, OpndType_GPR_ImmOffset):
- if (!opB->object) {
- opOut->optype = OpndType_GPR_ImmOffset;
- opOut->reg = opB->reg;
- opOut->immOffset = opB->immOffset;
- opOut->object = opB->object;
- if (FITS_IN_SHORT(opOut->immOffset + opA->immediate)) {
- opOut->immOffset += opA->immediate;
- } else {
- opOut->reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- if (!HIGH_PART(opA->immediate)) {
- emitpcode(PC_ADDI, opOut->reg, opB->reg, 0, LOW_PART(opA->immediate));
- } else {
- emitpcode(PC_ADDIS, opOut->reg, opB->reg, 0, (short) HIGH_PART(opA->immediate));
- if (FITS_IN_SHORT(opOut->immOffset + LOW_PART(opA->immediate))) {
- opOut->immOffset += LOW_PART(opA->immediate);
- } else {
- emitpcode(PC_ADDI, opOut->reg, opOut->reg, 0, LOW_PART(opA->immediate));
- }
- }
- }
- break;
- } else if (opB->object->datatype == DLOCAL && can_add_displ_to_local(opB->object, opB->immOffset + opA->immediate)) {
- opOut->optype = OpndType_GPR_ImmOffset;
- opOut->object = opB->object;
- opOut->reg = opB->reg;
- opOut->immOffset = LOW_PART(opB->immOffset + opA->immediate);
- break;
- } else {
- opOut->reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- add_immediate(opOut->reg, opB->reg, opB->object, opB->immOffset);
- opB->optype = OpndType_GPR;
- opB->reg = opOut->reg;
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- }
- case COMBO_OP(OpndType_GPR, OpndType_Absolute):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_Absolute, OpndType_GPR):
- opOut->optype = (opA->immediate != 0) ? OpndType_GPR_ImmOffset : OpndType_GPR;
- opOut->immOffset = LOW_PART(opA->immediate);
- opOut->object = NULL;
- if (FITS_IN_SHORT(opA->immediate)) {
- opOut->reg = opB->reg;
- } else {
- opOut->reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADDIS, opOut->reg, opB->reg, 0, (short) HIGH_PART(opA->immediate));
- }
- break;
- case COMBO_OP(OpndType_GPR_Indexed, OpndType_Absolute):
- tmp_op = opA;
- opA = opB;
- opB = tmp_op;
- case COMBO_OP(OpndType_Absolute, OpndType_GPR_Indexed):
- opOut->optype = OpndType_GPR_Indexed;
- opOut->reg = opB->reg;
- opOut->regOffset = (output_reg && (output_reg != opB->reg)) ? output_reg : used_virtual_registers[RegClass_GPR]++;
- if (!HIGH_PART(opA->immediate)) {
- emitpcode(PC_ADDI, opOut->regOffset, opB->regOffset, 0, LOW_PART(opA->immediate));
- } else {
- emitpcode(PC_ADDIS, opOut->regOffset, opB->regOffset, 0, (short) HIGH_PART(opA->immediate));
- if (LOW_PART_BUGGY(opA->immediate))
- emitpcode(PC_ADDI, opOut->regOffset, opOut->regOffset, 0, LOW_PART(opA->immediate));
- }
- break;
- case COMBO_OP(OpndType_Absolute, OpndType_Absolute):
- opOut->optype = OpndType_Absolute;
- opOut->immediate = opA->immediate + opB->immediate;
- break;
- default:
- CError_FATAL(415);
- }
-}
-
-void coerce_to_addressable(Operand *op) {
- UInt32 offset;
- short reg;
- short flag;
- short tmp;
- Object *obj;
-
- flag = 0;
- obj = op->object;
- tmp = 0;
-
- switch (op->optype) {
- case OpndType_GPR:
- case OpndType_GPR_ImmOffset:
- case OpndType_GPR_Indexed:
- case OpndType_GPRPair:
- case OpndType_Absolute:
- case OpndType_VR:
- case OpndType_CRField:
- case OpndType_IndirectGPR_ImmOffset:
- case OpndType_IndirectGPR_Indexed:
- break;
- case OpndType_IndirectSymbol:
- flag = 1;
- case OpndType_Symbol:
- if (obj->datatype == DLOCAL) {
- if (!local_is_16bit_offset(obj)) {
- reg = used_virtual_registers[RegClass_GPR]++;
- op_absolute_ha(reg, local_base_register(obj), obj, 0, 1);
- op->optype = OpndType_GPR_ImmOffset;
- op->reg = reg;
- op->object = obj;
- } else {
- op->optype = OpndType_GPR_ImmOffset;
- op->reg = local_base_register(obj);
- op->object = obj;
- }
- } else if (obj->datatype == DABSOLUTE) {
- offset = obj->u.address;
- if (FITS_IN_SHORT(offset)) {
- op->reg = 0;
- op->immOffset = obj->u.address;
- } else {
- emitpcode(PC_LIS, op->reg = used_virtual_registers[RegClass_GPR]++, 0, (short) HIGH_PART(offset));
- op->immOffset = LOW_PART(obj->u.address);
- }
- op->object = obj;
- op->optype = OpndType_GPR_ImmOffset;
- } else {
- if (copts.codegen_pic)
- tmp = pic_base_reg;
- reg = used_virtual_registers[RegClass_GPR]++;
- op_absolute_ha(reg, tmp, obj, 0, 1);
- op->optype = OpndType_GPR_ImmOffset;
- op->reg = reg;
- }
- if (flag) {
- if (op->optype == OpndType_GPR_ImmOffset) {
- op->optype = OpndType_IndirectGPR_ImmOffset;
- } else {
- CError_FATAL(563);
- }
- }
- break;
- default:
- CError_FATAL(581);
- }
-}
-
-void Coerce_to_register(Operand *op, Type *type, short output_reg) {
- SInt32 offset;
- Opcode opcode;
- short reg;
- short tmp;
- short cond_neg;
- short cond;
- short bit_offset;
- short bit_size;
-
- if (TYPE_IS_8BYTES(type)) {
- coerce_to_register_pair(op, type, output_reg, 0);
- return;
- }
-
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_GPRPair:
- return;
- case OpndType_GPR:
- return;
- case OpndType_GPR_ImmOffset:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- add_immediate(reg, op->reg, op->object, op->immOffset);
- break;
- case OpndType_GPR_Indexed:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, reg, op->reg, op->regOffset);
- break;
- case OpndType_Absolute:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- offset = op->immediate;
- if (FITS_IN_SHORT(offset)) {
- emitpcode(PC_LI, reg, offset);
- } else {
- tmp = reg;
- if (copts.optimizationlevel > 1 && LOW_PART_BUGGY(offset))
- tmp = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LIS, tmp, 0, (short) HIGH_PART(offset));
- if (LOW_PART_BUGGY(offset))
- emitpcode(PC_ADDI, reg, tmp, 0, LOW_PART(offset));
- }
- break;
- case OpndType_IndirectGPR_ImmOffset:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opcode = PC_LWZ;
- if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
- switch (type->size) {
- case 1:
- opcode = PC_LBZ;
- break;
- case 2:
- if (is_unsigned(type))
- opcode = PC_LHZ;
- else
- opcode = PC_LHA;
- break;
- }
- } else {
- CError_ASSERT(680, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
- }
- load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- opcode = PC_LWZX;
- if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
- switch (type->size) {
- case 1:
- opcode = PC_LBZX;
- break;
- case 2:
- if (is_unsigned(type))
- opcode = PC_LHZX;
- else
- opcode = PC_LHAX;
- break;
- }
- } else {
- CError_ASSERT(724, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
- }
- emitpcode(opcode, reg, op->reg, op->regOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_CRField:
- cond_neg = 0;
- cond = 0;
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_MFCR, tmp = reg);
- switch (op->regOffset) {
- case ENOTEQU:
- cond_neg = 1;
- case EEQU:
- cond = 2;
- break;
- case EGREATEREQU:
- cond_neg = 1;
- case ELESS:
- cond = 0;
- break;
- case ELESSEQU:
- cond_neg = 1;
- case EGREATER:
- cond = 1;
- break;
- default:
- CError_FATAL(758);
- }
- bit_offset = cond + (op->reg << 2);
- bit_size = 1;
- emitpcode(PC_RLWINM, tmp, tmp, (bit_size + bit_offset) & 31, 32 - bit_size, 31);
- if (cond_neg)
- emitpcode(PC_XORI, tmp, tmp, 1);
- break;
- default:
- CError_FATAL(769);
- }
-
- op->optype = OpndType_GPR;
- op->reg = reg;
-}
-
-void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short output_regHi) {
- SInt32 offset;
- short reg;
- short regHi;
- short tmp1;
- short tmp2;
-
- regHi = -1;
-
- CError_ASSERT(794, TYPE_IS_8BYTES(type) || (IS_TYPE_STRUCT(type) && type->size == 8));
-
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_GPRPair:
- if (output_reg && !output_regHi)
- output_regHi = used_virtual_registers[RegClass_GPR]++;
- if (output_regHi && !output_reg)
- output_reg = used_virtual_registers[RegClass_GPR]++;
- if (op->reg != output_reg || op->regHi != output_regHi) {
- tmp1 = output_reg ? output_reg : op->reg;
- tmp2 = output_regHi ? output_regHi : op->regHi;
- if (tmp1 != op->reg) {
- if (tmp1 == op->regHi) {
- CError_ASSERT(818, tmp1 != tmp2);
- emitpcode(PC_MR, tmp2, op->regHi);
- emitpcode(PC_MR, tmp1, op->reg);
- } else {
- emitpcode(PC_MR, tmp1, op->reg);
- if (op->regHi != tmp2)
- emitpcode(PC_MR, tmp2, op->regHi);
- }
- } else if (tmp2 != op->regHi) {
- if (tmp2 == op->reg) {
- CError_ASSERT(832, tmp1 != tmp2);
- emitpcode(PC_MR, tmp1, op->reg);
- emitpcode(PC_MR, tmp2, op->regHi);
- } else {
- emitpcode(PC_MR, tmp2, op->regHi);
- if (op->reg != tmp1)
- emitpcode(PC_MR, tmp1, op->reg);
- }
- }
- }
- reg = op->reg;
- regHi = op->regHi;
- break;
- case OpndType_GPR:
- CError_FATAL(849);
- break;
- case OpndType_GPR_ImmOffset:
- CError_FATAL(852);
- break;
- case OpndType_GPR_Indexed:
- CError_FATAL(855);
- break;
- case OpndType_Absolute:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- offset = op->immediate;
- if (FITS_IN_SHORT(offset)) {
- emitpcode(PC_LI, reg, offset);
- } else {
- tmp1 = reg;
- if (copts.optimizationlevel > 1 && LOW_PART_BUGGY(offset))
- tmp1 = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LIS, tmp1, 0, (short) HIGH_PART(offset));
- if (LOW_PART_BUGGY(offset))
- emitpcode(PC_ADDI, reg, tmp1, 0, LOW_PART(offset));
- }
- regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
- if (is_unsigned(type) || offset >= 0)
- load_immediate(regHi, 0);
- else
- load_immediate(regHi, -1);
- break;
- case OpndType_IndirectGPR_ImmOffset:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
- if (op->reg == regHi) {
- if (op->reg == reg) {
- CError_FATAL(887);
- } else {
- load_store_register(PC_LWZ, reg, op->reg, op->object, op->immOffset + low_offset);
- setpcodeflags(op->flags);
- load_store_register(PC_LWZ, regHi, op->reg, op->object, op->immOffset + high_offset);
- setpcodeflags(op->flags);
- }
- } else {
- load_store_register(PC_LWZ, regHi, op->reg, op->object, op->immOffset + high_offset);
- setpcodeflags(op->flags);
- load_store_register(PC_LWZ, reg, op->reg, op->object, op->immOffset + low_offset);
- setpcodeflags(op->flags);
- }
- break;
- case OpndType_IndirectGPR_Indexed:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, reg, op->reg, op->regOffset);
- load_store_register(PC_LWZ, regHi, reg, NULL, high_offset);
- setpcodeflags(op->flags);
- load_store_register(PC_LWZ, reg, reg, NULL, low_offset);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(912);
- }
-
- if (regHi == -1) {
- CError_FATAL(916);
- } else {
- op->optype = OpndType_GPRPair;
- op->reg = reg;
- op->regHi = regHi;
- }
-}
-
-void Coerce_to_fp_register(Operand *op, Type *type, short output_reg) {
- short reg;
-
- coerce_to_addressable(op);
-
- switch (op->optype) {
- case OpndType_FPR:
- reg = op->reg;
- break;
- case OpndType_IndirectGPR_ImmOffset:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_FPR]++;
- load_store_register((type->size == 4) ? PC_LFS : PC_LFD, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_FPR]++;
- emitpcode((type->size == 4) ? PC_LFSX : PC_LFDX, reg, op->reg, op->regOffset, 0, 0x390);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(986);
- }
-
- op->optype = OpndType_FPR;
- op->reg = reg;
-}
-
-void Coerce_to_v_register(Operand *op, Type *type, short output_reg) {
- short reg;
-
- coerce_to_addressable(op);
-
- switch (op->optype) {
- case OpndType_VR:
- reg = op->reg;
- break;
- case OpndType_IndirectGPR_ImmOffset:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_VR]++;
- load_store_register(PC_LVX, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_VR]++;
- emitpcode(PC_LVX, reg, op->reg, op->regOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_Absolute:
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_VR]++;
- switch (TYPE_STRUCT(type)->stype) {
- case STRUCT_VECTOR_UCHAR:
- case STRUCT_VECTOR_SCHAR:
- case STRUCT_VECTOR_BCHAR:
- emitpcode(PC_VSPLTISB, reg, op->immediate);
- break;
- case STRUCT_VECTOR_USHORT:
- case STRUCT_VECTOR_SSHORT:
- case STRUCT_VECTOR_BSHORT:
- case STRUCT_VECTOR_PIXEL:
- emitpcode(PC_VSPLTISH, reg, op->immediate);
- break;
- case STRUCT_VECTOR_UINT:
- case STRUCT_VECTOR_SINT:
- case STRUCT_VECTOR_BINT:
- case STRUCT_VECTOR_FLOAT:
- emitpcode(PC_VSPLTISW, reg, op->immediate);
- break;
- default:
- CError_FATAL(1049);
- }
- op->optype = OpndType_VR;
- op->reg = reg;
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(1059);
- }
-
- op->optype = OpndType_VR;
- op->reg = reg;
-}
-
-void store(short reg, Operand *op, Type *type) {
- Opcode opcode;
-
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_IndirectGPR_ImmOffset:
- opcode = PC_STW;
- if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
- switch (type->size) {
- case 1:
- opcode = PC_STB;
- break;
- case 2:
- opcode = PC_STH;
- break;
- }
- } else {
- CError_ASSERT(1171, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
- }
- load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- opcode = PC_STWX;
- if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
- switch (type->size) {
- case 1:
- opcode = PC_STBX;
- break;
- case 2:
- opcode = PC_STHX;
- break;
- }
- } else {
- CError_ASSERT(1188, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
- }
- emitpcode(opcode, reg, op->reg, op->regOffset);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(1193);
- }
-}
-
-void store_pair(short reg, short regHi, Operand *op, Type *type) {
- short tmp;
-
- CError_ASSERT(1208, TYPE_IS_8BYTES(type));
-
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_IndirectGPR_ImmOffset:
- load_store_register(PC_STW, reg, op->reg, op->object, op->immOffset + low_offset);
- setpcodeflags(op->flags);
- load_store_register(PC_STW, regHi, op->reg, op->object, op->immOffset + high_offset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- tmp = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, tmp, op->reg, op->regOffset);
- load_store_register(PC_STW, reg, tmp, NULL, low_offset);
- setpcodeflags(op->flags);
- load_store_register(PC_STW, regHi, tmp, NULL, high_offset);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(1228);
- }
-}
-
-void store_fp(short reg, Operand *op, Type *type) {
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_IndirectGPR_ImmOffset:
- load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- emitpcode((type->size == 4) ? PC_STFSX : PC_STFDX, reg, op->reg, op->regOffset);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(1259);
- }
-}
-
-void store_v(short reg, Operand *op, Type *tstruct) {
- coerce_to_addressable(op);
- switch (op->optype) {
- case OpndType_IndirectGPR_ImmOffset:
- load_store_register(PC_STVX, reg, op->reg, op->object, op->immOffset);
- setpcodeflags(op->flags);
- break;
- case OpndType_IndirectGPR_Indexed:
- emitpcode(PC_STVX, reg, op->reg, op->regOffset);
- setpcodeflags(op->flags);
- break;
- default:
- CError_FATAL(1283);
- }
-}
-
-static Boolean last_matches_rlwinm_or_exts(Operand *op, short opcode, short b, short c) {
- PCode *pc;
-
- if (pclastblock->pcodeCount <= 0)
- return 0;
-
- pc = pclastblock->lastPCode;
- if (pc->args[0].kind != PCOp_REGISTER || pc->args[0].arg != RegClass_GPR || pc->args[0].data.reg.reg != op->reg)
- return 0;
-
- if (pc->op != opcode && (opcode != PC_EXTSH || pc->op != PC_EXTSB))
- return 0;
-
- if (opcode == PC_RLWINM) {
- if (pc->args[2].data.imm.value != 0 || pc->args[3].data.imm.value != b || pc->args[4].data.imm.value != c)
- return 0;
- }
-
- return 1;
-}
-
-void extend32(Operand *op, Type *type, short output_reg) {
- int r28;
- int reg;
-
- r28 = op->optype >= OpndType_IndirectGPR_ImmOffset;
- if (op->optype != OpndType_GPR)
- Coerce_to_register(op, type, output_reg);
-
- switch (type->size) {
- case 1:
- if (is_unsigned(type)) {
- if (r28)
- return;
- if (last_matches_rlwinm_or_exts(op, PC_RLWINM, 24, 31))
- return;
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, reg, op->reg, 0, 24, 31);
- } else {
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- if (last_matches_rlwinm_or_exts(op, PC_EXTSB, 0, 0))
- return;
- emitpcode(PC_EXTSB, reg, op->reg);
- }
- break;
- case 2:
- if (r28)
- return;
- if (is_unsigned(type)) {
- if (last_matches_rlwinm_or_exts(op, PC_RLWINM, 16, 31))
- return;
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, reg, op->reg, 0, 16, 31);
- } else {
- if (last_matches_rlwinm_or_exts(op, PC_EXTSH, 0, 0))
- return;
- reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_EXTSH, reg, op->reg);
- }
- break;
- default:
- CError_FATAL(1389);
- }
-
- op->optype = OpndType_GPR;
- op->reg = reg;
-}
-
-void extend64(Operand *op, Type *type, short output_reg, short output_regHi) {
- short tmp;
- short regHi;
-
- if (op->optype != OpndType_GPR)
- Coerce_to_register(op, type, output_reg);
-
- regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
- if (regHi == op->reg) {
- tmp = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_MR, tmp, op->reg);
- op->reg = tmp;
- }
-
- if (is_unsigned(type))
- load_immediate(regHi, 0);
- else
- emitpcode(PC_SRAWI, regHi, op->reg, 31);
-
- op->optype = OpndType_GPRPair;
- op->regHi = regHi;
-}
-
-void load_floating_constant(short reg, Type *type, Float *data) {
- Object *object;
- Object *indObject;
- Operand op1;
- Operand op2;
- Operand op3;
- SInt32 offset = 0;
-
- memclrw(&op1, sizeof(Operand));
-
- object = CreateFloatConst(type, data, &offset);
- indObject = createIndirect(object, 0, 1);
-
- if (indObject) {
- symbol_operand(&op1, indObject);
- indirect(&op1, NULL);
- } else {
- symbol_operand(&op1, object);
- }
-
- if (offset) {
- op2 = op1;
- memclrw(&op3, sizeof(Operand));
- op3.optype = OpndType_Absolute;
- op3.immediate = offset;
- if (op2.optype != OpndType_GPR)
- Coerce_to_register(&op2, TYPE(&void_ptr), 0);
- combine(&op2, &op3, 0, &op1);
- }
-
- indirect(&op1, NULL);
- if (op1.optype != OpndType_FPR)
- Coerce_to_fp_register(&op1, type, reg);
-}
-
-void convert_integer_to_floating(Operand *op, Boolean is_single, short output_reg) {
- Operand temp_op;
- Float d;
- int const_reg;
- int tmp_reg;
- int work_reg;
- int result_reg;
- Opcode opcode;
-
- symbol_operand(&temp_op, maketemporary(TYPE(&stdouble)));
- coerce_to_addressable(&temp_op);
- d.value = *((double *) &int_to_float_cc);
-
- const_reg = used_virtual_registers[RegClass_FPR]++;
- load_floating_constant(const_reg, TYPE(&stdouble), &d);
-
- tmp_reg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_XORIS, tmp_reg, op->reg, 0x8000);
- load_store_register(PC_STW, tmp_reg, temp_op.reg, temp_op.object, low_offset);
-
- emitpcode(PC_LIS, tmp_reg = used_virtual_registers[RegClass_GPR]++, 0, 0x4330);
- load_store_register(PC_STW, tmp_reg, temp_op.reg, temp_op.object, high_offset);
-
- load_store_register(PC_LFD, work_reg = used_virtual_registers[RegClass_FPR]++, temp_op.reg, temp_op.object, 0);
-
- result_reg = output_reg ? output_reg : used_virtual_registers[RegClass_FPR]++;
- if (is_single != 0)
- opcode = PC_FSUBS;
- else
- opcode = PC_FSUB;
- emitpcode(opcode, result_reg, work_reg, const_reg);
-
- op->optype = OpndType_FPR;
- op->reg = result_reg;
-}
-
-void convert_unsigned_to_floating(Operand *op, Boolean is_single, short output_reg) {
- Operand temp_op;
- Float d;
- int const_reg;
- int tmp_reg;
- int work_reg;
- int result_reg;
- Opcode opcode;
-
- symbol_operand(&temp_op, maketemporary(TYPE(&stdouble)));
- coerce_to_addressable(&temp_op);
- d.value = *((double *) &uns_to_float_cc);
-
- const_reg = used_virtual_registers[RegClass_FPR]++;
- load_floating_constant(const_reg, TYPE(&stdouble), &d);
-
- load_store_register(PC_STW, op->reg, temp_op.reg, temp_op.object, low_offset);
-
- emitpcode(PC_LIS, tmp_reg = used_virtual_registers[RegClass_GPR]++, 0, 0x4330);
- load_store_register(PC_STW, tmp_reg, temp_op.reg, temp_op.object, high_offset);
-
- load_store_register(PC_LFD, work_reg = used_virtual_registers[RegClass_FPR]++, temp_op.reg, temp_op.object, 0);
-
- result_reg = output_reg ? output_reg : used_virtual_registers[RegClass_FPR]++;
- if (is_single != 0)
- opcode = PC_FSUBS;
- else
- opcode = PC_FSUB;
- emitpcode(opcode, result_reg, work_reg, const_reg);
-
- op->optype = OpndType_FPR;
- op->reg = result_reg;
-}
-
-void convert_floating_to_integer(Operand *op, short output_reg) {
- Operand temp_op;
- int tmp_reg;
- int result_reg;
-
- symbol_operand(&temp_op, maketemporary(TYPE(&stdouble)));
- coerce_to_addressable(&temp_op);
-
- tmp_reg = used_virtual_registers[RegClass_FPR]++;
- emitpcode(PC_FCTIWZ, tmp_reg, op->reg);
- load_store_register(PC_STFD, tmp_reg, temp_op.reg, temp_op.object, 0);
-
- result_reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LWZ, result_reg, temp_op.reg, temp_op.object, low_offset);
-
- op->optype = OpndType_GPR;
- op->reg = result_reg;
-}
-
-void convert_floating_to_unsigned(Operand *op, short output_reg) {
- static UInt32 used_regs[RegClassMax] = {0, 0, 0, 2, 0};
-
- if (op->reg != 1)
- emitpcode(PC_FMR, 1, op->reg);
-
- branch_subroutine(rt_cvt_fp2unsigned, 0, used_regs);
-
- op->optype = OpndType_GPR;
- op->reg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_MR, op->reg, 3);
-}
-
-void extract_bitfield(Operand *input_op, TypeBitfield *tbitfield, short output_reg, Operand *output_op) {
- int r27;
- int offset;
- int tmp_reg;
- int output;
-
- offset = tbitfield->bitlength;
- output = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
- r27 = tbitfield->offset + (32 - (tbitfield->bitfieldtype->size * 8));
- if (is_unsigned(tbitfield->bitfieldtype)) {
- emitpcode(PC_RLWINM, output, input_op->reg, (r27 + offset) & 31, 32 - offset, 31);
- } else if (r27 == 0) {
- emitpcode(PC_SRAWI, output, input_op->reg, 32 - offset);
- } else {
- tmp_reg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmp_reg, input_op->reg, r27 & 31, 0, offset);
- emitpcode(PC_SRAWI, output, tmp_reg, 32 - offset);
- }
-
- output_op->optype = OpndType_GPR;
- output_op->reg = output;
-}
-
-void insert_bitfield(short reg, Operand *op, TypeBitfield *tbitfield) {
- int offset = tbitfield->bitlength;
- int r7 = tbitfield->offset + (32 - (tbitfield->bitfieldtype->size * 8));
- emitpcode(PC_RLWIMI, op->reg, reg, 32 - (r7 + offset), r7, r7 + offset - 1);
-}
-
-void load_address(short dest_reg, Operand *op) {
- coerce_to_addressable(op);
- if (op->optype == OpndType_IndirectGPR_ImmOffset) {
- if (!op->immOffset && !op->object) {
- if (op->reg != dest_reg)
- emitpcode(PC_MR, dest_reg, op->reg);
- } else {
- add_immediate(dest_reg, op->reg, op->object, (SInt16) op->immOffset);
- }
- } else if (op->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(PC_ADD, dest_reg, op->reg, op->regOffset);
- } else {
- CError_FATAL(1849);
- }
-}
diff --git a/compiler_and_linker/unsorted/PCodeAssembly.c b/compiler_and_linker/unsorted/PCodeAssembly.c
deleted file mode 100644
index 368f8c5..0000000
--- a/compiler_and_linker/unsorted/PCodeAssembly.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-#include "compiler/PCodeAssembly.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PPCError.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/objects.h"
-
-static UInt32 codebase;
-
-static SInt32 pcode_update_mem_labeldiff_imm(PCode *instr, const PCodeArg *op, WeirdOperand *wop) {
- SInt32 offset;
- Object *object;
- UInt8 arg;
-
- if (op->kind == PCOp_MEMORY) {
- object = op->data.mem.obj;
- offset = op->data.mem.offset;
- switch (object->datatype) {
- case DLOCAL:
- switch ((UInt8) op->arg) {
- case RefType_1:
- offset += local_offset_16(object);
- break;
- case RefType_D:
- offset = local_offset_lo(object, offset);
- break;
- case RefType_C:
- offset = local_offset_ha(object, offset);
- break;
- default:
- CError_FATAL(83);
- }
- break;
- case DDATA:
- case DFUNC:
- case DVFUNC:
- case DNONLAZYPTR:
- switch ((UInt8) op->arg) {
- case RefType_6:
- wop->type = MW_RELOC_5_LO16;
- break;
- case RefType_2:
- wop->type = MW_RELOC_3;
- break;
- case RefType_3:
- wop->type = MW_RELOC_4;
- break;
- case RefType_8:
- wop->type = MW_RELOC_7_HA16;
- break;
- case RefType_7:
- wop->type = MW_RELOC_6_HI16;
- break;
- default:
- CError_FATAL(135);
- }
-
- wop->x2 = object;
- CError_ASSERT(144, offset == 0);
- break;
- default:
- CError_FATAL(164);
- }
- } else if (op->kind == PCOp_LABELDIFF) {
- arg = op->arg;
-
- offset = op->data.labeldiff.labelA->block->codeOffset - op->data.labeldiff.labelB->block->codeOffset;
- offset += op->data.labeldiff.offset;
- if (arg == 1)
- offset = -offset;
-
- if (offset > 0x7FFF)
- PPCError_Error(PPCErrorStr109);
- else if (offset < -0x8000)
- PPCError_Error(PPCErrorStr109);
- } else if (op->kind == PCOp_IMMEDIATE) {
- offset = op->data.imm.value;
- } else {
- CError_FATAL(193);
- }
-
- return offset;
-}
-
-UInt32 assemblepcode(PCode *instr, UInt32 offset, WeirdOperand *wop) {
- UInt32 bits;
-
- bits = opcodeinfo[instr->op].insn;
- wop->type = -1;
- wop->x6 = 0;
-
- switch (instr->op) {
- case PC_BL: {
- int flag = PCODE_FLAG_SET_T(instr) & fAbsolute;
- if (instr->args[0].kind == PCOp_MEMORY) {
- bits |= instr->args[0].data.mem.offset & 0x3FFFFFC;
- wop->type = MW_RELOC_2_BR24;
- wop->x2 = instr->args[0].data.mem.obj;
- if (flag == 0)
- wop->type = MW_RELOC_2_BR24;
- else
- CError_FATAL(246);
- } else if (instr->args[0].kind == PCOp_IMMEDIATE) {
- bits |= instr->args[0].data.imm.value & 0x3FFFFFC;
- if (flag)
- bits |= 2;
- } else {
- bits |= (instr->args[0].data.label.label->block->codeOffset - offset) & 0x3FFFFFC;
- if (flag)
- CError_FATAL(261);
- }
- break;
- }
-
- case PC_B: {
- int flag = PCODE_FLAG_SET_T(instr) & fAbsolute;
- if (instr->args[0].kind == PCOp_MEMORY) {
- bits |= instr->args[0].data.mem.offset & 0x3FFFFFC;
- wop->x2 = instr->args[0].data.mem.obj;
- if (flag == 0)
- wop->type = MW_RELOC_2_BR24;
- else
- CError_FATAL(288);
- } else if (instr->args[0].kind == PCOp_IMMEDIATE) {
- bits |= instr->args[0].data.imm.value & 0x3FFFFFC;
- if (flag)
- bits |= 2;
- } else {
- bits |= (instr->args[0].data.label.label->block->codeOffset - offset) & 0x3FFFFFC;
- if (flag)
- CError_FATAL(302);
- }
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- break;
- }
-
- case PC_BDNZ:
- case PC_BDZ: {
- int flag = PCODE_FLAG_SET_T(instr) & fAbsolute;
- if (instr->args[0].kind == PCOp_MEMORY) {
- bits |= instr->args[0].data.mem.offset & 0xFFFC;
- wop->x2 = instr->args[0].data.mem.obj;
- if (flag == 0)
- wop->type = MW_RELOC_8;
- else
- CError_FATAL(333);
- } else {
- SInt32 value;
- if (instr->args[0].kind == PCOp_IMMEDIATE)
- value = instr->args[0].data.imm.value;
- else
- value = instr->args[0].data.label.label->block->codeOffset - offset;
-
- bits |= value & 0xFFFF;
- if (value < 0) {
- if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken)
- bits |= 0x200000u;
- } else {
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- bits |= 0x200000u;
- }
- }
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- break;
- }
-
- case PC_BC: {
- int flag = PCODE_FLAG_SET_T(instr) & fAbsolute;
- bits |= (instr->args[0].data.imm.value & 31) << 21;
- bits |= ((instr->args[1].data.reg.reg * 4 + instr->args[2].data.imm.value) & 31) << 16;
-
- if (instr->args[3].kind == PCOp_MEMORY) {
- bits |= instr->args[3].data.mem.offset & 0xFFFC;
- wop->x2 = instr->args[3].data.mem.obj;
- if (flag == 0)
- wop->type = MW_RELOC_8;
- else
- CError_FATAL(387);
- } else {
- SInt32 value;
- if (instr->args[3].kind == PCOp_IMMEDIATE)
- value = instr->args[3].data.imm.value;
- else
- value = instr->args[3].data.label.label->block->codeOffset - offset;
-
- bits |= value & 0xFFFF;
- if (value < 0) {
- if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken)
- bits |= 0x200000u;
- } else {
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- bits |= 0x200000u;
- }
- }
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- break;
- }
-
- case PC_BT:
- case PC_BF:
- case PC_BDNZT:
- case PC_BDNZF:
- case PC_BDZT:
- case PC_BDZF: {
- int flag = PCODE_FLAG_SET_T(instr) & fAbsolute;
- bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 16;
-
- if (instr->args[2].kind == PCOp_MEMORY) {
- bits |= instr->args[2].data.mem.offset & 0xFFFC;
- wop->x2 = instr->args[2].data.mem.obj;
- if (flag == 0)
- wop->type = MW_RELOC_8;
- else
- CError_FATAL(446);
- } else {
- SInt32 value;
- if (instr->args[2].kind == PCOp_IMMEDIATE) {
- value = instr->args[2].data.imm.value;
- if (flag)
- bits |= 2;
- } else {
- value = instr->args[2].data.label.label->block->codeOffset - offset;
- CError_ASSERT(458, !flag);
- }
-
- bits |= value & 0xFFFF;
-
- if (value < 0) {
- if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken)
- bits |= 0x200000u;
- } else {
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- bits |= 0x200000u;
- }
- }
-
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- break;
- }
-
- case PC_BTLR:
- case PC_BTCTR:
- case PC_BFLR:
- case PC_BFCTR:
- bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 16;
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- bits |= 0x200000u;
- break;
-
- case PC_BCLR:
- case PC_BCCTR:
- bits |= instr->args[0].data.imm.value << 21;
- bits |= ((instr->args[1].data.reg.reg * 4 + instr->args[2].data.imm.value) & 31) << 16;
- case PC_BLR:
- case PC_BCTR:
- case PC_BCTRL:
- case PC_BLRL:
- if (PCODE_FLAG_SET_T(instr) & fLink)
- bits |= 1;
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- bits |= 0x200000u;
- break;
-
- case PC_CRAND:
- case PC_CRANDC:
- case PC_CREQV:
- case PC_CRNAND:
- case PC_CRNOR:
- case PC_CROR:
- case PC_CRORC:
- case PC_CRXOR:
- bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 21;
- bits |= ((instr->args[2].data.reg.reg * 4 + instr->args[3].data.imm.value) & 31) << 16;
- bits |= ((instr->args[4].data.reg.reg * 4 + instr->args[5].data.imm.value) & 31) << 11;
- break;
-
- case PC_MCRF:
- bits |= instr->args[0].data.reg.reg << 23;
- bits |= instr->args[1].data.reg.reg << 18;
- break;
-
- case PC_LBZ:
- case PC_LBZU:
- case PC_LHZ:
- case PC_LHZU:
- case PC_LHA:
- case PC_LHAU:
- case PC_LWZ:
- case PC_LWZU:
- case PC_LMW:
- case PC_STB:
- case PC_STBU:
- case PC_STH:
- case PC_STHU:
- case PC_STW:
- case PC_STWU:
- case PC_STMW:
- case PC_LFS:
- case PC_LFSU:
- case PC_LFD:
- case PC_LFDU:
- case PC_STFS:
- case PC_STFSU:
- case PC_STFD:
- case PC_STFDU:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF;
- break;
-
- case PC_LBZX:
- case PC_LBZUX:
- case PC_LHZX:
- case PC_LHZUX:
- case PC_LHAX:
- case PC_LHAUX:
- case PC_LHBRX:
- case PC_LWZX:
- case PC_LWZUX:
- case PC_LWBRX:
- case PC_STBX:
- case PC_STBUX:
- case PC_STHX:
- case PC_STHUX:
- case PC_STHBRX:
- case PC_STWX:
- case PC_STWUX:
- case PC_STWBRX:
- case PC_LFSX:
- case PC_LFSUX:
- case PC_LFDX:
- case PC_LFDUX:
- case PC_STFSX:
- case PC_STFSUX:
- case PC_STFDX:
- case PC_STFDUX:
- case PC_LWARX:
- case PC_LSWX:
- case PC_STFIWX:
- case PC_STSWX:
- case PC_STWCX:
- case PC_ECIWX:
- case PC_ECOWX:
- case PC_DCREAD:
- case PC_TLBSX:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_DCBF:
- case PC_DCBST:
- case PC_DCBT:
- case PC_DCBTST:
- case PC_DCBZ:
- case PC_DCBI:
- case PC_ICBI:
- case PC_DCCCI:
- case PC_ICBT:
- case PC_ICCCI:
- case PC_ICREAD:
- case PC_DCBA:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 11;
- break;
-
- case PC_ADD:
- case PC_ADDC:
- case PC_ADDE:
- case PC_DIVW:
- case PC_DIVWU:
- case PC_MULHW:
- case PC_MULHWU:
- case PC_MULLW:
- case PC_SUBF:
- case PC_SUBFC:
- case PC_SUBFE:
- bits |= instr->args[2].data.reg.reg << 11;
- case PC_ADDME:
- case PC_ADDZE:
- case PC_NEG:
- case PC_SUBFME:
- case PC_SUBFZE:
- case PC_MFROM:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- if (PCODE_FLAG_SET_F(instr) & fOverflow)
- bits |= 0x400;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_ADDI:
- case PC_ADDIC:
- case PC_ADDICR:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF;
- break;
-
- case PC_ADDIS:
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF;
- break;
-
- case PC_MULLI:
- case PC_SUBFIC:
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[2].data.imm.value & 0xFFFF;
- break;
-
- case PC_LI:
- case PC_LIS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[1], wop) & 0xFFFF;
- break;
-
- case PC_ANDI:
- case PC_ANDIS:
- case PC_ORI:
- case PC_ORIS:
- case PC_XORI:
- case PC_XORIS:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF;
- break;
-
- case PC_AND:
- case PC_OR:
- case PC_XOR:
- case PC_NAND:
- case PC_NOR:
- case PC_EQV:
- case PC_ANDC:
- case PC_ORC:
- case PC_SLW:
- case PC_SRW:
- case PC_SRAW:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_EXTSH:
- case PC_EXTSB:
- case PC_CNTLZW:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_MR:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_NOT:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_SRAWI:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= (instr->args[2].data.imm.value & 31) << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_RLWINM:
- case PC_RLWIMI:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= (instr->args[2].data.imm.value & 31) << 11;
- bits |= (instr->args[3].data.imm.value & 31) << 6;
- bits |= (instr->args[4].data.imm.value & 31) << 1;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_RLWNM:
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[2].data.reg.reg << 11;
- bits |= (instr->args[3].data.imm.value & 31) << 6;
- bits |= (instr->args[4].data.imm.value & 31) << 1;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_CMP:
- case PC_CMPL:
- bits |= instr->args[0].data.reg.reg << 23;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- break;
-
- case PC_CMPI:
- case PC_CMPLI:
- bits |= instr->args[0].data.reg.reg << 23;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.imm.value & 0xFFFF;
- break;
-
- case PC_MTXER:
- case PC_MTCTR:
- case PC_MTLR:
- case PC_MTMSR:
- case PC_MFMSR:
- case PC_MFXER:
- case PC_MFCTR:
- case PC_MFLR:
- case PC_MFCR:
- bits |= instr->args[0].data.reg.reg << 21;
- break;
-
- case PC_MFFS:
- bits |= instr->args[0].data.reg.reg << 21;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_MTCRF:
- bits |= instr->args[0].data.imm.value << 12;
- bits |= instr->args[1].data.reg.reg << 21;
- break;
-
- case PC_MTFSF:
- bits |= (instr->args[0].data.imm.value & 0xFF) << 17;
- bits |= instr->args[1].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_FMR:
- case PC_FABS:
- case PC_FNEG:
- case PC_FNABS:
- case PC_FRES:
- case PC_FRSQRTE:
- case PC_FRSP:
- case PC_FCTIW:
- case PC_FCTIWZ:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_FADD:
- case PC_FADDS:
- case PC_FSUB:
- case PC_FSUBS:
- case PC_FDIV:
- case PC_FDIVS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_FMADD:
- case PC_FMADDS:
- case PC_FMSUB:
- case PC_FMSUBS:
- case PC_FNMADD:
- case PC_FNMADDS:
- case PC_FNMSUB:
- case PC_FNMSUBS:
- case PC_FSEL:
- bits |= instr->args[3].data.reg.reg << 11;
- case PC_FMUL:
- case PC_FMULS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 6;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_FCMPU:
- case PC_FCMPO:
- bits |= instr->args[0].data.reg.reg << 23;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- break;
-
- case PC_MTSPR:
- if (instr->args[0].kind == PCOp_REGISTER) {
- CError_ASSERT(1027, instr->args[0].arg == RegClass_SPR);
- CError_ASSERT(1028, instr->args[0].data.reg.reg < 4);
- bits |= ((spr_to_sysreg[instr->args[0].data.reg.reg] & 0x1F) << 16) +
- ((spr_to_sysreg[instr->args[0].data.reg.reg] & 0x3E0) << 6);
- } else if (instr->args[0].kind == PCOp_SYSREG && instr->args[0].arg == 0) {
- bits |= ((instr->args[0].data.reg.reg & 0x1F) << 16) +
- ((instr->args[0].data.reg.reg & 0x3E0) << 6);
- } else {
- CError_FATAL(1033);
- }
-
- bits |= instr->args[1].data.reg.reg << 21;
- break;
-
- case PC_MTDCR:
- if (instr->args[0].kind == PCOp_IMMEDIATE) {
- bits |= ((instr->args[0].data.imm.value & 0x1F) << 16) +
- ((instr->args[0].data.imm.value & 0x3E0) << 6);
- } else {
- CError_FATAL(1042);
- }
-
- bits |= instr->args[1].data.reg.reg << 21;
- break;
-
- case PC_MFSPR:
- bits |= instr->args[0].data.reg.reg << 21;
-
- if (instr->args[1].kind == PCOp_REGISTER && instr->args[1].arg == RegClass_SPR) {
- CError_ASSERT(1055, instr->args[1].data.reg.reg < 4);
- bits |= ((spr_to_sysreg[instr->args[1].data.reg.reg] & 0x1F) << 16) +
- ((spr_to_sysreg[instr->args[1].data.reg.reg] & 0x3E0) << 6);
- } else if (instr->args[1].kind == PCOp_SYSREG && instr->args[1].arg == 0) {
- bits |= ((instr->args[1].data.reg.reg & 0x1F) << 16) +
- ((instr->args[1].data.reg.reg & 0x3E0) << 6);
- } else {
- CError_FATAL(1060);
- }
- break;
-
- case PC_MFDCR:
- bits |= instr->args[0].data.reg.reg << 21;
-
- if (instr->args[1].kind == PCOp_IMMEDIATE) {
- bits |= ((instr->args[1].data.imm.value & 0x1F) << 16) +
- ((instr->args[1].data.imm.value & 0x3E0) << 6);
- } else {
- CError_FATAL(1069);
- }
- break;
-
- case PC_LSWI:
- case PC_STSWI:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= (instr->args[2].data.imm.value & 31) << 11;
- break;
-
- case PC_MCRFS:
- bits |= (instr->args[1].data.imm.value & 7) << 18;
- case PC_MCRXR:
- bits |= instr->args[0].data.reg.reg << 23;
- break;
-
- case PC_MFTB:
- bits |= instr->args[0].data.reg.reg << 21;
- if (instr->args[1].kind == PCOp_SYSREG && instr->args[1].arg == 0) {
- if (instr->args[1].data.reg.reg == 284)
- bits |= 0xC4000u;
- else if (instr->args[1].data.reg.reg == 285)
- bits |= 0xD4000u;
- else
- CError_FATAL(1100);
- } else {
- CError_FATAL(1103);
- }
- break;
-
- case PC_MTSR:
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= (instr->args[0].data.imm.value & 15) << 16;
- break;
-
- case PC_MFSR:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= (instr->args[1].data.imm.value & 15) << 16;
- break;
-
- case PC_MFSRIN:
- case PC_MTSRIN:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- break;
-
- case PC_MTFSB0:
- case PC_MTFSB1:
- bits |= (instr->args[0].data.imm.value & 31) << 21;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_MTFSFI:
- bits |= instr->args[0].data.reg.reg << 23;
- bits |= (instr->args[1].data.imm.value & 15) << 12;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_FSQRT:
- case PC_FSQRTS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_TLBIE:
- case PC_TLBLD:
- case PC_TLBLI:
- bits |= instr->args[0].data.reg.reg << 11;
- break;
-
- case PC_TW:
- bits |= (instr->args[0].data.imm.value & 31) << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- break;
-
- case PC_TWI:
- bits |= (instr->args[0].data.imm.value & 31) << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.imm.value & 0xFFFF;
- break;
-
- case PC_OPWORD:
- CError_ASSERT(1176, instr->args[0].kind != PCOp_MEMORY);
- bits = pcode_update_mem_labeldiff_imm(instr, &instr->args[0], wop);
- break;
-
- case PC_MASKG:
- case PC_MASKIR:
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_LSCBX:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_DIV:
- case PC_DIVS:
- case PC_DOZ:
- case PC_MUL:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fOverflow)
- bits |= 0x400;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_NABS:
- case PC_ABS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- if (PCODE_FLAG_SET_F(instr) & fOverflow)
- bits |= 0x400;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_CLCS:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_DOZI:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.imm.value & 0xFFFF;
- break;
-
- case PC_RLMI:
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- bits |= (instr->args[3].data.imm.value & 31) << 6;
- bits |= (instr->args[4].data.imm.value & 31) << 1;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_SLE:
- case PC_SLEQ:
- case PC_SLLQ:
- case PC_SLQ:
- case PC_SRAQ:
- case PC_SRE:
- case PC_SREA:
- case PC_SREQ:
- case PC_SRLQ:
- case PC_SRQ:
- case PC_RRIB:
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_SLIQ:
- case PC_SLLIQ:
- case PC_SRAIQ:
- case PC_SRIQ:
- case PC_SRLIQ:
- bits |= instr->args[1].data.reg.reg << 21;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= (instr->args[2].data.imm.value & 31) << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 1;
- break;
-
- case PC_TLBRE:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= (instr->args[2].data.imm.value & 1) << 11;
- break;
-
- case PC_TLBWE:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= (instr->args[2].data.imm.value & 1) << 11;
- break;
-
- case PC_WRTEE:
- bits |= instr->args[0].data.reg.reg << 21;
- break;
-
- case PC_WRTEEI:
- bits |= instr->args[0].data.imm.value << 15;
- break;
-
- case PC_DSTT:
- case PC_DSTSTT:
- bits |= 0x2000000u;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 11;
- bits |= (instr->args[2].data.imm.value & 3) << 21;
- break;
-
- case PC_DST:
- case PC_DSTST:
- bits |= (instr->args[3].data.imm.value & 1) << 25;
- bits |= instr->args[0].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 11;
- bits |= (instr->args[2].data.imm.value & 3) << 21;
- break;
-
- case PC_DSSALL:
- bits |= 0x2000000u;
- break;
-
- case PC_DSS:
- bits |= (instr->args[1].data.imm.value & 1) << 25;
- bits |= (instr->args[0].data.imm.value & 3) << 21;
- break;
-
- case PC_LVEBX:
- case PC_LVEHX:
- case PC_LVEWX:
- case PC_LVSL:
- case PC_LVSR:
- case PC_LVX:
- case PC_LVXL:
- case PC_STVEBX:
- case PC_STVEHX:
- case PC_STVEWX:
- case PC_STVX:
- case PC_STVXL:
- case PC_VADDCUW:
- case PC_VADDFP:
- case PC_VADDSBS:
- case PC_VADDSHS:
- case PC_VADDSWS:
- case PC_VADDUBM:
- case PC_VADDUBS:
- case PC_VADDUHM:
- case PC_VADDUHS:
- case PC_VADDUWM:
- case PC_VADDUWS:
- case PC_VAND:
- case PC_VANDC:
- case PC_VAVGSB:
- case PC_VAVGSH:
- case PC_VAVGSW:
- case PC_VAVGUB:
- case PC_VAVGUH:
- case PC_VAVGUW:
- case PC_VMAXFP:
- case PC_VMAXSB:
- case PC_VMAXSH:
- case PC_VMAXSW:
- case PC_VMAXUB:
- case PC_VMAXUH:
- case PC_VMAXUW:
- case PC_VMINFP:
- case PC_VMINSB:
- case PC_VMINSH:
- case PC_VMINSW:
- case PC_VMINUB:
- case PC_VMINUH:
- case PC_VMINUW:
- case PC_VMRGHB:
- case PC_VMRGHH:
- case PC_VMRGHW:
- case PC_VMRGLB:
- case PC_VMRGLH:
- case PC_VMRGLW:
- case PC_VMULESB:
- case PC_VMULESH:
- case PC_VMULEUB:
- case PC_VMULEUH:
- case PC_VMULOSB:
- case PC_VMULOSH:
- case PC_VMULOUB:
- case PC_VMULOUH:
- case PC_VNOR:
- case PC_VOR:
- case PC_VPKPX:
- case PC_VPKSHSS:
- case PC_VPKSHUS:
- case PC_VPKSWSS:
- case PC_VPKSWUS:
- case PC_VPKUHUM:
- case PC_VPKUHUS:
- case PC_VPKUWUM:
- case PC_VPKUWUS:
- case PC_VRLB:
- case PC_VRLH:
- case PC_VRLW:
- case PC_VSL:
- case PC_VSLB:
- case PC_VSLH:
- case PC_VSLO:
- case PC_VSLW:
- case PC_VSR:
- case PC_VSRAB:
- case PC_VSRAH:
- case PC_VSRAW:
- case PC_VSRB:
- case PC_VSRH:
- case PC_VSRO:
- case PC_VSRW:
- case PC_VSUBCUW:
- case PC_VSUBFP:
- case PC_VSUBSBS:
- case PC_VSUBSHS:
- case PC_VSUBSWS:
- case PC_VSUBUBM:
- case PC_VSUBUBS:
- case PC_VSUBUHM:
- case PC_VSUBUHS:
- case PC_VSUBUWM:
- case PC_VSUBUWS:
- case PC_VSUMSWS:
- case PC_VSUM2SWS:
- case PC_VSUM4SBS:
- case PC_VSUM4SHS:
- case PC_VSUM4UBS:
- case PC_VXOR:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- break;
-
- case PC_VCFSX:
- case PC_VCFUX:
- case PC_VCTSXS:
- case PC_VCTUXS:
- case PC_VSPLTB:
- case PC_VSPLTH:
- case PC_VSPLTW:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- bits |= (instr->args[2].data.imm.value & 31) << 16;
- break;
-
- case PC_VEXPTEFP:
- case PC_VLOGEFP:
- case PC_VREFP:
- case PC_VRFIM:
- case PC_VRFIN:
- case PC_VRFIP:
- case PC_VRFIZ:
- case PC_VRSQRTEFP:
- case PC_VUPKHPX:
- case PC_VUPKHSB:
- case PC_VUPKHSH:
- case PC_VUPKLPX:
- case PC_VUPKLSB:
- case PC_VUPKLSH:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 11;
- break;
-
- case PC_VCMPBFP:
- case PC_VCMPEQFP:
- case PC_VCMPEQUB:
- case PC_VCMPEQUH:
- case PC_VCMPEQUW:
- case PC_VCMPGEFP:
- case PC_VCMPGTFP:
- case PC_VCMPGTSB:
- case PC_VCMPGTSH:
- case PC_VCMPGTSW:
- case PC_VCMPGTUB:
- case PC_VCMPGTUH:
- case PC_VCMPGTUW:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- bits |= 0x400;
- break;
-
- case PC_VSPLTISB:
- case PC_VSPLTISH:
- case PC_VSPLTISW:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= (instr->args[1].data.imm.value & 31) << 16;
- break;
-
- case PC_VMHADDSHS:
- case PC_VMHRADDSHS:
- case PC_VMLADDUHM:
- case PC_VMSUMMBM:
- case PC_VMSUMSHM:
- case PC_VMSUMSHS:
- case PC_VMSUMUBM:
- case PC_VMSUMUHM:
- case PC_VMSUMUHS:
- case PC_VPERM:
- case PC_VSEL:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- bits |= instr->args[3].data.reg.reg << 6;
- break;
-
- case PC_VMADDFP:
- case PC_VNMSUBFP:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 6;
- bits |= instr->args[3].data.reg.reg << 11;
- break;
-
- case PC_VSLDOI:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[2].data.reg.reg << 11;
- bits |= (instr->args[3].data.imm.value & 15) << 6;
- break;
-
- case PC_VMR:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 11;
- break;
-
- case PC_VMRP:
- bits |= instr->args[0].data.reg.reg << 21;
- bits |= instr->args[1].data.reg.reg << 16;
- bits |= instr->args[1].data.reg.reg << 11;
- break;
-
- case PC_MFVSCR:
- bits |= instr->args[0].data.reg.reg << 21;
- break;
-
- case PC_MTVSCR:
- bits |= instr->args[0].data.reg.reg << 11;
- break;
-
- case PC_EIEIO:
- case PC_ISYNC:
- case PC_SYNC:
- case PC_RFI:
- case PC_NOP:
- case PC_SC:
- case PC_TLBIA:
- case PC_TLBSYNC:
- case PC_TRAP:
- case PC_DSA:
- case PC_ESA:
- case PC_RFCI:
- break;
-
- default:
- CError_FATAL(2203);
- }
-
- return CTool_EndianConvertWord32(bits);
-}
-
-static PCode *targetinstruction(PCodeLabel *label) {
- PCodeBlock *block = label->block;
- while (block->pcodeCount == 0)
- block = block->nextBlock;
- return block->firstPCode;
-}
-
-static void invertybit(PCode *instr, SInt32 value) {
- if (instr->op == PC_BC) {
- if (instr->args[0].data.imm.value & 1) {
- if (value < 0)
- instr->flags |= fBranchNotTaken;
- else
- instr->flags |= fBranchTaken;
- }
- } else if (instr->op == PC_BCCTR || instr->op == PC_BCLR) {
- if (instr->args[0].data.imm.value & 1)
- instr->flags |= fBranchTaken;
- }
-
- if (PCODE_FLAG_SET_T(instr) & fBranchTaken)
- instr->flags = (instr->flags & ~fBranchTaken) | fBranchNotTaken;
- else if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken)
- instr->flags = (instr->flags & ~fBranchNotTaken) | fBranchTaken;
- else if (value < 0)
- instr->flags = (instr->flags & ~fBranchTaken) | fBranchNotTaken;
- else
- instr->flags = (instr->flags & ~fBranchNotTaken) | fBranchTaken;
-}
-
-static void insertlongbranches(SInt32 mask) {
- PCodeBlock *block;
- PCodeLabel *label;
- SInt32 i;
-
- i = 0;
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- block->codeOffset = i;
- if (block->pcodeCount) {
- i += block->pcodeCount * 4;
- if (block->pcodeCount && (block->lastPCode->flags & fIsBranch))
- i += 4;
- }
- }
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (block->pcodeCount && (block->lastPCode->flags & fIsBranch)) {
- switch (block->lastPCode->op) {
- case PC_BT:
- case PC_BF:
- i = block->codeOffset + ((block->pcodeCount - 1) * 4);
- if (block->lastPCode->args[2].kind == PCOp_LABEL) {
- label = block->lastPCode->args[2].data.label.label;
- i = label->block->codeOffset - i;
- if (i != ((SInt16) (i & mask))) {
- block->lastPCode->op = (block->lastPCode->op == PC_BT) ? PC_BF : PC_BT;
- block->lastPCode->args[2].data.label.label = block->nextBlock->labels;
- invertybit(block->lastPCode, i);
- appendpcode(block, makepcode(PC_B, label));
- }
- }
- break;
-
- case PC_BC:
- i = block->codeOffset + ((block->pcodeCount - 1) * 4);
- if (block->lastPCode->args[3].kind == PCOp_LABEL) {
- label = block->lastPCode->args[3].data.label.label;
- i = label->block->codeOffset - i;
- invertybit(block->lastPCode, i);
- if (i != ((SInt16) (i & mask))) {
- switch (block->lastPCode->args[0].data.imm.value & 30) {
- case 0:
- case 2:
- case 8:
- case 10:
- block->lastPCode->args[0].data.imm.value ^= 11;
- block->lastPCode->args[3].data.label.label = block->nextBlock->labels;
- break;
- case 16:
- case 18:
- block->lastPCode->args[0].data.imm.value ^= 3;
- block->lastPCode->args[3].data.label.label = block->nextBlock->labels;
- break;
- case 4:
- case 12:
- block->lastPCode->args[0].data.imm.value ^= 9;
- block->lastPCode->args[3].data.label.label = block->nextBlock->labels;
- break;
- case 20:
- deletepcode(block->lastPCode);
- break;
- default:
- CError_FATAL(2368);
- }
-
- appendpcode(block, makepcode(PC_B, label));
- }
- }
- break;
-
- case PC_BDNZ:
- case PC_BDZ:
- i = block->codeOffset + ((block->pcodeCount - 1) * 4);
- if (block->lastPCode->args[0].kind == PCOp_LABEL) {
- label = block->lastPCode->args[0].data.label.label;
- i = label->block->codeOffset - i;
- if (i != ((SInt16) (i & mask))) {
- switch (block->lastPCode->op) {
- case PC_BDZ:
- block->lastPCode->op = PC_BDNZ;
- break;
- case PC_BDNZ:
- block->lastPCode->op = PC_BDZ;
- break;
- default:
- CError_FATAL(2389);
- }
-
- block->lastPCode->args[0].data.label.label = block->nextBlock->labels;
- invertybit(block->lastPCode, i);
- appendpcode(block, makepcode(PC_B, label));
- }
- }
- break;
-
- case PC_BDNZT:
- case PC_BDNZF:
- case PC_BDZT:
- case PC_BDZF:
- i = block->codeOffset + ((block->pcodeCount - 1) * 4);
- if (block->lastPCode->args[2].kind == PCOp_LABEL) {
- label = block->lastPCode->args[2].data.label.label;
- i = label->block->codeOffset - i;
- if (i != ((SInt16) (i & mask))) {
- switch (block->lastPCode->op) {
- case PC_BDNZT:
- block->lastPCode->op = PC_BDZF;
- break;
- case PC_BDNZF:
- block->lastPCode->op = PC_BDZT;
- break;
- case PC_BDZT:
- block->lastPCode->op = PC_BDNZF;
- break;
- case PC_BDZF:
- block->lastPCode->op = PC_BDNZT;
- break;
- default:
- CError_FATAL(2420);
- }
-
- block->lastPCode->args[2].data.label.label = block->nextBlock->labels;
- invertybit(block->lastPCode, i);
- appendpcode(block, makepcode(PC_B, label));
- }
- }
- break;
-
- }
- }
- }
-}
-
-SInt32 optimizefinalbranches(SInt32 codesize) {
- PCodeBlock *block;
- PCode *instr;
- SInt32 offset;
- int changed;
- int deleted;
- PCodeLabel *label;
- PCode *target;
-
- do {
- changed = deleted = 0;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (block->pcodeCount == 0)
- continue;
-
- instr = block->lastPCode;
- if (!(instr->flags & fIsBranch))
- continue;
-
- offset = block->codeOffset + (block->pcodeCount - 1) * 4;
-
- if (instr->op == PC_B && instr->args[0].kind == PCOp_LABEL) {
- label = instr->args[0].data.label.label;
- target = targetinstruction(label);
-
- if (label->block->codeOffset == (offset + 4)) {
- deletepcode(instr);
- changed = deleted = 1;
- } else if (target->op == PC_B) {
- if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[0].data.label.label) {
- instr->args[0].data.label.label = target->args[0].data.label.label;
- changed = 1;
- }
- } else if (target->op == PC_BLR) {
- instr->op = PC_BLR;
- changed = 1;
- }
- continue;
- }
-
- if ((instr->op == PC_BT || instr->op == PC_BF) && instr->args[2].kind == PCOp_LABEL) {
- PCodeBlock *block2 = instr->block;
- label = instr->args[2].data.label.label;
- target = targetinstruction(label);
-
- if (label->block->codeOffset == (offset + 4)) {
- deletepcode(instr);
- changed = deleted = 1;
- } else if (target->op == PC_B) {
- if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[2].data.label.label) {
- instr->args[2].data.label.label = target->args[0].data.label.label;
- changed = 1;
- }
- } else if (copts.opt_bcc_lr_ctr) {
- if (target->op == PC_BLR) {
- if (instr->op == PC_BT)
- instr->op = PC_BTLR;
- else
- instr->op = PC_BFLR;
- instr->argCount = 2;
- changed = 1;
- } else if (target->op == PC_BCTR) {
- if (instr->op == PC_BT)
- instr->op = PC_BTCTR;
- else
- instr->op = PC_BFCTR;
- instr->argCount = 2;
- changed = 1;
- } else if (
- block2->nextBlock &&
- block2->nextBlock->firstPCode &&
- block2->nextBlock->firstPCode->op == PC_BLR &&
- label->block->codeOffset == (offset + 8)
- ) {
- if (
- block2->nextBlock->predecessors &&
- block2->nextBlock->predecessors->block == block2 &&
- !block2->nextBlock->predecessors->nextLink
- ) {
- if (instr->op == PC_BT)
- instr->op = PC_BFLR;
- else
- instr->op = PC_BTLR;
- change_num_operands(instr, 2);
- deletepcode(block2->nextBlock->firstPCode);
- changed = deleted = 1;
- }
- } else if (
- block2->nextBlock &&
- block2->nextBlock->firstPCode &&
- block2->nextBlock->firstPCode->op == PC_BCTR &&
- label->block->codeOffset == (offset + 8)
- ) {
- if (
- block2->nextBlock->predecessors &&
- block2->nextBlock->predecessors->block == block2 &&
- !block2->nextBlock->predecessors->nextLink
- ) {
- if (instr->op == PC_BT)
- instr->op = PC_BFCTR;
- else
- instr->op = PC_BTCTR;
- change_num_operands(instr, 2);
- deletepcode(block2->nextBlock->firstPCode);
- changed = deleted = 1;
- }
- }
- }
- continue;
- }
-
- if (
- instr->op == PC_BC &&
- instr->args[3].kind == PCOp_LABEL &&
- !(PCODE_FLAG_SET_T(instr) & (fSideEffects | fLink))
- )
- {
- PCodeBlock *block2 = instr->block;
- label = instr->args[3].data.label.label;
- target = targetinstruction(label);
-
- if (label->block->codeOffset == (offset + 4)) {
- deletepcode(instr);
- changed = deleted = 1;
- } else if (target->op == PC_B) {
- if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[3].data.label.label) {
- instr->args[3].data.label.label = target->args[0].data.label.label;
- changed = 1;
- }
- } else if (copts.opt_bcc_lr_ctr) {
- if (target->op == PC_BLR) {
- instr->op = PC_BCLR;
- instr->argCount = 3;
- changed = 1;
- } else if (target->op == PC_BCTR) {
- instr->op = PC_BCCTR;
- instr->argCount = 3;
- changed = 1;
- } else if (
- block2->nextBlock &&
- block2->nextBlock->firstPCode &&
- block2->nextBlock->firstPCode->op == PC_BLR &&
- label->block->codeOffset == (offset + 8)
- ) {
- SInt32 val = instr->args[0].data.imm.value & 30;
- if (
- block2->nextBlock->predecessors &&
- block2->nextBlock->predecessors->block == block2 &&
- !block2->nextBlock->predecessors->nextLink
- ) {
- if ((val & 30) == 4)
- instr->args[0].data.imm.value = val | 12;
- else if ((val & 30) == 12)
- instr->args[0].data.imm.value = val & 23;
- instr->op = PC_BCLR;
- instr->argCount = 3;
- deletepcode(block2->nextBlock->firstPCode);
- changed = deleted = 1;
- }
- } else if (
- block2->nextBlock &&
- block2->nextBlock->firstPCode &&
- block2->nextBlock->firstPCode->op == PC_BCTR &&
- label->block->codeOffset == (offset + 8)
- ) {
- SInt32 val = instr->args[0].data.imm.value & 30;
- if (
- block2->nextBlock->predecessors &&
- block2->nextBlock->predecessors->block == block2 &&
- !block2->nextBlock->predecessors->nextLink
- ) {
- if ((val & 30) == 4)
- instr->args[0].data.imm.value = val | 12;
- else if ((val & 30) == 12)
- instr->args[0].data.imm.value = val & 23;
- instr->op = PC_BCCTR;
- instr->argCount = 3;
- deletepcode(block2->nextBlock->firstPCode);
- changed = deleted = 1;
- }
- }
- }
- }
- }
-
- if (deleted)
- codesize = pccomputeoffsets();
- } while (changed);
-
- return codesize;
-}
-
-static SInt32 insert_align_nops(Object *func, SInt32 codesize) {
- PCodeBlock *block;
- int changed;
- PCodeBlock *prev;
-
- do {
- changed = 0;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (
- (block->flags & fPCBlockFlag6000) == fPCBlockFlag2000 &&
- (block->codeOffset & 7) &&
- block->pcodeCount < 8 &&
- (prev = block->prevBlock) &&
- !(prev->flags & fPCBlockFlag2000)
- )
- {
- if (prev->lastPCode && prev->lastPCode->op == PC_NOP && !(prev->lastPCode->flags & fSideEffects)) {
- deletepcode(prev->lastPCode);
- } else {
- PCode *nop = makepcode(PC_NOP);
- nop->flags &= ~fSideEffects;
- appendpcode(prev, nop);
- }
-
- codesize = pccomputeoffsets();
- changed = 1;
- }
- }
-
- if (changed) {
- pclistblocks(CMangler_GetLinkName(func)->name, "AFTER INSERT ALIGN NOPs");
- if (codesize > 32766) {
- insertlongbranches(32766);
- codesize = pccomputeoffsets();
- }
- }
-
- } while (changed);
-
- return codesize;
-}
-
-SInt32 assemblefunction(Object *func, EntryPoint *entrypoints) {
- void *tbdata;
- GList *gl;
- PCodeBlock *block;
- PCode *instr;
- SInt32 offset2;
- SInt32 codesize;
- SInt32 tbsize;
- SInt32 offset;
- SectionHandle section;
- EntryPoint *ep;
- WeirdOperand wop;
-
- codesize = pccomputeoffsets();
- if (codesize <= 0)
- PPCError_Error(PPCErrorStr190, func->name->name);
-
- if (copts.peephole || copts.optimizationlevel >= 3)
- codesize = optimizefinalbranches(codesize);
-
- if (codesize > 32766) {
- insertlongbranches(32766);
- codesize = pccomputeoffsets();
- }
-
- if (copts.function_align > 4)
- codesize = insert_align_nops(func, codesize);
-
- tbsize = 0;
- if (copts.traceback)
- tbdata = generate_traceback(codesize, CMangler_GetLinkName(func)->name, &tbsize, func);
-
- if (func->section == SECT_DEFAULT)
- func->section = SECT_TEXT;
-
- offset = tbsize;
- section = ObjGen_DeclareCode(func, codesize + tbsize);
- gl = ObjGen_GetSectionGList(section);
-
- codebase = gl->size;
- AppendGListNoData(gl, codesize + tbsize);
-
- if (copts.filesyminfo) {
- ObjGen_SymFunc(func);
- ObjGen_Line(functionbodyoffset, 0);
- ObjGen_DeclareSymInfo();
- }
-
- if (uses_globals && pic_base_reg)
- ObjGen_DeclarePICBase(func, pic_base_pcodelabel->block->codeOffset);
-
- if (entrypoints) {
- for (ep = entrypoints; ep; ep = ep->next) {
- ObjGen_DeclareEntry(ep->object, ep->block->codeOffset);
- }
- }
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (offset2 = block->codeOffset, instr = block->firstPCode; instr; instr = instr->nextPCode, offset2 += 4) {
- if (copts.filesyminfo && instr->sourceoffset != -1)
- ObjGen_Line(instr->sourceoffset, offset2);
-
- *((UInt32 *) (*gl->data + codebase + offset2)) = assemblepcode(instr, offset2, &wop);
-
- if (wop.type != -1)
- ObjGen_RelocateObj(section, offset2, wop.x2, wop.type);
- }
- }
-
- if (copts.filesyminfo)
- ObjGenMach_SymFuncEnd(func, codesize);
-
- if (copts.traceback)
- memcpy(*gl->data + codebase + codesize, tbdata, offset);
-
- if (copts.traceback)
- return codesize + tbsize;
- else
- return codesize;
-}
diff --git a/compiler_and_linker/unsorted/PCodeInfo.c b/compiler_and_linker/unsorted/PCodeInfo.c
deleted file mode 100644
index b2e2385..0000000
--- a/compiler_and_linker/unsorted/PCodeInfo.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-#include "compiler/PCodeInfo.h"
-#include "compiler/CError.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/Alias.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-#pragma pool_strings on
-
-int pcode_bad_operand;
-char *orig_buf;
-static int do_show_basic_blocks;
-
-void pcode_get_hi_lo(int bits, char typechar, SInt32 *hi, SInt32 *lo) {
- if (bits == 0) {
- *hi = 0;
- *lo = 0;
- return;
- }
- if (bits == 32) {
- *hi = 0x7FFFFFFF;
- *lo = -0x80000000;
- return;
- }
-
- if (bits < 32 && bits > 0) {
- switch (typechar) {
- case 'u':
- *hi = (1 << bits) - 1;
- *lo = 0;
- break;
- case 'i':
- case 'x':
- *hi = (1 << bits) - 1;
- *lo = -(1 << (bits - 1));
- break;
- default:
- *hi = (1 << (bits - 1)) - 1;
- *lo = -(1 << (bits - 1));
- }
- } else {
- CError_FATAL(65);
- }
-}
-
-int pcode_check_imm_bits(SInt32 value, int bits, char typechar) {
- char buf[2];
- int forcedBits;
- SInt32 r6;
- SInt32 r0;
-
- forcedBits = 0;
- if (bits >= 0 && bits < 32) {
- if (bits == 0) {
- r6 = 0;
- r0 = 0;
- } else {
- switch (typechar) {
- case 'u':
- r6 = (1 << bits) - 1;
- r0 = 0;
- break;
- case 'i':
- case 'x':
- r6 = (1 << bits) - 1;
- r0 = -(1 << (bits - 1));
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- buf[0] = typechar;
- buf[1] = 0;
- forcedBits = atoi(buf);
- default:
- r6 = (1 << (bits - 1)) - 1;
- r0 = -(1 << (bits - 1));
- }
- }
-
- if ((value < r0) || (value > r6))
- return 1;
- if (forcedBits > 0 && value != ((value >> forcedBits) << forcedBits))
- return 1;
- } else if (bits > 32) {
- CError_FATAL(110);
- }
-
- return 0;
-}
-
-int pcode_const_from_format(const char *format, SInt32 *pResult) {
- char buf[32];
- int len = 0;
-
- for (len = 0; len < 30 && isdigit(format[len]); len++) {
- buf[len] = format[len];
- }
- buf[len] = 0;
-
- *pResult = atoi(buf);
- return len;
-}
-
-PCode *vformatpcode(short opcode, va_list argList) {
- // has many wrong registers but probably ok otherwise
- int argcount; // r29
- OpcodeInfo *info; // r27 for a short time
- int effect; // r27
- const char *format; // r26
- PCode *pcode; // r25
- PCodeArg *arg; // r24
- int unkreg_r23; // r23
- int unkreg_r22; // r22
- PCodeArg *lastArg; // r21
- int pcode_size; // r20 for a short time
- int tmp;
- int tmp2; // r19
- int i;
- SInt32 thing;
- SInt32 thing2;
- SInt32 thing3;
- SInt32 thing4;
- Object *obj;
- PCodeLabel *label;
- char c;
-
- info = &opcodeinfo[opcode];
- format = info->format;
- argcount = info->x8;
- unkreg_r23 = 0;
- unkreg_r22 = 0;
-
- if (format[0] == '#') {
- unkreg_r23 = va_arg(argList, int);
- argcount += unkreg_r23;
- format++;
- }
-
- if (info->flags & fCanSetRecordBit)
- unkreg_r22 = 1;
-
- if ((argcount + unkreg_r22) < 5)
- unkreg_r22 += 5 - (argcount + unkreg_r22);
-
- pcode_size = (argcount + unkreg_r22) * sizeof(PCodeArg) + sizeof(PCode);
- pcode = lalloc(pcode_size);
- memclrw(pcode, pcode_size);
-
- pcode->op = opcode;
- pcode->argCount = argcount;
- pcode->flags = info->flags;
- lastArg = pcode->args + pcode->argCount;
- arg = pcode->args;
- while (*format) {
- if (arg >= lastArg)
- CError_FATAL(189);
-
- if (*format == ',' || *format == ';')
- format++;
- if (*format == '[' || *format == '(')
- format++;
-
- effect = EffectRead;
- if (*format == '=') {
- effect = EffectWrite;
- format++;
- } else if (*format == '+') {
- effect = EffectRead | EffectWrite;
- format++;
- }
-
- if (*format == '-')
- format++;
- if (*format == '?')
- format++;
- if (*format == '!')
- format++;
-
- switch ((c = *format)) {
- case 'b':
- tmp = va_arg(argList, int);
- if (!tmp)
- effect = 0;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- break;
- case 'r':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'f':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_FPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'v':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_VR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'c':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'C':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 2;
- arg->data.reg.effect = effect;
- break;
- case 'L':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 1;
- arg->data.reg.effect = effect;
- break;
- case 'V':
- i = unkreg_r23;
- while (i > 0) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = 31 - --i;
- arg->data.reg.effect = effect;
- arg++;
- }
- arg--;
- break;
- case 'X':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0;
- arg->data.reg.effect = effect;
- break;
- case 'Y':
- if (pcode->op == PC_MTCRF) {
- tmp = pcode->args[0].data.imm.value;
- for (i = 0; i < 8; i++) {
- if (tmp & (0x80 >> i)) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = i;
- arg->data.reg.effect = EffectWrite;
- arg++;
- }
- }
- } else {
- i = 0;
- while (i < 8) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = i++;
- arg->data.reg.effect = EffectRead;
- arg++;
- }
- }
- arg--;
- break;
- case 'Z':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = 0;
- arg->data.reg.effect = effect;
- break;
- case 'P':
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing);
- else
- CError_FATAL(319);
- case 's':
- tmp = va_arg(argList, int);
- tmp2 = -1;
- for (i = 0; i < 4; i++) {
- if (tmp == spr_to_sysreg[i]) {
- tmp2 = i;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = i;
- arg->data.reg.effect = effect;
- if ((effect & EffectWrite) && (tmp == 0x100))
- pcsetsideeffects(pcode);
- break;
- }
- }
-
- if (tmp2 < 0) {
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- }
-
- break;
-
- case 'T':
- tmp = va_arg(argList, int);
- if (tmp == 0x10C) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0x11C;
- arg->data.reg.effect = effect;
- } else if (tmp == 0x10D) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0x11D;
- arg->data.reg.effect = effect;
- } else {
- CError_FATAL(353);
- }
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
-
- case 'S':
- tmp2 = -1;
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing2);
- else
- CError_FATAL(371);
-
- for (i = 0; i < 4; i++) {
- if (thing2 == spr_to_sysreg[i]) {
- tmp2 = i;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = i;
- arg->data.reg.effect = effect;
- if ((effect & EffectWrite) && (thing2 == 0x100))
- pcsetsideeffects(pcode);
- break;
- }
- }
-
- if (tmp2 < 0) {
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- }
- break;
-
- case 'a':
- case 'i':
- case 'n':
- case 'u':
- case 'w':
- case 'x':
- tmp2 = (unsigned char) c;
- thing3 = 16;
- if (*format == 'a') {
- if (isdigit(format[1]))
- tmp2 = (unsigned char) *(++format);
- else
- CError_FATAL(408);
- }
- if (isdigit(format[1])) {
- format += pcode_const_from_format(format + 1, &thing3);
- }
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, thing3, tmp2))
- CError_FATAL(419);
- break;
-
- case 'N':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 6, 'u'))
- CError_FATAL(429);
- break;
-
- case 'D':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 10, 'u'))
- CError_FATAL(438);
- break;
-
- case 'B':
- case 't':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 5, 'u'))
- CError_FATAL(448);
- break;
-
- case 'Q':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- arg++;
- case 'q':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 4, 'u'))
- CError_FATAL(463);
- break;
-
- case 'l':
- if ((label = va_arg(argList, PCodeLabel *))) {
- arg->kind = PCOp_LABEL;
- arg->data.label.label = label;
- } else {
- arg->kind = PCOp_MEMORY;
- obj = va_arg(argList, Object *);
- CError_ASSERT(476, obj->otype == OT_OBJECT);
- arg->data.mem.obj = obj;
- arg->data.mem.offset = 0;
- arg->arg = RefType_4;
- }
- break;
-
- case 'd':
- CError_ASSERT(490, format[1] == '(');
- effect = EffectRead;
- format += 2;
- if (*format == '=') {
- effect = EffectWrite;
- format++;
- } else if (*format == '+') {
- effect = EffectRead | EffectWrite;
- format++;
- }
-
- CError_ASSERT(502, format[0] == 'b');
-
- tmp = va_arg(argList, int);
- if (tmp == 0)
- effect = 0;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- arg++;
-
- case 'm':
- obj = va_arg(argList, Object *);
- if (obj) {
- CError_ASSERT(515, obj->otype == OT_OBJECT);
-
- if (obj->datatype == DABSOLUTE) {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.obj = obj;
- arg->data.imm.value = va_arg(argList, SInt32);
- } else {
- arg->kind = PCOp_MEMORY;
- arg->data.mem.obj = obj;
- arg->data.mem.offset = va_arg(argList, SInt32);
-
- if (pcode->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- pcode->alias = make_alias(obj, arg->data.mem.offset, nbytes_loaded_or_stored_by(pcode));
- if (is_volatile_object(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- } else {
- if (pcode->op == PC_ADDI)
- pcode->alias = make_alias(obj, arg->data.mem.offset, 1);
- }
- CError_ASSERT(536, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
- if (pcode->flags & (fIsRead | fIsWrite)) {
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
- if (OBJ_GET_TARGET_VOLATILE(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- }
-
- if (pcode->flags & (fIsBranch | fIsCall)) {
- arg->arg = RefType_4;
- } else if (obj->datatype == DLOCAL) {
- if (!local_is_16bit_offset(obj))
- arg->arg = RefType_D;
- else
- arg->arg = RefType_1;
- } else {
- arg->arg = RefType_6;
- }
- }
- } else {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, SInt32);
- arg->data.imm.obj = NULL;
- if (pcode->flags & (fIsRead | fIsWrite))
- pcode->flags |= fIsPtrOp;
- }
- break;
-
- case 'M':
- obj = va_arg(argList, Object *);
- if (obj) {
- CError_ASSERT(578, obj->otype == OT_OBJECT);
-
- if (obj->datatype == DABSOLUTE) {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.obj = obj;
- arg->data.imm.value = va_arg(argList, SInt32);
- } else {
- arg->kind = PCOp_MEMORY;
- arg->data.mem.obj = obj;
- arg->data.mem.offset = va_arg(argList, SInt32);
-
- CError_ASSERT(590, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
- if (pcode->flags & (fIsRead | fIsWrite)) {
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
- if (OBJ_GET_TARGET_VOLATILE(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- }
-
- if (obj->datatype == DLOCAL) {
- arg->arg = RefType_C;
- } else {
- arg->arg = RefType_8;
- }
- }
- } else {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, SInt32);
- arg->data.imm.obj = NULL;
- if (pcode->flags & (fIsRead | fIsWrite))
- pcode->flags |= fIsPtrOp;
- }
- break;
-
- case 'p':
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- break;
-
- case 'O':
- arg--;
- break;
-
- default:
- CError_FATAL(629);
- }
-
- while (format[1] && strchr("/<>|*", format[1])) {
- switch (*(++format)) {
- case '/':
- if (format[1] == '2')
- format++;
- break;
- case '<':
- case '*':
- case '|':
- case '>':
- if (format[1] == 'p')
- format++;
- else if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing4);
- else
- CError_FATAL(659);
- break;
- }
- }
-
- if ((c = *(++format)) == ']' || c == ')')
- format++;
- arg++;
- }
-
- while (arg < lastArg) {
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- arg++;
- }
- while (unkreg_r22) {
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- arg++;
- unkreg_r22--;
- }
- return pcode;
-}
-
-int expectandformatoperand(PCodeArg *operand, PCOpKind expectedKind, char a3, int bitCount, char *buf) {
- int errorlen;
- char *name;
- int tmp;
- int regclass;
- int refis1;
- int b_null;
-
- errorlen = 0;
-
- if (operand->kind != expectedKind) {
- char *kindstr;
- switch (expectedKind) {
- case PCOp_REGISTER: kindstr = "REGISTER"; break;
- case PCOp_SYSREG: kindstr = "SYSREG"; break;
- case PCOp_IMMEDIATE: kindstr = "IMMEDIATE"; break;
- case PCOp_MEMORY: kindstr = "MEMORY"; break;
- case PCOp_LABEL: kindstr = "LABEL"; break;
- case PCOp_LABELDIFF: kindstr = "LABELDIFF"; break;
- case PCOp_PLACEHOLDEROPERAND: kindstr = "PLACEHOLDEROPERAND"; break;
- default: kindstr = "unknown kind";
- }
- tmp = sprintf(buf, "{EXPECTED %s}", kindstr);
- errorlen += tmp;
- buf += tmp;
- pclist_bad_operand = 1;
- }
-
- switch (operand->kind) {
- case PCOp_REGISTER:
- if (operand->arg != (regclass = a3)) {
- tmp = sprintf(buf, "{EXPECTED %s}", register_class_name[regclass]);
- errorlen += tmp;
- buf += tmp;
- }
- if (operand->data.reg.reg < n_real_registers[regclass] && (name = special_register_names[operand->arg][operand->data.reg.reg]))
- tmp = sprintf(buf, "%s", name);
- else
- tmp = sprintf(buf, register_class_format[operand->arg], operand->data.reg.reg);
- errorlen += tmp;
- break;
- case PCOp_SYSREG:
- if (operand->arg != RegClass_SPR) {
- tmp = sprintf(buf, "{EXPECTED %s}", register_class_name[RegClass_SPR]);
- errorlen += tmp;
- buf += tmp;
- }
- tmp = sprintf(buf, register_class_format[RegClass_SPR], operand->data.reg.reg);
- errorlen += tmp;
- break;
- case PCOp_IMMEDIATE:
- switch (a3) {
- case 'x':
- tmp = sprintf(buf, "0x%x", operand->data.imm.value);
- break;
- case 'u':
- tmp = sprintf(buf, "%u", operand->data.imm.value);
- break;
- default:
- tmp = sprintf(buf, "%" PRId32, operand->data.imm.value);
- break;
- }
- errorlen += tmp;
- buf += tmp;
- if (operand->data.imm.obj) {
- name = CMangler_GetLinkName(operand->data.imm.obj)->name;
- if (strlen(name) > 50)
- tmp = sprintf(buf, "{%45.45s...}", name);
- else
- tmp = sprintf(buf, "{%s}", name);
- errorlen += tmp;
- buf += tmp;
- }
- if (pcode_check_imm_bits(operand->data.imm.value, bitCount, (char) a3)) {
- errorlen += sprintf(buf, "{IMM too large %i bits}", bitCount);
- pclist_bad_operand = 1;
- }
- break;
- case PCOp_MEMORY:
- switch ((unsigned char) operand->arg) {
- case RefType_0:
- case RefType_1:
- case RefType_2:
- case RefType_3:
- case RefType_4:
- case RefType_5:
- case RefType_9:
- break;
- case RefType_8:
- case RefType_B:
- case RefType_C:
- tmp = sprintf(buf, "HA(");
- errorlen += tmp;
- buf += tmp;
- break;
- case RefType_7:
- tmp = sprintf(buf, "HI(");
- errorlen += tmp;
- buf += tmp;
- break;
- case RefType_6:
- case RefType_A:
- case RefType_D:
- tmp = sprintf(buf, "LO(");
- errorlen += tmp;
- buf += tmp;
- break;
- default:
- tmp = sprintf(buf, "{UNEXPECTED reftype = %d}", (unsigned char) operand->arg);
- errorlen += tmp;
- buf += tmp;
- }
- name = CMangler_GetLinkName(operand->data.mem.obj)->name;
- if (strlen(name) == 0 || strlen(name) > 3200 || name[0] < 0)
- CError_FATAL(849);
- if (strlen(name) > 50)
- tmp = sprintf(buf, "%45.45s...", name);
- else
- tmp = sprintf(buf, "%s", name);
- errorlen += tmp;
- buf += tmp;
- if (operand->data.mem.offset > 0)
- tmp = sprintf(buf, "+%d", operand->data.mem.offset);
- else if (operand->data.mem.offset != 0)
- tmp = sprintf(buf, "-%d", -operand->data.mem.offset);
- else
- tmp = 0;
- errorlen += tmp;
- buf += tmp;
- if (copts.codegen_pic && uses_globals && pic_base_reg) {
- tmp = sprintf(buf, "-B%d", pic_base_pcodelabel->block->blockIndex);
- errorlen += tmp;
- buf += tmp;
- }
- switch ((unsigned char) operand->arg) {
- case RefType_6:
- case RefType_7:
- case RefType_8:
- case RefType_A:
- case RefType_B:
- case RefType_C:
- case RefType_D:
- errorlen += sprintf(buf, ")");
- }
- break;
- case PCOp_LABEL:
- if (do_show_basic_blocks) {
- if (!operand->data.label.label->block)
- tmp = sprintf(buf, "B<unknown>");
- else
- tmp = sprintf(buf, "B%" PRId32, operand->data.label.label->block->blockIndex);
- } else {
- tmp = sprintf(buf, "%.8" PRIX32, operand->data.label.label->block->codeOffset);
- }
- errorlen += tmp;
- break;
- case PCOp_LABELDIFF:
- refis1 = ((unsigned char) operand->arg == 1);
- b_null = !operand->data.labeldiff.labelB->block;
- if (operand->data.labeldiff.labelA->block == NULL) {
- if (b_null)
- tmp = sprintf(buf, "%sB<unknown>-B<unknown>+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.offset);
- else
- tmp = sprintf(buf, "%sB<unknown>-B%" PRId32 "+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset);
- } else {
- if (b_null)
- tmp = sprintf(buf, "%sB%" PRId32 "-B<unknown>+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.offset);
- else
- tmp = sprintf(buf, "%sB%" PRId32 "-B%" PRId32 "+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset);
- }
- errorlen += tmp;
- break;
- case PCOp_PLACEHOLDEROPERAND:
- errorlen += sprintf(buf, "{placeholder}");
- break;
- default:
- errorlen += sprintf(buf, "{UNEXPECTED kind = %d}", operand->kind);
- }
-
- return errorlen;
-}
-
-int formatoperand(PCodeArg *operand, char *buf) {
- return expectandformatoperand(
- operand,
- operand->kind,
- (operand->kind == PCOp_REGISTER) ? operand->arg : 'x',
- -1,
- buf);
-}
-
-void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
- const char *format; // r29
- // there might be a PCodeArg *arg in r28
- // not sure lol
- PCodeArg *pa;
- int arg_index; // r27
-
- char *name;
- int i;
- int tmp;
- int tmp2;
- SInt32 thing;
- SInt32 thing2;
- SInt32 thing4;
- char c;
- int flagSetT;
- int flagSetF;
-
- static char *cc[] = {
- "lt", "gt", "eq", "un"
- };
- static char *to[] = {
- "", "lgt", "llt", "",
- "eq", "lge", "lle", "",
- "gt", "", "", "",
- "ge", "", "", "",
- "lt", "", "", "",
- "le", "", "", "",
- "ne", "", "", "",
- "", "", ""
- };
-
- format = opcodeinfo[pcode->op].format;
- orig_buf = buf;
- do_show_basic_blocks = showBasicBlocks;
-
- if (format[0] == '#') {
- format++;
- if (format[0] == ',')
- format++;
- }
-
- arg_index = 0;
- pa = pcode->args;
- while (*format) {
- if (*format == ';')
- break;
- if (arg_index == pcode->argCount) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "{EXCEDED noperands, remaning format = %s}", format);
- break;
- }
-
- if (*format == ',') {
- *(buf++) = ',';
- format++;
- }
-
- if (*format == '[' || *format == '(') {
- *(buf++) = *format;
- format++;
- }
-
- if (*format == '=' || *format == '+')
- format++;
- if (*format == '-')
- format++;
-
- if (*format == '?') {
- format++;
- if (*format != 'c')
- *(buf++) = ',';
- }
-
- if (*format == '!')
- format++;
-
- switch (*format) {
- case 'b':
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
- if (pa->data.reg.effect & EffectWrite) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "!!!r");
- }
- buf += sprintf(buf, "0");
- break;
- }
- case 'r':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- break;
- case 'f':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_FPR, -1, buf);
- break;
- case 'v':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_VR, -1, buf);
- break;
- case 'c':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- break;
- case 'X':
- CError_ASSERT(1124, pa->data.reg.reg == 0);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'C':
- CError_ASSERT(1129, pa->data.reg.reg == 2);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'L':
- CError_ASSERT(1134, pa->data.reg.reg == 1);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'Z':
- CError_ASSERT(1139, pa->data.reg.reg == 0);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'P':
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing);
- else
- CError_FATAL(1149);
- case 'S':
- case 'T':
- case 's':
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_SPR) {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- } else {
- for (i = 0; i < 4; i++) {
- if (pa->data.reg.reg == spr_to_sysreg[i]) {
- CError_FATAL(1161);
- break;
- }
- }
-
- buf += expectandformatoperand(pa, PCOp_SYSREG, RegClass_SPR, -1, buf);
- }
- break;
-
- case 'V':
- do {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- } while (arg_index < pcode->argCount && pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR);
- buf--;
- pa--;
- arg_index--;
- break;
-
- case 'Y':
- do {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- } while (arg_index < pcode->argCount && pa->kind == PCOp_REGISTER && pa->arg == RegClass_CRFIELD);
- buf--;
- pa--;
- arg_index--;
- break;
-
- case 'Q':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- case 'q':
- if (pa->kind == PCOp_IMMEDIATE && pa->data.imm.value >= 0 && pa->data.imm.value < 4 && (name = cc[pa->data.imm.value])[0]) {
- buf += sprintf(buf, "%s", name);
- } else {
- buf += sprintf(buf, "{OUT OF RANGE}");
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- }
- break;
- case 'a':
- case 'i':
- case 'u':
- case 'x':
- tmp = *format;
- if (tmp == 'a') {
- if (isdigit(format[1])) {
- format++;
- tmp = *format;
- } else {
- CError_FATAL(1227);
- }
- }
- if ((tmp2 = isdigit(format[1])))
- format += pcode_const_from_format(format + 1, &thing2);
- if (!tmp2)
- thing2 = -1;
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, tmp, thing2, buf);
- break;
-
- case 'N':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'u', 6, buf);
- break;
-
- case 'D':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'u', 10, buf);
- break;
-
- case 't':
- if (pa->kind == PCOp_IMMEDIATE && pa->data.imm.value > 0 && pa->data.imm.value < 31 && (name = to[pa->data.imm.value])[0]) {
- buf += sprintf(buf, "%s", name);
- break;
- }
-
- case 'B':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'x', 5, buf);
- break;
-
- case 'l':
- if (pa->kind == PCOp_IMMEDIATE) {
- buf += sprintf(buf, "*%s%" PRId32, (pa->data.imm.value >= 0) ? "+" : "", pa->data.imm.value);
- } else if (pa->kind == PCOp_LABELDIFF) {
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- } else if (pa->kind == PCOp_LABEL) {
- buf += expectandformatoperand(pa, PCOp_LABEL, 0, -1, buf);
- } else {
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- }
- break;
-
- case 'd':
- if (pa[1].kind == PCOp_MEMORY)
- buf += expectandformatoperand(pa + 1, PCOp_MEMORY, 0, -1, buf);
- else
- buf += expectandformatoperand(pa + 1, PCOp_IMMEDIATE, 0, -1, buf);
- CError_ASSERT(1283, format[1] == '(');
- format++;
- *(buf++) = *(format++);
- if (*format == '+')
- format++;
- CError_ASSERT(1291, format[0] == 'b');
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
- if (pa->data.reg.effect & (EffectRead | EffectWrite)) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "!!!r");
- }
- buf += sprintf(buf, "0");
- } else {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- }
- pa++;
- i++;
- break;
-
- case 'w':
- if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'm':
- case 'n':
- if (pa->kind == PCOp_MEMORY)
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- else if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else if ((pcode->flags & (fIsBranch | fIsCall)) && (pa->kind == PCOp_LABEL))
- buf += expectandformatoperand(pa, PCOp_LABEL, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'M':
- if (pa->kind == PCOp_MEMORY) {
- CError_ASSERT(1335, pa->arg == RefType_8 || pa->arg == RefType_B || pa->arg == RefType_C);
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- } else if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'O':
- pa--;
- arg_index--;
- break;
-
- case 'p':
- buf += expectandformatoperand(pa, PCOp_PLACEHOLDEROPERAND, 0, -1, buf);
- break;
-
- default:
- CError_FATAL(1465);
- }
-
- while (format[1] && strchr("/<>|*", format[1])) {
- switch (*(++format)) {
- case '/':
- if (format[1] == '2')
- format++;
- break;
- case '<':
- case '*':
- case '|':
- case '>':
- if (format[1] == 'p')
- format++;
- else if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing4);
- else
- CError_FATAL(1495);
- break;
- }
- }
-
- if ((c = *(++format)) == ']' || c == ')') {
- *(buf++) = c;
- format++;
- }
-
- pa++;
- arg_index++;
- }
-
- if (buf[-1] == ',')
- buf--;
-
- flagSetT = PCODE_FLAG_SET_T(pcode);
- flagSetF = PCODE_FLAG_SET_F(pcode);
- if (pcode->flags & fIsConst)
- buf += sprintf(buf, "; fIsConst");
- if (pcode->flags & fIsVolatile)
- buf += sprintf(buf, "; fIsVolatile");
- if (pcode->flags & fSideEffects)
- buf += sprintf(buf, "; fSideEffects");
- if (pcode->flags & fIsCSE)
- buf += sprintf(buf, "; fIsCSE");
- if (pcode->flags & fCommutative)
- buf += sprintf(buf, "; fCommutative");
-
- if (flagSetF & fIsPtrOp)
- buf += sprintf(buf, "; fIsPtrOp");
-
- if (flagSetT) {
- if (flagSetT & fLink)
- buf += sprintf(buf, "; fLink");
- if (flagSetT & fAbsolute)
- buf += sprintf(buf, "; fAbsolute");
- if (flagSetT & fBranchTaken)
- buf += sprintf(buf, "; fBranchTaken");
- if (flagSetT & fBranchNotTaken)
- buf += sprintf(buf, "; fBranchNotTaken");
- } else if (flagSetF) {
- if (flagSetF & fSetsCarry)
- buf += sprintf(buf, "; fSetsCarry");
- if (flagSetF & fOverflow)
- buf += sprintf(buf, "; fOverflow");
- }
-
- *buf = 0;
-}
-
-PCode *makecopyinstruction(PCodeArg *a, PCodeArg *b) {
- if (b->kind == PCOp_REGISTER) {
- switch (b->arg) {
- case RegClass_GPR:
- return makepcode(PC_MR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_FPR:
- return makepcode(PC_FMR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_VR:
- return makepcode(PC_VMR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_CRFIELD:
- return makepcode(PC_MCRF, b->data.reg.reg, a->data.reg.reg);
- }
- }
-
- CError_FATAL(1622);
- return NULL;
-}
-
-int is_location_independent(PCode *pcode) {
- switch (pcode->op) {
- case PC_LI:
- case PC_LIS:
- case PC_VSPLTISB:
- case PC_VSPLTISH:
- case PC_VSPLTISW:
- return 1;
- case PC_ADDI:
- case PC_ADDIS:
- case PC_ORI:
- case PC_ORIS:
- return pcode->args[1].data.reg.reg == _FP_;
- case PC_LWZ:
- if (
- pcode->args[1].data.reg.reg == 1 &&
- pcode->args[2].kind == PCOp_IMMEDIATE &&
- pcode->args[2].data.imm.value == 0
- )
- return 1;
- }
-
- return 0;
-}
-
-int can_reuse_stored_value(PCode *a, PCode *b) {
- switch (b->op) {
- case PC_LWZ:
- case PC_LWZU:
- case PC_LWZX:
- case PC_LWZUX:
- switch (a->op) {
- case PC_STW:
- case PC_STWU:
- case PC_STWX:
- case PC_STWUX:
- return 1;
- }
- break;
-
- case PC_LFD:
- case PC_LFDU:
- case PC_LFDX:
- case PC_LFDUX:
- switch (a->op) {
- case PC_STFD:
- case PC_STFDU:
- case PC_STFDX:
- case PC_STFDUX:
- return 1;
- }
- break;
-
- case PC_LVX:
- if (a->op == PC_STVX)
- return 1;
- break;
- }
-
- return 0;
-}
-
-int nbytes_loaded_or_stored_by(PCode *pcode) {
- OpcodeInfo *oinfo = opcodeinfo + pcode->op;
- if (oinfo->flags & (fIsRead | fIsWrite)) {
- switch (pcode->op) {
- case PC_LBZ:
- case PC_LBZU:
- case PC_LBZX:
- case PC_LBZUX:
- case PC_STB:
- case PC_STBU:
- case PC_STBX:
- case PC_STBUX:
- return 1;
- case PC_LHZ:
- case PC_LHZU:
- case PC_LHZX:
- case PC_LHZUX:
- case PC_LHA:
- case PC_LHAU:
- case PC_LHAX:
- case PC_LHAUX:
- case PC_LHBRX:
- case PC_STH:
- case PC_STHU:
- case PC_STHX:
- case PC_STHUX:
- case PC_STHBRX:
- return 2;
- case PC_LWZ:
- case PC_LWZU:
- case PC_LWZX:
- case PC_LWZUX:
- case PC_LWBRX:
- case PC_STW:
- case PC_STWU:
- case PC_STWX:
- case PC_STWUX:
- case PC_STWBRX:
- case PC_LFS:
- case PC_LFSU:
- case PC_LFSX:
- case PC_LFSUX:
- case PC_STFS:
- case PC_STFSU:
- case PC_STFSX:
- case PC_STFSUX:
- case PC_LWARX:
- case PC_STFIWX:
- case PC_STWCX:
- case PC_ECIWX:
- case PC_ECOWX:
- case PC_MFROM:
- case PC_LSCBX:
- return 4;
- case PC_LMW:
- case PC_STMW:
- if (pcode->args[0].kind == PCOp_REGISTER && pcode->args[0].arg == RegClass_GPR)
- return (32 - pcode->args[0].data.reg.reg) * 4;
- else
- return 128;
- case PC_LFD:
- case PC_LFDU:
- case PC_LFDX:
- case PC_LFDUX:
- case PC_STFD:
- case PC_STFDU:
- case PC_STFDX:
- case PC_STFDUX:
- return 8;
- case PC_LSWI:
- case PC_STSWI:
- return pcode->args[2].data.imm.value; // not sure if imm is the right union type here
- case PC_LSWX:
- case PC_STSWX:
- return 128;
-
- // there's probably an ifdef here lmao
- case PC_LVEBX:
- case PC_STVEBX:
- return 1;
- case PC_LVEHX:
- case PC_STVEHX:
- return 2;
- case PC_LVEWX:
- case PC_STVEWX:
- return 4;
- case PC_LVSL:
- case PC_LVSR:
- case PC_LVX:
- case PC_LVXL:
- case PC_STVX:
- case PC_STVXL:
- return 16;
-
- default:
- CError_FATAL(2011);
- }
- }
-
- CError_FATAL(2014);
- return 0;
-}
-
-void change_num_operands(PCode *pcode, int newNum) {
- int i;
-
- CError_ASSERT(2026, ((pcode->argCount > 5) ? pcode->argCount : 5) >= newNum);
-
- for (i = pcode->argCount - 1; i >= newNum; i--)
- pcode->args[i].kind = PCOp_PLACEHOLDEROPERAND;
-
- pcode->argCount = newNum;
-}
-
-void change_opcode(PCode *pcode, short opcode) {
- pcode->flags = (pcode->flags & ~(opcodeinfo[pcode->op].flags & ~fIsPtrOp)) | opcodeinfo[opcode].flags;
- if ((pcode->flags & fIsMove) && (PCODE_FLAG_SET_F(pcode) & fRecordBit))
- pcode->flags &= ~fIsMove;
- pcode->op = opcode;
-}
diff --git a/compiler_and_linker/unsorted/PCodeListing.c b/compiler_and_linker/unsorted/PCodeListing.c
deleted file mode 100644
index 7a9fa13..0000000
--- a/compiler_and_linker/unsorted/PCodeListing.c
+++ /dev/null
@@ -1,536 +0,0 @@
-#include "compiler/PCodeListing.h"
-#include "compiler/CError.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/Alias.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InterferenceGraph.h"
-#include "compiler/LiveInfo.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeAssembly.h"
-#include "compiler/Registers.h"
-#include "compiler/Scheduler.h"
-#include "compiler/objects.h"
-
-static FILE *pcfile;
-static int ptime;
-static int sourcetext;
-static int sourcetext_is_main;
-static int sourcelength;
-int pclist_bad_operand;
-
-static void formatdataflowset(char *name, UInt32 *vec, UInt32 size, char *format) {
- UInt32 i;
- UInt32 counter;
- char *separator;
-
- separator = "";
- fprintf(pcfile, "%s = {", name);
-
- for (i = 0, counter = 0; i < size; i++) {
- if (bitvectorgetbit(i, vec)) {
- if (i)
- fprintf(pcfile, separator);
- if (counter++ == 10) {
- fprintf(pcfile, "\n\t\t");
- counter = 0;
- }
- fprintf(pcfile, format, i);
- separator = ",";
- }
- }
-
- fprintf(pcfile, "}\n");
-}
-
-static void pclistblock(PCodeBlock *block, char *format, UInt32 vecSize) {
- PCLink *link;
- PCodeLabel *label;
- int cpu;
- int chr;
- PCode *instr;
- int offset;
- int latency;
- UInt32 opcode;
- MachineInfo *mi;
- char buf[500];
- WeirdOperand dummyArg;
-
- fprintf(pcfile, ":{%4.4x}::::::::::::::::::::::::::::::::::::::::LOOPWEIGHT=%" PRId32 "\n", block->flags, block->loopWeight);
- fprintf(pcfile, "B%" PRId32 ": ", block->blockIndex);
-
- fprintf(pcfile, "Successors = { ");
- for (link = block->successors; link; link = link->nextLink) {
- if (link->block)
- fprintf(pcfile, "B%" PRId32 " ", link->block->blockIndex);
- }
- fprintf(pcfile, "} ");
-
- fprintf(pcfile, "Predecessors = { ");
- for (link = block->predecessors; link; link = link->nextLink) {
- if (link->block)
- fprintf(pcfile, "B%" PRId32 " ", link->block->blockIndex);
- }
-
- if (block->labels) {
- fprintf(pcfile, "} Labels = { ");
- for (label = block->labels; label; label = label->nextLabel)
- fprintf(pcfile, "L%" PRId32 " ", label->index);
- }
-
- fprintf(pcfile, "}\n\n");
-
- cpu = copts.scheduling;
- if (cpu == 10) {
- mi = &machine7450;
- } else if (copts.altivec_model != 0 || cpu == 7) {
- mi = &machine7400;
- } else if (cpu == 2) {
- mi = &machine603;
- } else if (cpu == 5) {
- mi = &machine603e;
- } else if (cpu == 3) {
- mi = &machine604;
- } else if (cpu == 6) {
- mi = &machine604;
- } else if (cpu == 4) {
- mi = &machine750;
- } else if (cpu == 1) {
- mi = &machine601;
- } else if (cpu == 9) {
- mi = &machine821;
- } else {
- mi = &machine603;
- }
-
- for (offset = block->codeOffset, instr = block->firstPCode; instr; instr = instr->nextPCode, offset += 4) {
- latency = mi->latency(instr);
- formatoperands(instr, buf, 1);
- chr = (PCODE_FLAG_SET_F(instr) & fRecordBit) ? '.' : ' ';
- if (coloring)
- opcode = 0;
- else
- opcode = assemblepcode(instr, offset, &dummyArg);
-
- fprintf(
- pcfile,
- " %.8" PRIX32 " %.8" PRIX32 " %4" PRId32 " %-7s%c %s\n",
- offset, CTool_EndianConvertWord32(opcode), latency,
- opcodeinfo[instr->op].name, chr, buf
- );
-
- if (instr->alias)
- dumpalias(instr->alias, 0, 1, 0);
- }
-
- if (vecSize) {
- fprintf(pcfile, "............................................................\n");
- formatdataflowset("use", liveinfo[block->blockIndex].use, vecSize, format);
- formatdataflowset("def", liveinfo[block->blockIndex].def, vecSize, format);
- formatdataflowset("in ", liveinfo[block->blockIndex].in, vecSize, format);
- formatdataflowset("out", liveinfo[block->blockIndex].out, vecSize, format);
- }
-
- fflush(pcfile);
-
- if (pclist_bad_operand)
- CError_FATAL(252);
-}
-
-static void pclistonoff(int flag) {
- if (flag)
- fprintf(pcfile, "On\n");
- else
- fprintf(pcfile, "Off\n");
-}
-
-void pcinitlisting() {
- // unknown args, etc
-}
-
-void pccleanuplisting(void) {
-#ifdef CW_ENABLE_PCODE_DEBUG
- // this code is not based on the original as we don't have it
- if (pcfile) {
- fclose(pcfile);
- pcfile = NULL;
- }
-#endif
-}
-
-void pclistblocks(char *name1, char *name2) {
-#ifdef CW_ENABLE_PCODE_DEBUG
- // this code is not based on the original as we don't have it
- PCodeBlock *block;
- if (copts.debuglisting) {
- if (!pcfile)
- pcfile = fopen("pcdump.txt", "a");
-
- fprintf(pcfile, "\n%s\n%s\n", name1, name2);
- for (block = pcbasicblocks; block; block = block->nextBlock)
- pclistblock(block, NULL, 0);
- }
-#endif
-}
-
-void pclistdataflow() {
- // unknown args
-}
-
-void pclistinterferences(char *class_format, int regcount) {
-}
-
-void pclistspill() {
- // unknown args
-}
-
-void pclistcopypropitem() {
- // unknown args
-}
-
-void pclistcoalesce() {
- // unknown args
-}
-
-void pclistusedefs() {
- // unknown args
-}
-
-void pclistpropinfo() {
- // unknown args
-}
-
-static void listloop() {
- // unknown args
-}
-
-static void listloops() {
- // unknown args
-}
-
-void pclistloops() {
- // unknown args
-}
-
-static void listswitchtables() {
- // unknown args
-}
-
-void pclistswitchtables() {
- // unknown args
-}
-
-void pclistdominators() {
- // unknown args
-}
-
-void pclistbackedge() {
- // unknown args
-}
-
-static char *GetInterferenceFlags(IGNode *node) {
- char *buf;
- Boolean first;
-
- first = 1;
- buf = oalloc(512);
- buf[0] = 0;
-
- if (node->flags & fSpilled) {
- strcat(buf, "fSpilled");
- first = 0;
- }
-
- if (node->flags & fPushed) {
- if (!first)
- strcat(buf, "|");
- strcat(buf, "fPushed");
- first = 0;
- }
-
- if (node->flags & fCoalesced) {
- if (!first)
- strcat(buf, "|");
- strcat(buf, "fCoalesced");
- first = 0;
- }
-
- if (node->flags & fCoalescedInto) {
- if (!first)
- strcat(buf, "|");
- strcat(buf, "fCoalescedInto");
- first = 0;
- }
-
- if (node->flags & fPairHigh) {
- if (!first)
- strcat(buf, "|");
- strcat(buf, "fPairHigh");
- first = 0;
- }
-
- if (node->flags & fPairLow) {
- if (!first)
- strcat(buf, "|");
- strcat(buf, "fPairLow");
- first = 0;
- }
-
- if (!*buf)
- strcat(buf, "no_flags");
-
- return buf;
-}
-
-void pclistinterferencegraphnode() {
- // unknown args
-}
-
-void pclistinterferencegraph() {
- // unknown args
-}
-
-void pclistblock_scheduler() {
- // unknown args
-}
-
-void pclistblocks_start_scheduler(char *str1, char *str2) {
-}
-
-void pclistblocks_end_scheduler(void) {
- if (pclist_bad_operand)
- CError_FATAL(1318);
-}
-
-static void printheapsize() {
- // unknown args
-}
-
-void pctotalheap() {
- // unknown args
-}
-
-void pctotalmemory() {
- // unknown args
-}
-
-void pcmessage(char *probably_a_string, ...) {
-}
-
-int formatalias(Alias *alias, char *buf, int bufSize) {
- char *name;
- char *typestr;
- int len;
- int len2;
-
- if (bufSize < 16)
- return sprintf(buf, "...");
-
- switch (alias->type) {
- case AliasType0:
- case AliasType1:
- name = CMangler_GetLinkName(alias->object)->name;
- if (!strlen(name) || name[0] < 0)
- CError_FATAL(1458);
-
- if (strlen(name) + 16 > bufSize)
- return sprintf(buf, "...");
-
- switch (alias->object->datatype) {
- case DNONLAZYPTR:
- typestr = "{NL}";
- break;
- case DDATA:
- typestr = "{RW}";
- break;
- case DLOCAL:
- typestr = "{SP}";
- break;
- default:
- typestr = "";
- }
-
- len = sprintf(buf, "%0.*s%s", bufSize - 20, name, typestr, alias->size);
- buf += len;
- if (alias->type == AliasType0)
- return len;
-
- if (alias->offset == 0)
- len2 = sprintf(buf, ":%d", alias->size);
- else if (alias->offset > 0)
- len2 = sprintf(buf, "+%d:%d", alias->offset, alias->size);
- else
- len2 = sprintf(buf, "-%d:%d", -alias->offset, alias->size);
-
- return len + len2;
-
- case AliasType2:
- len = 0;
-
- len2 = sprintf(buf, "{");
- buf += len2;
- len += len2;
-
- len2 = sprintf(buf, "*");
- buf += len2;
- len += len2;
-
- len2 = sprintf(buf, "}");
- buf += len2;
- len += len2;
- return len;
-
- default:
- CError_FATAL(1543);
- return 0;
- }
-}
-
-int dumpalias(Alias *alias, int len, Boolean flag1, Boolean flag2) {
- char *name;
- char *typestr;
- AliasMember *member;
- Boolean notFirst;
-
- if (!flag2 && alias == worst_case) {
- fprintf(pcfile, " ALIAS = {worst_case}");
- if (flag1)
- fprintf(pcfile, "\n");
- return 0;
- }
-
- if (flag1) {
- if (alias == worst_case)
- fprintf(pcfile, "ALIAS worst_case = ");
- else
- fprintf(pcfile, " ALIAS = ");
- }
-
- switch (alias->type) {
- case AliasType0:
- case AliasType1:
- name = CMangler_GetLinkName(alias->object)->name;
- if (!strlen(name) || name[0] < 0)
- CError_FATAL(1581);
-
- switch (alias->object->datatype) {
- case DNONLAZYPTR:
- typestr = "{NL}";
- break;
- case DDATA:
- typestr = "{RW}";
- break;
- case DLOCAL:
- typestr = "{SP}";
- break;
- default:
- typestr = "";
- }
-
- len += fprintf(pcfile, "%0.80s%s", name, typestr);
-
- if (alias->type == AliasType0) {
- if (flag1)
- fprintf(pcfile, "\n");
- return len;
- }
-
- if (alias->offset == 0)
- len += fprintf(pcfile, ":%d", alias->size);
- else if (alias->offset > 0)
- len += fprintf(pcfile, "+%d:%d", alias->offset, alias->size);
- else
- len += fprintf(pcfile, "-%d:%d", -alias->offset, alias->size);
-
- if (flag1)
- fprintf(pcfile, "\n");
-
- return len;
-
- case AliasType2:
- len += fprintf(pcfile, "{");
- notFirst = 0;
- for (member = alias->parents; member; member = member->nextParent) {
- if (member->child->type == AliasType0) {
- if (notFirst)
- len += fprintf(pcfile, ",");
- if (len > 60) {
- fprintf(pcfile, "\n ");
- len = 0;
- }
- len = dumpalias(member->child, len, 0, 0);
- notFirst = 1;
- }
- }
- for (member = alias->parents; member; member = member->nextParent) {
- if (member->child->type != AliasType0) {
- if (notFirst)
- len += fprintf(pcfile, ",");
- if (len > 60) {
- fprintf(pcfile, "\n ");
- len = 0;
- }
- len = dumpalias(member->child, len, 0, 0);
- notFirst = 1;
- }
- }
-
- len += fprintf(pcfile, "}");
- if (flag1)
- fprintf(pcfile, "\n");
- return len;
-
- default:
- CError_FATAL(1661);
- return 0;
- }
-}
-
-void pcformatset() {
- // unknown args
-}
-
-int GetLineEndOffset(char *str, int lineNum, int len) {
- int offset;
- char *work;
-
- offset = GetLineOffset(str, lineNum, len);
- if (offset < 0)
- return offset;
-
- work = str + offset;
- while (*work) {
- if (*work == '\n')
- return work - str - 1;
- work++;
- }
- return -1;
-}
-
-int GetLineOffset(char *str, int lineNum, int len) {
- char *work = str;
- char *end;
-
- if (lineNum < 0)
- return -1;
-
- end = str + len;
- while (work < end) {
- if (*work == '\n' && --lineNum <= 0)
- return work - str;
- work++;
- }
-
- return 0;
-}
-
-void DumpSourceCode() {
- // unknown args
-}
-
-int DumpIR_SrcBreak() {
- // unknown args
- return 0;
-}
-
diff --git a/compiler_and_linker/unsorted/PCodeUtilities.c b/compiler_and_linker/unsorted/PCodeUtilities.c
deleted file mode 100644
index b1f8ffb..0000000
--- a/compiler_and_linker/unsorted/PCodeUtilities.c
+++ /dev/null
@@ -1,345 +0,0 @@
-#include "compiler/PCodeUtilities.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/Exceptions.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/Registers.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-
-void pcsetrecordbit(PCode *pc) {
- int reg;
- PCodeArg *arg;
- short argCount;
- int argIdx;
-
- pc->flags &= ~(fIsMove | fCommutative | fIsCSE);
- if ((pc->flags & fOpTypeMask) == fOpTypeFPR) {
- reg = 1;
- } else if ((pc->flags & fOpTypeMask) == fOpTypeVR) {
- reg = 6;
- } else {
- reg = 0;
- }
-
- if (pc->op == PC_ANDI || pc->op == PC_ANDIS) {
- pc->flags |= fRecordBit;
- } else if (pc->op == PC_ADDI || pc->op == PC_ADDIC) {
- pc->flags |= fSetsCarry;
- pc->flags |= fRecordBit;
- change_num_operands(pc, 5);
- pc->op = PC_ADDICR;
-
- CError_ASSERT(76, pc->args[3].kind == PCOp_PLACEHOLDEROPERAND);
- pc->args[3].kind = PCOp_REGISTER;
- pc->args[3].arg = RegClass_SPR;
- pc->args[3].data.reg.reg = 0;
- pc->args[3].data.reg.effect = EffectWrite;
- CError_ASSERT(80, pc->args[4].kind == PCOp_PLACEHOLDEROPERAND);
- pc->args[4].kind = PCOp_REGISTER;
- pc->args[4].arg = RegClass_CRFIELD;
- pc->args[4].data.reg.reg = reg;
- pc->args[4].data.reg.effect = EffectWrite;
- } else {
- arg = pc->args;
- argIdx = argCount = pc->argCount;
- while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
- if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_CRFIELD && arg->data.reg.reg == reg) {
- arg->data.reg.effect |= EffectWrite;
- pc->flags |= fRecordBit;
- return;
- }
- arg++;
- argIdx--;
- }
-
- if (argIdx <= 0) {
- arg = &pc->args[argCount];
- pc->argCount++;
- }
-
- CError_ASSERT(105, arg->kind == PCOp_PLACEHOLDEROPERAND);
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = reg;
- arg->data.reg.effect = EffectWrite;
- if (pc->op != PC_ADDICR)
- pc->flags |= fRecordBit;
- }
-}
-
-void pcsetsideeffects(PCode *pc) {
- pc->flags &= ~(fIsMove | fCommutative | fIsCSE);
- pc->flags |= fSideEffects;
-}
-
-void pcsetlinkbit(PCode *pc) {
- PCodeArg *arg;
- int argIdx;
-
- switch (pc->op) {
- case PC_B:
- pc->op = PC_BL;
- break;
- case PC_BCTR:
- pc->op = PC_BCTRL;
- break;
- case PC_BLR:
- pc->op = PC_BLRL;
- break;
- }
-
- arg = pc->args;
- argIdx = pc->argCount;
- while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
- if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_SPR && arg->data.reg.reg == 1) {
- arg->data.reg.effect |= EffectWrite;
- pc->flags |= fLink;
- return;
- }
- arg++;
- argIdx--;
- }
-
- CError_ASSERT(169, arg->kind == PCOp_PLACEHOLDEROPERAND);
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 1;
- arg->data.reg.effect = EffectWrite;
-
- if (opcodeinfo[pc->op].flags & fIsCall) {
- pc->flags &= ~fIsBranch;
- pc->flags |= fIsCall;
- }
- pc->flags |= fLink;
-}
-
-void branch_label(PCodeLabel *label) {
- if (pclastblock->pcodeCount) {
- pcbranch(pclastblock, label);
- makepcblock();
- }
- pclabel(pclastblock, label);
-}
-
-void branch_conditional(short a, short compareop, short c, PCodeLabel *label) {
- PCodeBlock *tmpblock;
- PCodeLabel *tmplabel;
- int r28;
-
- tmpblock = pclastblock;
- tmplabel = makepclabel();
-
- switch (compareop) {
- case ENOTEQU:
- c = !c;
- case EEQU:
- r28 = 2;
- break;
- case EGREATEREQU:
- c = !c;
- case ELESS:
- r28 = 0;
- break;
- case ELESSEQU:
- c = !c;
- case EGREATER:
- r28 = 1;
- break;
- }
-
- emitpcode(c ? PC_BT : PC_BF, a, r28, label);
- pcbranch(pclastblock, label);
- pcbranch(pclastblock, tmplabel);
- makepcblock();
- pclabel(pclastblock, tmplabel);
-}
-
-void branch_always(PCodeLabel *label) {
- emitpcode(PC_B, label);
- pcbranch(pclastblock, label);
- makepcblock();
-}
-
-void branch_decrement_always(Opcode opcode, PCodeLabel *label) {
- PCodeLabel *tmplabel = makepclabel();
- emitpcode(opcode, label);
- pcbranch(pclastblock, label);
- pcbranch(pclastblock, tmplabel);
- makepcblock();
- pclabel(pclastblock, tmplabel);
-}
-
-void branch_indirect(Object *obj) {
- emitpcode(PC_BCTR, obj, 0);
- makepcblock();
-}
-
-int branch_count_volatiles(void) {
- int count = 0;
- int i;
- RegClass rclass;
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- for (i = 0; i < n_scratch_registers[rclass]; i++) {
- count++;
- }
- }
-
- return count;
-}
-
-PCodeArg *branch_record_volatiles(PCodeArg *arglist, UInt32 *masks) {
- int i;
- RegClass rclass;
-
- for (rclass = RegClassMax - 1; rclass >= 0; rclass--) {
- for (i = 0; i < n_scratch_registers[rclass]; i++) {
- arglist->kind = PCOp_REGISTER;
- arglist->arg = rclass;
- arglist->data.reg.reg = scratch_registers[rclass][i];
- arglist->data.reg.effect = EffectWrite;
- if (masks[rclass] & (1 << scratch_registers[rclass][i]))
- arglist->data.reg.effect |= EffectRead;
- arglist++;
- }
- }
-
- return arglist;
-}
-
-void branch_subroutine(Object *obj, short add_nop, UInt32 *masks) {
- int count;
- PCode *pc;
- PCodeArg *arg;
-
- count = branch_count_volatiles();
- if (copts.exceptions && current_statement)
- count += countexceptionactionregisters(current_statement->dobjstack);
-
- pc = makepcode(PC_BL, count, obj, 0);
- arg = branch_record_volatiles(pc->args + 1, masks);
- if (copts.exceptions && current_statement)
- noteexceptionactionregisters(current_statement->dobjstack, arg);
- appendpcode(pclastblock, pc);
-
- if (add_nop)
- emitpcode(PC_NOP);
-
- branch_label(makepclabel());
- if (copts.exceptions && current_statement)
- recordexceptionactions(pc, current_statement->dobjstack);
-}
-
-void branch_subroutine_ctr(UInt32 *masks) {
- int count;
- PCode *pc;
- PCodeArg *arg;
-
- count = branch_count_volatiles();
- if (copts.exceptions && current_statement)
- count += countexceptionactionregisters(current_statement->dobjstack);
-
- pc = makepcode(PC_BCTRL, count);
- arg = branch_record_volatiles(pc->args + 1, masks);
- if (copts.exceptions && current_statement)
- noteexceptionactionregisters(current_statement->dobjstack, arg);
- appendpcode(pclastblock, pc);
-
- branch_label(makepclabel());
- if (copts.exceptions && current_statement)
- recordexceptionactions(pc, current_statement->dobjstack);
-}
-
-void add_immediate(short dest_reg, short base_reg, Object *obj, SInt16 offset) {
- short tmp_reg = base_reg;
-
- if (obj && offset && obj->datatype != DLOCAL) {
- tmp_reg = used_virtual_registers[RegClass_GPR]++;
- add_immediate_lo(tmp_reg, base_reg, obj, 0, 1);
- obj = NULL;
- }
-
- if (!obj && !offset)
- emitpcode(PC_MR, dest_reg, tmp_reg);
- else
- emitpcode(PC_ADDI, dest_reg, tmp_reg, obj, offset);
-}
-
-PCode *add_immediate_lo(short dest_reg, short base_reg, Object *obj, SInt16 offset, char add_to_block) {
- PCode *pc;
-
- CError_ASSERT(577, obj);
-
- pc = makepcode(PC_ADDI, dest_reg, base_reg, obj, offset);
- if (add_to_block)
- appendpcode(pclastblock, pc);
- return pc;
-}
-
-PCode *op_absolute_ha(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
- PCode *pc;
- int tmp_reg;
-
- if (obj->datatype == DLOCAL) {
- pc = makepcode(PC_ADDIS, dest_reg, base_reg, obj, offset);
- } else if (copts.codegen_pic) {
- tmp_reg = base_reg;
- CError_ASSERT(601, tmp_reg);
- pc = makepcode(PC_ADDIS, dest_reg, tmp_reg, obj, offset);
- } else {
- CError_ASSERT(606, base_reg == 0);
- pc = makepcode(PC_LIS, dest_reg, obj, offset);
- }
-
- if (add_to_block)
- appendpcode(pclastblock, pc);
- return pc;
-}
-
-void load_store_register(Opcode opcode, short dest_reg, short base_reg, Object *obj, SInt32 offset) {
- short addi_tmp;
- short offset_reg1;
- short offset_reg2;
-
- offset_reg1 = base_reg;
- if (obj && offset && obj->datatype != DLOCAL) {
- offset_reg1 = used_virtual_registers[RegClass_GPR]++;
- add_immediate_lo(offset_reg1, base_reg, obj, 0, 1);
- obj = NULL;
- }
-
- if (offset != (short)offset) {
- if (opcode == PC_LWZ && dest_reg == 12)
- offset_reg2 = 12;
- else if (opcode == PC_LWZ && dest_reg == 11)
- offset_reg2 = 11;
- else
- offset_reg2 = used_virtual_registers[RegClass_GPR]++;
-
- emitpcode(PC_ADDIS, offset_reg2, offset_reg1, 0, (short) ((offset >> 16) + ((offset & 0x8000) >> 15)));
- offset = (short) offset;
- offset_reg1 = offset_reg2;
- }
-
- if (opcode == PC_STVX || opcode == PC_LVX) {
- offset_reg2 = 0;
- if (obj) {
- addi_tmp = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADDI, addi_tmp, offset_reg1, obj, offset);
- offset_reg1 = addi_tmp;
- } else if (offset) {
- offset_reg2 = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LI, offset_reg2, offset);
- }
- if (!offset_reg2)
- emitpcode(opcode, dest_reg, 0, offset_reg1);
- else
- emitpcode(opcode, dest_reg, offset_reg1, offset_reg2);
- } else {
- emitpcode(opcode, dest_reg, offset_reg1, obj, offset);
- }
-}
diff --git a/compiler_and_linker/unsorted/PPCError.c b/compiler_and_linker/unsorted/PPCError.c
deleted file mode 100644
index 2d4c469..0000000
--- a/compiler_and_linker/unsorted/PPCError.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "compiler/PPCError.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/InlineAsm.h"
-#include "cos.h"
-
-static void PPCError_GetErrorString(char *str, short code) {
- short scode;
-
- scode = (short) code;
- CError_ASSERT(40, scode >= 100 && scode < PPCErrorStrMAX);
-
- COS_GetString(str, 10001, scode - 99);
-}
-
-static void PPCError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) {
- char format[256];
- PPCError_GetErrorString(format, code);
- CError_ErrorMessageVA(code + 10001, format, list, flag1, flag2);
-}
-
-void PPCError_Error(int code, ...) {
- va_list list;
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- va_start(list, code);
- PPCError_VAErrorMessage(code, list, 0, 0);
- va_end(list);
-
- if (in_assembler)
- AssemblerError();
-}
-
-void PPCError_Warning(int code, ...) {
- va_list list;
-
- if (!trychain) {
- va_start(list, code);
- PPCError_VAErrorMessage(code, list, 0, 1);
- va_end(list);
- }
-}
-
-void PPCError_Message(char *format, ...) {
- va_list list;
-
- if (!trychain) {
- va_start(list, format);
- CError_ErrorMessageVA(10213, format, list, 0, 1);
- va_end(list);
- }
-}
-
-void PPCError_ErrorTerm(short code, ...) {
- va_list list;
-
- if (trychain)
- longjmp(trychain->jmpbuf, 1);
-
- va_start(list, code);
- PPCError_VAErrorMessage(code, list, 1, 0);
- va_end(list);
-
- if (in_assembler)
- AssemblerError();
-
- longjmp(errorreturn, 1);
-}
diff --git a/compiler_and_linker/unsorted/Peephole.c b/compiler_and_linker/unsorted/Peephole.c
deleted file mode 100644
index 151e448..0000000
--- a/compiler_and_linker/unsorted/Peephole.c
+++ /dev/null
@@ -1,2753 +0,0 @@
-#include "compiler/Peephole.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/InstrSelection.h"
-#include "compiler/PCode.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-#include "compiler/Scheduler.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Alias.h"
-#include "compiler/CParser.h"
-
-typedef int (*PeepholeFunc)(PCode *instr, UInt32 *masks);
-
-typedef struct Pattern {
- struct Pattern *next;
- PeepholeFunc func;
-} Pattern;
-
-typedef struct LiveRegs {
- UInt32 x0;
- UInt32 x4;
- UInt32 x8;
- UInt32 xC;
-} LiveRegs;
-
-static LiveRegs *liveregs[RegClassMax];
-static Pattern *peepholepatterns[OPCODE_MAX];
-static PCode **defininginstruction;
-
-static void computeregisterusedefs(void) {
- PCodeBlock *block;
- PCode *instr;
- PCodeArg *op;
- int i;
- RegClass rclass;
- LiveRegs *lr;
- UInt32 array1[RegClassMax];
- UInt32 array2[RegClassMax];
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- array1[rclass] = 0;
- array2[rclass] = 0;
- }
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (
- op->kind == PCOp_REGISTER &&
- (op->data.reg.effect & EffectRead) &&
- !((1 << op->data.reg.reg) & array2[op->arg])
- )
- array1[op->arg] |= 1 << op->data.reg.reg;
- }
-
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (
- op->kind == PCOp_REGISTER &&
- (op->data.reg.effect & EffectWrite) &&
- !((1 << op->data.reg.reg) & array1[op->arg])
- )
- array2[op->arg] |= 1 << op->data.reg.reg;
- }
- }
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- lr = liveregs[rclass] + block->blockIndex;
- lr->x0 = array1[rclass];
- lr->x4 = array2[rclass];
- if (rclass == RegClass_GPR) {
- lr->x8 = 1 << 1;
- lr->xC = 1 << 1;
- } else {
- lr->x8 = 0;
- lr->xC = 0;
- }
- }
- }
-}
-
-static void computeliveness(LiveRegs *lrarray, UInt32 x) {
- PCodeBlock *block;
- LiveRegs *lr;
- PCLink *link;
- UInt32 newC;
- UInt32 new8;
- int i;
- int flag;
-
- flag = 1;
- while (flag) {
- flag = 0;
- i = pcblockcount;
- while (i) {
- if ((block = depthfirstordering[--i])) {
- lr = lrarray + block->blockIndex;
- newC = x;
- for (link = block->successors; link; link = link->nextLink)
- newC |= lrarray[link->block->blockIndex].x8;
- lr->xC = newC;
-
- new8 = lr->x0 | (lr->xC & ~lr->x4);
- if (new8 != lr->x8) {
- lr->x8 = new8;
- flag = 1;
- }
- }
- }
- }
-}
-
-static void computeliveregisters(Object *func) {
- Type *returntype;
- RegClass rclass;
-
- returntype = TYPE_FUNC(func->type)->functype;
-
- for (rclass = 0; rclass < RegClassMax; rclass++)
- liveregs[rclass] = lalloc(sizeof(LiveRegs) * pcblockcount);
-
- computedepthfirstordering();
- computeregisterusedefs();
-
- if (TYPE_FITS_IN_REGISTER(returntype)) {
- liveregs[RegClass_GPR][epilogue->blockIndex].x0 |= 1 << 3;
- if (TYPE_IS_8BYTES(returntype))
- liveregs[RegClass_GPR][epilogue->blockIndex].x0 |= 1 << 4;
- } else if (IS_TYPE_FLOAT(returntype)) {
- liveregs[RegClass_FPR][epilogue->blockIndex].x0 |= 1 << 1;
- } else if (IS_TYPE_VECTOR(returntype)) {
- liveregs[RegClass_VR][epilogue->blockIndex].x0 |= 1 << 2;
- }
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- if (rclass == RegClass_GPR)
- computeliveness(liveregs[rclass], 2);
- else
- computeliveness(liveregs[rclass], 0);
- }
-}
-
-static void computeinstructionpredecessors(PCodeBlock *block) {
- PCode *nop;
- RegClass rclass;
- SInt32 i;
- SInt32 defID;
- SInt32 totalOps;
- PCode *instr;
- PCodeArg *op;
- PCode *array[RegClassMax][32];
-
- nop = makepcode(PC_NOP);
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- for (i = 0; i < 32; i++) {
- array[rclass][i] = nop;
- }
- }
-
- totalOps = 0;
- for (instr = block->firstPCode; instr; instr = instr->nextPCode)
- totalOps += instr->argCount;
-
- if (totalOps) {
- defininginstruction = oalloc(sizeof(PCode *) * totalOps);
- for (i = 0; i < totalOps; i++)
- defininginstruction[i] = nop;
-
- defID = 0;
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- instr->defID = defID;
-
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectRead))
- defininginstruction[defID + i] = array[op->arg][op->data.reg.reg];
- }
-
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite))
- array[op->arg][op->data.reg.reg] = instr;
- }
-
- defID += instr->argCount;
- }
- }
-}
-
-static int dead(PCode *instr, UInt32 *masks) {
- int i;
- PCodeArg *op;
-
- if (instr->block->flags & (fIsProlog | fIsEpilogue))
- return 0;
- if (instr->flags & (fIsBranch | fIsWrite | fIsCall | fIsVolatile | fSideEffects))
- return 0;
- if (!instr->block->predecessors)
- return 1;
-
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (
- op->kind == PCOp_REGISTER &&
- (op->data.reg.effect & EffectWrite) &&
- ((1 << op->data.reg.reg) & masks[op->arg])
- )
- return 0;
- }
-
- return 1;
-}
-
-static int definedbetween(PCode *start, PCode *end, PCodeArg *checkOp) {
- PCode *instr;
- PCodeArg *op;
- int i;
-
- for (instr = start->prevPCode; instr != end; instr = instr->prevPCode) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (PC_OP_IS_WRITE_REGISTER(op, checkOp->arg, checkOp->data.reg.reg))
- return 1;
- }
- }
-
- return 0;
-}
-
-static int usedbetween(PCode *start, PCode *end, PCodeArg *checkOp) {
- PCode *instr;
- PCodeArg *op;
- int i;
-
- for (instr = start->prevPCode; instr != end; instr = instr->prevPCode) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (PC_OP_IS_READ_REGISTER(op, checkOp->arg, checkOp->data.reg.reg))
- return 1;
- }
- }
-
- return 0;
-}
-
-static int isSPRlive(PCode *instr, int reg) {
- PCode *scan;
- PCodeArg *op;
- int i;
-
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (PC_OP_IS_READ_REGISTER(op, RegClass_SPR, reg))
- return 1;
-
- if (PC_OP_IS_WRITE_REGISTER(op, RegClass_SPR, reg))
- return 0;
- }
- }
-
- return 0;
-}
-
-static SInt32 extractedbits(PCode *instr) {
- SInt32 a = instr->args[2].data.imm.value;
- SInt32 b = instr->args[3].data.imm.value;
- SInt32 c = instr->args[4].data.imm.value;
- SInt32 val;
-
- if (b <= c)
- val = ((b > 31) ? 0 : (0xFFFFFFFFu >> b)) & ~(((c + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c + 1)));
- else
- val = ((b > 31) ? 0 : (0xFFFFFFFFu >> b)) | ~(((c + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c + 1)));
-
- return ((UInt32) val >> a) | (val << (32 - a));
-}
-
-static int canmergemasks(SInt32 b1, SInt32 c1, SInt32 a, SInt32 b2, SInt32 c2, short *first, short *last) {
- SInt32 val1;
- SInt32 val2;
-
- if (b1 <= c1)
- val1 = ((b1 > 31) ? 0 : (0xFFFFFFFFu >> b1)) & ~(((c1 + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c1 + 1)));
- else
- val1 = ((b1 > 31) ? 0 : (0xFFFFFFFFu >> b1)) | ~(((c1 + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c1 + 1)));
-
- if (b2 <= c2)
- val2 = ((b2 > 31) ? 0 : (0xFFFFFFFFu >> b2)) & ~(((c2 + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c2 + 1)));
- else
- val2 = ((b2 > 31) ? 0 : (0xFFFFFFFFu >> b2)) | ~(((c2 + 1) > 31) ? 0 : (0xFFFFFFFFu >> (c2 + 1)));
-
- return ismaskconstant(val2 & ((val1 << a) | ((UInt32) val1 >> (32 - a))), first, last);
-}
-
-static int canuseupdatetest(PCodeBlock *block, PCode *instr, int count1, int count2, int count3, int count4, int count5) {
- int i;
- PCLink *link;
-
- while (instr) {
- if (++count1 > 17)
- return 1;
-
- switch (instr->op) {
- case PC_DIVW:
- case PC_DIVWU:
- case PC_MULHW:
- case PC_MULHWU:
- case PC_MULLI:
- case PC_MULLW:
- return count3 == 0;
- case PC_MTXER:
- case PC_MTCTR:
- case PC_MTLR:
- case PC_MTCRF:
- case PC_MTMSR:
- case PC_MTSPR:
- case PC_MFMSR:
- case PC_MFSPR:
- case PC_MFXER:
- case PC_MFCTR:
- case PC_MFLR:
- case PC_MFCR:
- case PC_ECIWX:
- case PC_ECOWX:
- case PC_DCBI:
- case PC_ICBI:
- case PC_MCRFS:
- case PC_MCRXR:
- case PC_MFTB:
- case PC_MFSR:
- case PC_MTSR:
- case PC_MFSRIN:
- case PC_MTSRIN:
- case PC_MTFSB0:
- case PC_MTFSB1:
- case PC_MTFSFI:
- case PC_SC:
- case PC_TLBIA:
- case PC_TLBIE:
- case PC_TLBLD:
- case PC_TLBLI:
- case PC_TLBSYNC:
- case PC_TW:
- case PC_TRAP:
- case PC_TWI:
- case PC_MFROM:
- case PC_DSA:
- case PC_ESA:
- return 1;
- case PC_CRAND:
- case PC_CRANDC:
- case PC_CREQV:
- case PC_CRNAND:
- case PC_CRNOR:
- case PC_CROR:
- case PC_CRORC:
- case PC_CRXOR:
- case PC_MCRF:
- if (++count5 > 1)
- return 1;
- }
-
- if (instr->flags & (fIsRead | fIsWrite)) {
- if (++count4 > 1)
- return 1;
- } else if (instr->flags & fIsBranch) {
- if (++count2 > 2)
- return 1;
-
- for (i = 0; i < instr->argCount; i++) {
- if (PC_OP_IS_ANY_REGISTER(&instr->args[i], RegClass_CRFIELD)) {
- ++count3;
- break;
- }
- }
- }
-
- instr = instr->nextPCode;
- }
-
- if (block && block->successors) {
- for (link = block->successors; link; link = link->nextLink) {
- if (link->block && !canuseupdatetest(link->block, link->block->firstPCode, count1, count2, count3, count4, count5))
- return 0;
- }
- }
-
- return 1;
-}
-
-static int canuseupdate(PCode *instr) {
- return canuseupdatetest(instr->block, instr->nextPCode, 0, 0, 0, 0, 0);
-}
-
-static int MR_Rx_Rx(PCode *instr, UInt32 *masks) {
- if (
- instr->args[0].data.reg.reg == instr->args[1].data.reg.reg &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit)
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int FMR_Fx_Fx(PCode *instr, UInt32 *masks) {
- if (
- instr->args[0].data.reg.reg == instr->args[1].data.reg.reg &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit)
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int VMR_Vx_Vx(PCode *instr, UInt32 *masks) {
- if (
- instr->args[0].data.reg.reg == instr->args[1].data.reg.reg &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit)
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int MR_MR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_MR &&
- instr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- !definedbetween(instr, defInstr, &instr->args[0]) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit)
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int FMR_FMR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_FMR &&
- instr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &instr->args[0])
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int VMR_VMR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_VMR &&
- instr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &instr->args[0])
- )
- {
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int VMR_VMRP(PCode *instr, UInt32 *masks) {
- PCode *prev = instr->prevPCode;
- PCode *next = instr->nextPCode;
- int prevFlag = 0;
- int prevPermute = 0;
- int nextFlag = 0;
- int nextPermute = 0;
-
- if (prev) {
- prevFlag = (prev->flags & fOpTypeMask) == fOpTypeVR;
- prevPermute = uses_vpermute_unit(prev);
- }
- if (next) {
- nextFlag = (next->flags & fOpTypeMask) == fOpTypeVR;
- nextPermute = uses_vpermute_unit(next);
- }
-
- if (prev) {
- if (next) {
- if (prevFlag && !prevPermute) {
- if (nextFlag) {
- if (!nextPermute) {
- change_opcode(instr, PC_VMRP);
- return 1;
- }
- } else {
- change_opcode(instr, PC_VMRP);
- return 1;
- }
- }
- } else {
- if (prevFlag && !prevPermute) {
- change_opcode(instr, PC_VMRP);
- return 1;
- }
- }
- } else {
- if (next && nextFlag && !nextPermute) {
- change_opcode(instr, PC_VMRP);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int MR_CMPI(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
- PCodeArg op;
-
- if (
- instr->args[0].data.reg.reg == 0 &&
- instr->args[2].data.imm.value == 0 &&
- (PCODE_FLAG_SET_F(defInstr) & (fSideEffects | fCanSetRecordBit | fOpTypeGPR)) == (fCanSetRecordBit | fOpTypeGPR) &&
- !usedbetween(instr, defInstr, &instr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0])
- )
- {
- if (defInstr->op == PC_ADDI) {
- op.kind = PCOp_REGISTER;
- op.arg = RegClass_SPR;
- op.data.reg.reg = 0;
- op.data.reg.effect = EffectRead | EffectWrite;
- if (usedbetween(instr, defInstr, &op))
- return 0;
- }
-
- pcsetrecordbit(defInstr);
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int EXTSB_RLWINM(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_EXTSB &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- (extractedbits(instr) & 0xFFFFFF00) == 0
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int EXTSH_RLWINM(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_EXTSH &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- (extractedbits(instr) & 0xFFFF0000) == 0
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int LBZ_RLWINM(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- (defInstr->op == PC_LBZ || defInstr->op == PC_LBZX) &&
- instr->args[2].data.imm.value == 0 &&
- instr->args[3].data.imm.value <= 24 &&
- instr->args[4].data.imm.value == 31 &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0]) &&
- !usedbetween(instr, defInstr, &instr->args[0])
- )
- {
- defInstr->args[0].data.reg.reg = instr->args[0].data.reg.reg;
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int LHZ_RLWINM(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- (defInstr->op == PC_LHZ || defInstr->op == PC_LHZX) &&
- instr->args[2].data.imm.value == 0 &&
- instr->args[3].data.imm.value <= 16 &&
- instr->args[4].data.imm.value == 31 &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0]) &&
- !usedbetween(instr, defInstr, &instr->args[0])
- )
- {
- defInstr->args[0].data.reg.reg = instr->args[0].data.reg.reg;
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int LHA_EXTSH(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_LHA &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0]) &&
- !usedbetween(instr, defInstr, &instr->args[0])
- )
- {
- defInstr->args[0].data.reg.reg = instr->args[0].data.reg.reg;
- deletepcode(instr);
- return 1;
- }
-
- if (
- defInstr->op == PC_EXTSB &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit)
- )
- {
- if (defInstr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg) {
- if (
- !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg)) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- {
- change_opcode(instr, PC_EXTSB);
- deletepcode(defInstr);
- return 1;
- }
- } else {
- if (!definedbetween(instr, defInstr, &defInstr->args[1])) {
- change_opcode(instr, PC_EXTSB);
- instr->args[1] = defInstr->args[1];
- } else {
- change_opcode(instr, PC_MR);
- }
- return 1;
- }
- }
-
- return 0;
-}
-
-static int ADDI_L_S(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
- SInt32 addleft;
- SInt32 addright;
-
- if (defInstr->op == PC_ADDI && instr->args[2].kind == PCOp_IMMEDIATE) {
- if (!PC_OP_IS_REGISTER(&instr->args[0], RegClass_GPR, instr->args[1].data.reg.reg)) {
- if (
- instr->args[2].data.imm.value == 0 &&
- defInstr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- (!(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg)) || canuseupdate(instr))
- )
- {
- if (!(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) {
- instr->args[2] = defInstr->args[2];
- } else {
- instr->op++;
- instr->args[1].data.reg.effect |= EffectWrite;
- instr->args[2] = defInstr->args[2];
- }
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- addleft = 0x1FFFF;
- addright = instr->args[2].data.imm.value;
- if (defInstr->args[2].kind == PCOp_IMMEDIATE) {
- addleft = defInstr->args[2].data.imm.value;
- } else if (defInstr->args[2].kind == PCOp_MEMORY) {
- if (defInstr->args[2].data.mem.obj->datatype == DLOCAL)
- addleft = defInstr->args[2].data.mem.offset + defInstr->args[2].data.mem.obj->u.var.uid;
- else if (addright == 0)
- addleft = 0;
- else
- return 0;
- }
-
- if (!FITS_IN_SHORT(addleft + addright))
- return 0;
-
- if (
- !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg)) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !definedbetween(instr, defInstr, &defInstr->args[1])
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- if (defInstr->args[2].kind == PCOp_MEMORY) {
- instr->args[2] = defInstr->args[2];
- instr->args[2].data.mem.offset += addright;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- instr->alias = make_alias(
- instr->args[2].data.mem.obj,
- instr->args[2].data.mem.offset,
- nbytes_loaded_or_stored_by(instr)
- );
- }
- } else {
- instr->args[2].data.imm.value = addleft + addright;
- }
-
- deletepcode(defInstr);
- return 1;
- }
-
- if (
- instr->args[1].data.reg.reg != defInstr->args[1].data.reg.reg &&
- !definedbetween(instr, defInstr, &defInstr->args[1])
- )
- {
- if (defInstr->args[2].kind == PCOp_MEMORY && defInstr->args[2].data.mem.obj->datatype != DLOCAL)
- return 0;
-
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- if (defInstr->args[2].kind == PCOp_MEMORY) {
- instr->args[2] = defInstr->args[2];
- instr->args[2].data.mem.offset += addright;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- instr->alias = make_alias(
- instr->args[2].data.mem.obj,
- instr->args[2].data.mem.offset,
- nbytes_loaded_or_stored_by(instr)
- );
- }
- } else {
- instr->args[2].data.imm.value = addleft + addright;
- }
-
- return 1;
- }
- }
- } else {
- if (
- defInstr->op == PC_MR &&
- PC_OP_IS_ANY_REGISTER(&defInstr->args[1], RegClass_GPR) &&
- defInstr->args[1].data.reg.reg != 0 &&
- !definedbetween(instr, defInstr, &defInstr->args[1])
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- }
- }
-
- return 0;
-}
-
-static int ADDI_LU_SU(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- instr->args[2].kind == PCOp_IMMEDIATE &&
- defInstr->args[2].kind == PCOp_IMMEDIATE &&
- defInstr->op == PC_ADDI &&
- defInstr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- !(instr->args[0].arg == instr->args[1].arg && instr->args[0].data.reg.reg == instr->args[1].data.reg.reg) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- FITS_IN_SHORT(instr->args[2].data.imm.value + defInstr->args[2].data.imm.value)
- )
- {
- if ((instr->args[2].data.imm.value + defInstr->args[2].data.imm.value) == 0) {
- instr->op--;
- instr->args[1].data.reg.effect &= ~EffectWrite;
- instr->args[2].data.imm.value = 0;
- } else {
- instr->args[2].data.imm.value += defInstr->args[2].data.imm.value;
- }
-
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int L_S_ADDI(PCode *instr, UInt32 *masks) {
- PCode *scan;
- PCodeArg *op;
- int i;
- short reg;
-
- if (instr->args[2].kind != PCOp_IMMEDIATE)
- return 0;
-
- reg = instr->args[1].data.reg.reg;
- if (!canuseupdate(instr))
- return 0;
-
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (PC_OP_IS_READ_REGISTER(op, RegClass_GPR, reg))
- return 0;
-
- if (PC_OP_IS_WRITE_REGISTER(op, RegClass_GPR, reg)) {
- if (scan->op != PC_ADDI)
- return 0;
- if (scan->args[2].kind != PCOp_IMMEDIATE)
- return 0;
-
- if (
- instr->args[2].data.imm.value == scan->args[2].data.imm.value &&
- scan->args[0].data.reg.reg == scan->args[1].data.reg.reg &&
- !(instr->args[0].arg == instr->args[1].arg && instr->args[0].data.reg.reg == instr->args[1].data.reg.reg)
- )
- {
- if (!(masks[RegClass_GPR] & (1 << scan->args[0].data.reg.reg))) {
- instr->args[2] = scan->args[2];
- } else {
- instr->op++;
- instr->args[1].data.reg.effect |= EffectWrite;
- instr->args[2] = scan->args[2];
- }
-
- change_opcode(scan, PC_NOP);
- change_num_operands(scan, 0);
- deletepcode(scan);
- return 1;
- }
-
- return 0;
- }
- }
- }
-
- return 0;
-}
-
-static int LI_CMP_BC(PCode *instr, UInt32 *masks) {
- PCode *defInstr;
- PCode *defInstr2;
- PCLink *link;
- PCLink **ptr;
-
- if (instr->args[1].data.imm.value == 2) {
- defInstr = defininginstruction[instr->defID];
- if ((defInstr->op == PC_CMPLI || defInstr->op == PC_CMPI) && defInstr->args[0].data.reg.reg == 0) {
- defInstr2 = defininginstruction[defInstr->defID + 1];
- if (
- defInstr2->op == PC_LI &&
- defInstr2->args[1].kind == PCOp_IMMEDIATE &&
- (instr->op == PC_BT) == (defInstr2->args[1].data.imm.value == defInstr->args[2].data.imm.value)
- )
- {
- change_opcode(instr, PC_B);
- instr->args[0] = instr->args[2];
- change_num_operands(instr, 1);
-
- defininginstruction[instr->defID] = defininginstruction[instr->defID + 1];
-
- for (ptr = &instr->block->successors; (link = *ptr); ptr = &link->nextLink) {
- if (link->block == instr->block->nextBlock) {
- *ptr = link->nextLink;
- break;
- }
- }
-
- for (ptr = &instr->block->nextBlock->predecessors; (link = *ptr); ptr = &link->nextLink) {
- if (link->block == instr->block) {
- *ptr = link->nextLink;
- break;
- }
- }
- }
- }
- }
-
- return 0;
-}
-
-static int RLWINM_CMPLI_BC(PCode *instr, UInt32 *masks) {
- PCode *defInstr;
- PCode *defInstr2;
-
- if (instr->args[1].data.imm.value == 2) {
- defInstr = defininginstruction[instr->defID];
- if (defInstr->op == PC_CMPLI && defInstr->args[0].data.reg.reg == 0 && defInstr->args[2].data.imm.value == 0) {
- defInstr2 = defininginstruction[defInstr->defID + 1];
- if (
- (PCODE_FLAG_SET_F(defInstr2) & (fSideEffects | fCanSetRecordBit | fOpTypeGPR)) == (fCanSetRecordBit | fOpTypeGPR) &&
- !usedbetween(defInstr, defInstr2, &defInstr->args[0]) &&
- !definedbetween(defInstr, defInstr2, &defInstr->args[0])
- )
- {
- pcsetrecordbit(defInstr2);
- defininginstruction[instr->defID] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static int LBZ_EXTSB_CMPI_BC(PCode *instr, UInt32 *masks) {
- PCode *defInstr;
- PCode *defInstr2;
-
- if (instr->args[1].data.imm.value == 2) {
- defInstr = defininginstruction[instr->defID];
- if (
- (
- (defInstr->op == PC_CMPI || defInstr->op == PC_CMPLI) &&
- defInstr->args[2].data.imm.value >= 0 &&
- defInstr->args[2].data.imm.value <= 127
- )
- ||
- (
- (defInstr->op == PC_EXTSB || defInstr->op == PC_EXTSH) &&
- (PCODE_FLAG_SET_F(defInstr) & fRecordBit)
- )
- )
- {
- defInstr2 = defininginstruction[defInstr->defID + 1];
- if (
- defInstr2->op == PC_EXTSB &&
- defininginstruction[defInstr2->defID + 1]->op == PC_LBZ &&
- !(masks[RegClass_GPR] & (1 << defInstr2->args[0].data.reg.reg)) &&
- !usedbetween(instr, defInstr, &defInstr2->args[0]) &&
- !usedbetween(defInstr, defInstr2, &defInstr2->args[0]) &&
- !definedbetween(defInstr, defInstr2, &defInstr2->args[1])
- )
- {
- defInstr->args[1].data.reg.reg = defInstr2->args[1].data.reg.reg;
- defininginstruction[defInstr->defID + 1] = defininginstruction[defInstr2->defID + 1];
- deletepcode(defInstr2);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static int FRSP_STFS(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID];
-
- if (
- defInstr->op == PC_FRSP &&
- !(masks[RegClass_FPR] & (1 << defInstr->args[0].data.reg.reg)) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- {
- instr->args[0].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int NOT_AND(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 2];
-
- if (
- defInstr->op == PC_NOT &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- {
- instr->args[2].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 2] = defininginstruction[defInstr->defID + 1];
- change_opcode(instr, PC_ANDC);
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int LI_MR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_LI &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1] = defInstr->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int VSPLTIS_VMR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
- short opcode = defInstr->op;
-
- if (
- (opcode == PC_VSPLTISB || opcode == PC_VSPLTISH || opcode == PC_VSPLTISW) &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_VR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- {
- change_opcode(instr, opcode);
- instr->args[1] = defInstr->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int L_MR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- (defInstr->flags & fIsRead) &&
- !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg)) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !usedbetween(instr, defInstr, &instr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0])
- )
- {
- defInstr->args[0].data.reg.reg = instr->args[0].data.reg.reg;
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int L_FMR(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- (defInstr->flags & fIsRead) &&
- !(masks[RegClass_FPR] & (1 << defInstr->args[0].data.reg.reg)) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- !usedbetween(instr, defInstr, &instr->args[0]) &&
- !definedbetween(instr, defInstr, &instr->args[0])
- )
- {
- defInstr->args[0].data.reg.reg = instr->args[0].data.reg.reg;
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int L_S(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID];
- SInt32 isIndexed;
- SInt32 isFloat;
- SInt32 isVector;
- PCode *scan;
- SInt32 loadSize;
- SInt32 defInstrOffset;
- SInt32 scanOffset;
- SInt32 storeSize;
-
- if (PCODE_FLAG_SET_F(instr) & (fIsVolatile | fSideEffects | fUpdatesPtr))
- return 0;
- if (PCODE_FLAG_SET_F(defInstr) & (fIsVolatile | fSideEffects | fUpdatesPtr))
- return 0;
-
- if (
- (defInstr->flags & fIsRead) &&
- PC_OP_IS_REGISTER(&defInstr->args[1], RegClass_GPR, instr->args[1].data.reg.reg) &&
- defInstr->args[2].kind == instr->args[2].kind &&
- !definedbetween(instr, defInstr, &instr->args[1])
- )
- {
- if (instr->args[2].kind == PCOp_IMMEDIATE) {
- if (instr->args[2].data.imm.value != defInstr->args[2].data.imm.value)
- return 0;
- } else if (instr->args[2].kind == PCOp_MEMORY) {
- if (instr->args[2].data.mem.offset != defInstr->args[2].data.mem.offset ||
- instr->args[2].data.mem.obj != defInstr->args[2].data.mem.obj)
- return 0;
- } else if (instr->args[2].kind == PCOp_REGISTER && instr->args[2].arg == RegClass_GPR) {
- if (instr->args[2].data.reg.reg != defInstr->args[2].data.reg.reg ||
- definedbetween(instr, defInstr, &instr->args[2]))
- return 0;
- } else {
- return 0;
- }
-
- isIndexed = 0;
- isFloat = 0;
- isVector = 0;
- switch (defInstr->op) {
- case PC_LBZX:
- isIndexed = 1;
- case PC_LBZ:
- loadSize = 1;
- break;
- case PC_LHZX:
- case PC_LHAX:
- isIndexed = 1;
- case PC_LHZ:
- case PC_LHA:
- loadSize = 2;
- break;
- case PC_LWZX:
- isIndexed = 1;
- case PC_LWZ:
- loadSize = 4;
- break;
- case PC_LFSX:
- isIndexed = 1;
- case PC_LFS:
- isFloat = 1;
- loadSize = 4;
- break;
- case PC_LFDX:
- isIndexed = 1;
- case PC_LFD:
- isFloat = 1;
- loadSize = 8;
- break;
- case PC_LVX:
- case PC_LVXL:
- isIndexed = 1;
- isVector = 1;
- loadSize = 16;
- break;
- default:
- return 0;
- }
-
- switch (instr->op) {
- case PC_STBX:
- if (!isIndexed) return 0;
- case PC_STB:
- if (isFloat) return 0;
- if (loadSize != 1) return 0;
- break;
- case PC_STHX:
- if (!isIndexed) return 0;
- case PC_STH:
- if (isFloat) return 0;
- if (loadSize != 2) return 0;
- break;
- case PC_STWX:
- if (!isIndexed) return 0;
- case PC_STW:
- if (isFloat) return 0;
- if (loadSize != 4) return 0;
- break;
- case PC_STFSX:
- if (!isIndexed) return 0;
- case PC_STFS:
- if (!isFloat) return 0;
- if (loadSize != 4) return 0;
- break;
- case PC_STFDX:
- if (!isIndexed) return 0;
- case PC_STFD:
- if (!isFloat) return 0;
- if (loadSize != 8) return 0;
- break;
- case PC_STVX:
- case PC_STVXL:
- if (!isIndexed) return 0;
- if (!isVector) return 0;
- if (loadSize != 16) return 0;
- break;
- default:
- return 0;
- }
-
- for (scan = instr->prevPCode; scan && scan != defInstr; scan = scan->prevPCode) {
- if (scan->flags & fIsWrite) {
- if (scan->args[1].data.reg.reg != instr->args[1].data.reg.reg)
- return 0;
- if (scan->args[2].kind != defInstr->args[2].kind)
- return 0;
-
- if (scan->args[2].kind == PCOp_MEMORY) {
- if (instr->args[2].data.mem.obj == scan->args[2].data.mem.obj) {
- if (instr->args[2].data.mem.offset == defInstr->args[2].data.mem.offset)
- return 0;
- defInstrOffset = defInstr->args[2].data.mem.offset;
- scanOffset = scan->args[2].data.mem.offset;
- }
- } else if (scan->args[2].kind == PCOp_IMMEDIATE) {
- if (instr->args[1].data.reg.reg != scan->args[1].data.reg.reg)
- return 0;
- if (instr->args[2].data.imm.value == scan->args[2].data.imm.value)
- return 0;
- defInstrOffset = defInstr->args[2].data.imm.value;
- scanOffset = scan->args[2].data.imm.value;
- } else {
- return 0;
- }
-
- switch (scan->op) {
- case PC_STB:
- case PC_STBX:
- storeSize = 1;
- break;
- case PC_STH:
- case PC_STHX:
- storeSize = 2;
- break;
- case PC_STW:
- case PC_STWX:
- case PC_STFS:
- case PC_STFSX:
- storeSize = 4;
- break;
- case PC_STFD:
- case PC_STFDX:
- storeSize = 8;
- break;
- case PC_STVX:
- case PC_STVXL:
- storeSize = 16;
- break;
- default:
- return 0;
- }
-
- if (defInstrOffset > scanOffset) {
- if ((scanOffset + storeSize) > defInstrOffset)
- return 0;
- } else {
- if ((defInstrOffset + loadSize) > scanOffset)
- return 0;
- }
- }
- }
-
- deletepcode(instr);
- return 1;
- }
-
- return 0;
-}
-
-static int RLWINM_RLWINM(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
- short start;
- short end;
-
- if (
- defInstr->op == PC_RLWINM &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !(
- defInstr->args[0].data.reg.reg == defInstr->args[1].data.reg.reg &&
- (
- (defInstr->args[0].data.reg.reg != instr->args[0].data.reg.reg && (masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) ||
- usedbetween(instr, defInstr, &defInstr->args[0])
- )
- ) &&
- canmergemasks(
- defInstr->args[3].data.imm.value,
- defInstr->args[4].data.imm.value,
- instr->args[2].data.imm.value,
- instr->args[3].data.imm.value,
- instr->args[4].data.imm.value,
- &start, &end)
- )
- {
- if (instr->op == PC_RLWIMI) {
- if (instr->args[0].data.reg.reg == defInstr->args[0].data.reg.reg)
- return 0;
- if (start != instr->args[3].data.imm.value || end != instr->args[4].data.imm.value)
- return 0;
- }
-
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- instr->args[2].data.imm.value = (instr->args[2].data.imm.value + defInstr->args[2].data.imm.value) & 31;
- instr->args[3].data.imm.value = start;
- instr->args[4].data.imm.value = end;
-
- if (
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- deletepcode(defInstr);
-
- return 1;
- }
-
- if (
- defInstr->op == PC_MR &&
- instr->op == PC_RLWINM &&
- !definedbetween(instr, defInstr, &defInstr->args[1])
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- if (
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !usedbetween(instr, defInstr, &defInstr->args[0])
- )
- deletepcode(defInstr);
-
- return 1;
- }
-
- return 0;
-}
-
-static int MULLI_MULLI(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_MULLI &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- FITS_IN_SHORT(instr->args[2].data.imm.value * defInstr->args[2].data.imm.value)
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- instr->args[2].data.imm.value *= defInstr->args[2].data.imm.value;
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int ADDI_ADDI(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_ADDI &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- instr->args[2].kind == PCOp_IMMEDIATE &&
- defInstr->args[2].kind == PCOp_IMMEDIATE &&
- FITS_IN_SHORT(instr->args[2].data.imm.value + defInstr->args[2].data.imm.value)
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- instr->args[2].data.imm.value += defInstr->args[2].data.imm.value;
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int SRAWI_SRAWI(PCode *instr, UInt32 *masks) {
- PCode *defInstr = defininginstruction[instr->defID + 1];
-
- if (
- defInstr->op == PC_SRAWI &&
- (defInstr->args[0].data.reg.reg == instr->args[0].data.reg.reg || !(masks[RegClass_GPR] & (1 << defInstr->args[0].data.reg.reg))) &&
- !(PCODE_FLAG_SET_F(defInstr) & fRecordBit) &&
- !definedbetween(instr, defInstr, &defInstr->args[1]) &&
- !usedbetween(instr, defInstr, &defInstr->args[0]) &&
- instr->args[2].kind == PCOp_IMMEDIATE &&
- defInstr->args[2].kind == PCOp_IMMEDIATE &&
- (instr->args[2].data.imm.value + defInstr->args[2].data.imm.value) < 32 &&
- (instr->args[2].data.imm.value + defInstr->args[2].data.imm.value) > 0
- )
- {
- instr->args[1].data.reg.reg = defInstr->args[1].data.reg.reg;
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr->defID + 1];
-
- instr->args[2].data.imm.value += defInstr->args[2].data.imm.value;
- deletepcode(defInstr);
- return 1;
- }
-
- return 0;
-}
-
-static int MR_ADDI(PCode *instr, UInt32 *masks) {
- PCode *prev = instr->prevPCode;
- PCode *next = instr->nextPCode;
- int prevFlag = 0;
- int nextFlag = 0;
-
- if (copts.processor == CPU_PPC603e) {
- if (prev)
- prevFlag = (prev->flags & fOpTypeMask) == fOpTypeGPR;
- if (next)
- nextFlag = (next->flags & fOpTypeMask) == fOpTypeGPR;
-
- if (
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- instr->argCount >= 2 &&
- instr->args[1].data.reg.reg != 0 &&
- (prevFlag || nextFlag)
- )
- {
- change_opcode(instr, PC_ADDI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = 0;
- instr->args[2].data.imm.obj = NULL;
- change_num_operands(instr, 3);
- }
- }
-
- return 0;
-}
-
-static int rotatedefinedusedtest(UInt32 *masks, PCode *instr, PCode *a, PCode *b, PCode *subfic) {
- PCode *scan;
- PCodeArg *op;
- int i;
- int reg1;
- int reg2;
-
- if (
- (masks[RegClass_GPR] & (1 << subfic->args[0].data.reg.reg)) &&
- subfic->args[0].data.reg.reg != instr->args[0].data.reg.reg &&
- subfic->args[0].data.reg.reg != a->args[2].data.reg.reg
- )
- return 1;
-
- for (scan = instr->block->firstPCode; scan != instr->block->lastPCode; scan = scan->nextPCode) {
- if (scan == a) break;
- if (scan == b) break;
- if (scan == subfic) break;
- }
-
- reg1 = a->args[1].data.reg.reg;
- reg2 = subfic->args[1].data.reg.reg;
- while (scan != instr) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (
- (
- (op->data.reg.reg == reg1 || op->data.reg.reg == reg2) &&
- (op->data.reg.effect & EffectWrite)
- )
- ||
- (
- op->data.reg.reg == subfic->args[0].data.reg.reg && (op->data.reg.effect & EffectRead)
- )
- ) &&
- scan != a &&
- scan != b &&
- scan != subfic
- )
- return 1;
- }
-
- scan = scan->nextPCode;
- }
-
- return 0;
-}
-
-static int SRW_SUBFIC_RLW_OR(PCode *instr, UInt32 *masks) {
- PCode *subfic;
- PCode *defInstr1 = defininginstruction[instr->defID + 1];
- PCode *defInstr2 = defininginstruction[instr->defID + 2];
-
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- return 0;
-
- if (
- (masks[RegClass_GPR] & (1 << instr->args[1].data.reg.reg)) &&
- instr->args[1].data.reg.reg != instr->args[0].data.reg.reg
- )
- return 0;
-
- if (
- (masks[RegClass_GPR] & (1 << instr->args[2].data.reg.reg)) &&
- instr->args[1].data.reg.reg != instr->args[0].data.reg.reg
- )
- return 0;
-
- if (defInstr1->op != PC_SRW && defInstr1->op != PC_SLW)
- return 0;
- if (defInstr2->op != PC_SRW && defInstr2->op != PC_SLW)
- return 0;
-
- if (usedbetween(instr, defInstr1, &defInstr1->args[0]))
- return 0;
- if (usedbetween(instr, defInstr2, &defInstr2->args[0]))
- return 0;
-
- if (
- defInstr1->op == PC_SRW && defInstr2->op == PC_SLW &&
- defInstr1->args[1].data.reg.reg == defInstr2->args[1].data.reg.reg
- )
- {
- subfic = defininginstruction[defInstr1->defID + 2];
- if (
- subfic->op == PC_SUBFIC &&
- subfic->args[1].data.reg.reg == defInstr2->args[2].data.reg.reg &&
- subfic->args[2].data.imm.value == 32
- )
- {
- if (rotatedefinedusedtest(masks, instr, defInstr2, defInstr1, subfic))
- return 0;
-
- change_opcode(instr, PC_RLWNM);
-
- instr->args[1] = defInstr1->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr1->defID + 1];
-
- instr->args[2] = defInstr2->args[2];
- defininginstruction[instr->defID + 2] = defininginstruction[defInstr2->defID + 2];
-
- instr->args[3].kind = PCOp_IMMEDIATE;
- instr->args[3].data.imm.value = 0;
- instr->args[3].data.imm.obj = NULL;
-
- instr->args[4].kind = PCOp_IMMEDIATE;
- instr->args[4].data.imm.value = 31;
- instr->args[4].data.imm.obj = NULL;
-
- deletepcode(defInstr1);
- deletepcode(defInstr2);
- deletepcode(subfic);
- return 1;
- }
-
- subfic = defininginstruction[defInstr2->defID + 2];
- if (
- subfic->op == PC_SUBFIC &&
- subfic->args[1].data.reg.reg == defInstr1->args[2].data.reg.reg &&
- subfic->args[2].data.imm.value == 32
- )
- {
- if (rotatedefinedusedtest(masks, instr, defInstr2, defInstr1, subfic))
- return 0;
-
- change_opcode(instr, PC_RLWNM);
-
- instr->args[1] = defInstr1->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr1->defID + 1];
-
- instr->args[2] = defInstr2->args[2];
- defininginstruction[instr->defID + 2] = defininginstruction[defInstr2->defID + 2];
-
- instr->args[3].kind = PCOp_IMMEDIATE;
- instr->args[3].data.imm.value = 0;
- instr->args[3].data.imm.obj = NULL;
-
- instr->args[4].kind = PCOp_IMMEDIATE;
- instr->args[4].data.imm.value = 31;
- instr->args[4].data.imm.obj = NULL;
-
- deletepcode(defInstr1);
- deletepcode(defInstr2);
- return 1;
- }
- } else if (
- defInstr1->op == PC_SLW && defInstr2->op == PC_SRW &&
- defInstr1->args[1].data.reg.reg == defInstr2->args[1].data.reg.reg
- )
- {
- subfic = defininginstruction[defInstr1->defID + 2];
- if (
- subfic->op == PC_SUBFIC &&
- subfic->args[1].data.reg.reg == defInstr2->args[2].data.reg.reg &&
- subfic->args[2].data.imm.value == 32
- )
- {
- if (rotatedefinedusedtest(masks, instr, defInstr1, defInstr2, subfic))
- return 0;
-
- change_opcode(instr, PC_RLWNM);
-
- instr->args[1] = defInstr1->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr1->defID + 1];
-
- instr->args[2] = defInstr1->args[2];
- defininginstruction[instr->defID + 2] = defininginstruction[defInstr1->defID + 2];
-
- instr->args[3].kind = PCOp_IMMEDIATE;
- instr->args[3].data.imm.value = 0;
- instr->args[3].data.imm.obj = NULL;
-
- instr->args[4].kind = PCOp_IMMEDIATE;
- instr->args[4].data.imm.value = 31;
- instr->args[4].data.imm.obj = NULL;
-
- deletepcode(defInstr1);
- deletepcode(defInstr2);
- return 1;
- }
-
- subfic = defininginstruction[defInstr2->defID + 2];
- if (
- subfic->op == PC_SUBFIC &&
- subfic->args[1].data.reg.reg == defInstr1->args[2].data.reg.reg &&
- subfic->args[2].data.imm.value == 32
- )
- {
- if (rotatedefinedusedtest(masks, instr, defInstr1, defInstr2, subfic))
- return 0;
-
- change_opcode(instr, PC_RLWNM);
-
- instr->args[1] = defInstr1->args[1];
- defininginstruction[instr->defID + 1] = defininginstruction[defInstr1->defID + 1];
-
- instr->args[2] = defInstr1->args[2];
- defininginstruction[instr->defID + 2] = defininginstruction[defInstr1->defID + 2];
-
- instr->args[3].kind = PCOp_IMMEDIATE;
- instr->args[3].data.imm.value = 0;
- instr->args[3].data.imm.obj = NULL;
-
- instr->args[4].kind = PCOp_IMMEDIATE;
- instr->args[4].data.imm.value = 31;
- instr->args[4].data.imm.obj = NULL;
-
- deletepcode(defInstr1);
- deletepcode(defInstr2);
- deletepcode(subfic);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int RLWINM_RLWIMI_STW(PCode *instr, UInt32 *masks) {
- PCode *newInstr;
- Boolean isZeroOffset;
- int flags;
- PCode *scan;
- int i;
- PCode *array[4];
-
- flags = 0;
- isZeroOffset = 0;
- if (instr->op == PC_STW && instr->args[2].kind == PCOp_IMMEDIATE && instr->args[2].data.imm.value == 0)
- isZeroOffset = 1;
-
- scan = instr;
- for (i = 0; i < 4; i++) {
- if (scan->op == PC_RLWINM)
- array[i] = defininginstruction[scan->defID + 1];
- else
- array[i] = defininginstruction[scan->defID];
-
- scan = array[i];
- if (array[0]->args[1].data.reg.reg != scan->args[1].data.reg.reg)
- return 0;
-
- if (i < 3) {
- if (scan->op != PC_RLWIMI)
- return 0;
- } else {
- if (scan->op != PC_RLWINM)
- return 0;
- }
-
- if (scan->args[2].data.imm.value == 8) {
- if (scan->args[3].data.imm.value == 24 && scan->args[4].data.imm.value == 31) {
- if (flags & 1)
- return 0;
- flags |= 1;
- } else if (scan->args[3].data.imm.value == 8 && scan->args[4].data.imm.value == 15) {
- if (flags & 4)
- return 0;
- flags |= 4;
- } else {
- return 0;
- }
- } else if (scan->args[2].data.imm.value == 24) {
- if (scan->args[3].data.imm.value == 0 && scan->args[4].data.imm.value == 7) {
- if (flags & 8)
- return 0;
- flags |= 8;
- } else if (scan->args[3].data.imm.value == 16 && scan->args[4].data.imm.value == 23) {
- if (flags & 2)
- return 0;
- flags |= 2;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
-
- if (definedbetween(instr, array[3], &array[0]->args[1]))
- return 0;
-
- if (instr->op == PC_STWX) {
- change_opcode(instr, PC_STWBRX);
- instr->args[0] = array[0]->args[1];
- defininginstruction[instr->defID] = defininginstruction[array[3]->defID + 1];
- return 1;
- }
-
- if (instr->op == PC_STW) {
- if (!isZeroOffset) {
- if (masks[RegClass_GPR] & (1 << array[0]->args[0].data.reg.reg))
- return 0;
-
- if (usedbetween(array[2], array[3], &array[0]->args[0]))
- return 0;
- if (usedbetween(array[1], array[2], &array[0]->args[0]))
- return 0;
- if (usedbetween(array[0], array[1], &array[0]->args[0]))
- return 0;
- if (usedbetween(instr, array[0], &array[0]->args[0]))
- return 0;
- }
-
- defininginstruction[instr->defID] = defininginstruction[array[3]->defID + 1];
-
- if (!isZeroOffset) {
- newInstr = makepcode(PC_STWBRX, array[3]->args[1].data.reg.reg, 0, instr->args[0].data.reg.reg);
- newInstr->alias = instr->alias;
- change_opcode(instr, PC_ADDI);
- insertpcodeafter(instr, newInstr);
-
- masks[RegClass_GPR] |= 1 << newInstr->args[0].data.reg.reg;
- masks[RegClass_GPR] |= 1 << newInstr->args[2].data.reg.reg;
- instr->args[0].data.reg.effect &= ~EffectRead;
- instr->args[0].data.reg.effect |= EffectWrite;
- defininginstruction[instr->defID] = instr;
-
- deletepcode(array[0]);
- deletepcode(array[1]);
- deletepcode(array[2]);
- deletepcode(array[3]);
- } else {
- change_opcode(instr, PC_STWBRX);
- instr->args[0] = array[0]->args[1];
- instr->args[2] = instr->args[1];
- defininginstruction[instr->defID + 2] = defininginstruction[instr->defID + 1];
-
- instr->args[1].kind = PCOp_REGISTER;
- instr->args[1].arg = RegClass_GPR;
- instr->args[1].data.reg.reg = 0;
- instr->args[1].data.reg.effect = 0;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-static int RLWINM_RLWIMI_STH(PCode *instr, UInt32 *masks) {
- PCode *newInstr;
- Boolean isZeroOffset;
- int flags;
- PCode *scan;
- int i;
- PCode *array[2];
-
- flags = 0;
- isZeroOffset = 0;
- if (instr->op == PC_STH && instr->args[2].kind == PCOp_IMMEDIATE && instr->args[2].data.imm.value == 0)
- isZeroOffset = 1;
-
- scan = instr;
- for (i = 0; i < 2; i++) {
- if (scan->op == PC_RLWINM)
- array[i] = defininginstruction[scan->defID + 1];
- else
- array[i] = defininginstruction[scan->defID];
-
- scan = array[i];
- if (array[0]->args[1].data.reg.reg != scan->args[1].data.reg.reg)
- return 0;
-
- if (i < 1) {
- if (scan->op != PC_RLWIMI)
- return 0;
- } else {
- if (scan->op != PC_RLWINM)
- return 0;
- }
-
- if (scan->args[2].data.imm.value == 8) {
- if (scan->args[3].data.imm.value == 16 && scan->args[4].data.imm.value == 23) {
- if (flags & 2)
- return 0;
- flags |= 2;
- } else {
- return 0;
- }
- } else if (scan->args[2].data.imm.value == 24) {
- if (scan->args[3].data.imm.value == 24 && scan->args[4].data.imm.value == 31) {
- if (flags & 1)
- return 0;
- flags |= 1;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
-
- if (definedbetween(instr, array[1], &array[0]->args[1]))
- return 0;
-
- if (instr->op == PC_STHX) {
- change_opcode(instr, PC_STHBRX);
- instr->args[0] = array[0]->args[1];
- defininginstruction[instr->defID] = defininginstruction[array[1]->defID + 1];
- return 1;
- }
-
- if (instr->op == PC_STH) {
- if (!isZeroOffset) {
- if (masks[RegClass_GPR] & (1 << array[0]->args[0].data.reg.reg))
- return 0;
-
- if (usedbetween(array[0], array[1], &array[0]->args[0]))
- return 0;
- if (usedbetween(instr, array[0], &array[0]->args[0]))
- return 0;
- }
-
- defininginstruction[instr->defID] = defininginstruction[array[1]->defID + 1];
-
- if (!isZeroOffset) {
- newInstr = makepcode(PC_STHBRX, array[1]->args[1].data.reg.reg, 0, instr->args[0].data.reg.reg);
- newInstr->alias = instr->alias;
- change_opcode(instr, PC_ADDI);
-
- instr->args[0].data.reg.effect &= ~EffectRead;
- instr->args[0].data.reg.effect |= EffectWrite;
- defininginstruction[instr->defID] = instr;
-
- insertpcodeafter(instr, newInstr);
-
- masks[RegClass_GPR] |= 1 << newInstr->args[0].data.reg.reg;
- masks[RegClass_GPR] |= 1 << newInstr->args[2].data.reg.reg;
-
- deletepcode(array[0]);
- deletepcode(array[1]);
- } else {
- change_opcode(instr, PC_STHBRX);
- instr->args[0] = array[0]->args[1];
- instr->args[2] = instr->args[1];
- defininginstruction[instr->defID + 2] = defininginstruction[instr->defID + 1];
-
- instr->args[1].kind = PCOp_REGISTER;
- instr->args[1].arg = RegClass_GPR;
- instr->args[1].data.reg.reg = 0;
- instr->args[1].data.reg.effect = 0;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-static void peepholeoptimizeblock(PCodeBlock *block) {
- RegClass rclass;
- PCode *instr;
- PCodeArg *op;
- int i;
- Pattern *pattern;
- UInt32 masks[RegClassMax];
-
- for (rclass = 0; rclass < RegClassMax; rclass++)
- masks[rclass] = liveregs[rclass][block->blockIndex].xC;
-
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- if (dead(instr, masks)) {
- deletepcode(instr);
- } else {
- pattern = peepholepatterns[instr->op];
-
- while (pattern) {
- if (pattern->func(instr, masks)) {
- if (!instr->block)
- break;
- pattern = peepholepatterns[instr->op];
- } else {
- pattern = pattern->next;
- }
- }
-
- if (instr->block) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite))
- masks[op->arg] &= ~(1 << op->data.reg.reg);
- }
-
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectRead))
- masks[op->arg] |= 1 << op->data.reg.reg;
- }
- }
- }
- }
-}
-
-static SInt32 computepossiblemask(PCode *instr, short reg) {
- SInt32 mask;
- SInt32 val;
- PCodeArg *op;
- int i;
-
- mask = 0xFFFFFFFF;
- while (instr) {
- for (op = instr->args, i = instr->argCount; i--; op++) {
- if (PC_OP_IS_WRITE_REGISTER(op, RegClass_GPR, reg)) {
- switch (instr->op) {
- case PC_LBZ:
- case PC_LBZU:
- case PC_LBZX:
- case PC_LBZUX:
- mask = 0xFF;
- break;
-
- case PC_LHZ:
- case PC_LHZU:
- case PC_LHZX:
- case PC_LHZUX:
- mask = 0xFFFF;
- break;
-
- case PC_LI:
- mask = instr->args[1].data.imm.value;
- break;
-
- case PC_SRAWI:
- mask = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg) >> instr->args[2].data.imm.value;
- break;
-
- case PC_RLWINM:
- val = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg);
- mask = (val << instr->args[2].data.imm.value) | ((UInt32) val >> (32 - instr->args[2].data.imm.value));
-
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value)
- val = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) & ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
- else
- val = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) | ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
-
- mask &= val;
- break;
-
- case PC_RLWIMI:
- val = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg);
- mask = (val << instr->args[2].data.imm.value) | ((UInt32) val >> (32 - instr->args[2].data.imm.value));
-
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value)
- val = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) & ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
- else
- val = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) | ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
-
- mask &= val;
- mask |= computepossiblemask(instr->prevPCode, instr->args[0].data.reg.reg);
- break;
-
- case PC_OR:
- mask = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg) |
- computepossiblemask(instr->prevPCode, instr->args[2].data.reg.reg);
- break;
-
- case PC_ORI:
- mask = instr->args[2].data.imm.value |
- computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg);
- break;
-
- case PC_AND:
- mask = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg) &
- computepossiblemask(instr->prevPCode, instr->args[2].data.reg.reg);
- break;
-
- case PC_ANDI:
- mask = instr->args[2].data.imm.value &
- computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg);
- break;
-
- case PC_MR:
- mask = computepossiblemask(instr->prevPCode, instr->args[1].data.reg.reg);
- break;
- }
-
- return mask;
- }
- }
- instr = instr->prevPCode;
- }
-
- return mask;
-}
-
-static UInt32 fillmaskholes(UInt32 mask) {
- UInt32 oneBit;
- UInt32 allBits;
- UInt32 result;
-
- oneBit = 1;
- allBits = 0xFFFFFFFF;
- result = 0;
-
- if ((mask & 1) && (mask & 0x80000000)) {
- result = 0xFFFFFFFF;
- while ((mask & oneBit) == 1) {
- oneBit <<= 1;
- }
-
- while ((mask & oneBit) == 0) {
- result &= ~oneBit;
- oneBit <<= 1;
- }
-
- return result;
- } else {
- while ((mask & oneBit) == 0 && (mask & allBits) != 0) {
- oneBit <<= 1;
- allBits <<= 1;
- }
- while ((mask & allBits) != 0) {
- result |= oneBit;
- oneBit <<= 1;
- allBits <<= 1;
- }
- return result;
- }
-}
-
-static int canuseinsert(PCode *instr1, PCode *instr2, short reg) {
- if (computepossiblemask(instr2, reg) & fillmaskholes(computepossiblemask(instr1, instr1->args[0].data.reg.reg)))
- return 0;
- return 1;
-}
-
-static PCode *find_def_backwords(PCode *instr, short reg) {
- int i;
-
- while (instr) {
- for (i = 0; i < instr->argCount; i++) {
- if (PC_OP_IS_WRITE_REGISTER(&instr->args[i], RegClass_GPR, reg))
- return instr;
- }
- instr = instr->prevPCode;
- }
-
- return NULL;
-}
-
-static void adjustforward(PCodeBlock *block) {
- PCode *instr;
- PCode *scan;
- PCode *tmp;
- PCodeArg *op;
- int i;
- short opcode;
- short reg0;
- short reg1;
- SInt32 valA;
- SInt32 valB;
-
- instr = block->firstPCode;
- while (instr) {
- if (instr->op == PC_RLWINM) {
- SInt32 val2;
- SInt32 val3;
- SInt32 val4;
- short start;
- short end;
-
- short flag1 = 0;
- short flag2 = 0;
- reg0 = instr->args[0].data.reg.reg;
- reg1 = instr->args[1].data.reg.reg;
- val2 = instr->args[2].data.imm.value;
- val3 = instr->args[3].data.imm.value;
- val4 = instr->args[4].data.imm.value;
-
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- opcode = scan->op;
- if (opcode == PC_RLWINM && scan->args[1].data.reg.reg == reg0) {
- if (
- scan->args[3].data.imm.value == val3 &&
- scan->args[4].data.imm.value == val4 &&
- scan->args[2].data.imm.value == 0
- )
- {
- if (PCODE_FLAG_SET_F(scan) & fRecordBit) {
- if (!flag1) {
- pcsetrecordbit(instr);
- change_opcode(scan, PC_MR);
- scan->flags &= ~fRecordBit;
- scan->flags |= fIsMove;
- change_num_operands(scan, 2);
- } else {
- change_opcode(scan, PC_MR);
- scan->args[2] = scan->args[5];
- change_num_operands(scan, 3);
- }
- } else {
- change_opcode(scan, PC_MR);
- change_num_operands(scan, 2);
- }
- }
- else if (
- reg0 != reg1 &&
- !flag2 &&
- canmergemasks(
- val3,
- val4,
- scan->args[2].data.imm.value,
- scan->args[3].data.imm.value,
- scan->args[4].data.imm.value,
- &start, &end)
- )
- {
- scan->args[1].data.reg.reg = reg1;
- scan->args[2].data.imm.value = (scan->args[2].data.imm.value + instr->args[2].data.imm.value) & 31;
- scan->args[3].data.imm.value = start;
- scan->args[4].data.imm.value = end;
- }
- }
- else if (
- opcode == PC_SRAWI &&
- scan->args[1].data.reg.reg == reg0 &&
- reg0 != reg1 &&
- instr->args[2].data.imm.value == 0 &&
- !(computepossiblemask(instr, reg0) & 0x80000000) &&
- !flag2 &&
- canmergemasks(val3, val4, 32 - scan->args[2].data.imm.value, scan->args[2].data.imm.value, 31, &start, &end) &&
- !isSPRlive(scan, 0)
- )
- {
- insertpcodeafter(scan, makepcode(
- PC_RLWINM, scan->args[0].data.reg.reg, reg1,
- 32 - scan->args[2].data.imm.value, start, end
- ));
- if (PCODE_FLAG_SET_F(scan) & fRecordBit)
- pcsetrecordbit(scan->nextPCode);
- deletepcode(scan);
- }
- else if (
- opcode == PC_OR &&
- !flag2 &&
- reg0 != reg1 &&
- !(PCODE_FLAG_SET_F(scan) & fRecordBit) &&
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- scan->args[0].data.reg.reg != instr->args[1].data.reg.reg
- )
- {
- if (scan->args[1].data.reg.reg == reg0 && canuseinsert(instr, scan, scan->args[2].data.reg.reg)) {
- op = &scan->args[2];
- tmp = find_def_backwords(scan->prevPCode, scan->args[2].data.reg.reg);
- if (tmp->op == PC_RLWINM && tmp->args[2].data.imm.value == 0) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value)
- valA = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) & ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
- else
- valA = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) | ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
-
- if (tmp->args[3].data.imm.value <= tmp->args[4].data.imm.value)
- valB = ((tmp->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> tmp->args[3].data.imm.value)) & ~(((tmp->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (tmp->args[4].data.imm.value + 1)));
- else
- valB = ((tmp->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> tmp->args[3].data.imm.value)) | ~(((tmp->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (tmp->args[4].data.imm.value + 1)));
-
- if (valA == ~valB)
- op = &tmp->args[1];
- }
-
- change_opcode(scan, PC_MR);
- scan->args[1] = *op;
- change_num_operands(scan, 2);
-
- tmp = copypcode(instr);
- change_opcode(tmp, PC_RLWIMI);
- tmp->args[0] = scan->args[0];
- tmp->args[0].data.reg.effect |= EffectRead;
-
- if (ismaskconstant(fillmaskholes(computepossiblemask(instr, instr->args[0].data.reg.reg)), &start, &end)) {
- tmp->args[3].data.imm.value = start;
- tmp->args[4].data.imm.value = end;
- }
-
- insertpcodeafter(scan, tmp);
- break;
- }
-
- if (
- scan->args[2].data.reg.reg == reg0 &&
- canuseinsert(instr, scan, scan->args[1].data.reg.reg)
- )
- {
- op = &scan->args[1];
- tmp = find_def_backwords(scan->prevPCode, scan->args[1].data.reg.reg);
- if (tmp->op == PC_RLWINM && tmp->args[2].data.imm.value == 0) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value)
- valA = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) & ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
- else
- valA = ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> instr->args[3].data.imm.value)) | ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (instr->args[4].data.imm.value + 1)));
-
- if (tmp->args[3].data.imm.value <= tmp->args[4].data.imm.value)
- valB = ((tmp->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> tmp->args[3].data.imm.value)) & ~(((tmp->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (tmp->args[4].data.imm.value + 1)));
- else
- valB = ((tmp->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFu >> tmp->args[3].data.imm.value)) | ~(((tmp->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFu >> (tmp->args[4].data.imm.value + 1)));
-
- if (valA == ~valB)
- op = &tmp->args[1];
- }
-
- change_opcode(scan, PC_MR);
- scan->args[1] = *op;
- change_num_operands(scan, 2);
-
- tmp = copypcode(instr);
- change_opcode(tmp, PC_RLWIMI);
- tmp->args[0] = scan->args[0];
- tmp->args[0].data.reg.effect |= EffectRead;
-
- if (ismaskconstant(fillmaskholes(computepossiblemask(instr, instr->args[0].data.reg.reg)), &start, &end)) {
- tmp->args[3].data.imm.value = start;
- tmp->args[4].data.imm.value = end;
- }
-
- insertpcodeafter(scan, tmp);
- break;
- }
- }
- else if (
- !flag2 &&
- reg0 != reg1 &&
- val4 == 31 &&
- instr->args[2].data.imm.value == 0 &&
- (
- ((opcode == PC_STB || opcode == PC_STBX) && val3 <= 24) ||
- ((opcode == PC_STH || opcode == PC_STHX) && val3 <= 16)
- ) &&
- scan->args[0].data.reg.reg == reg0
- )
- {
- scan->args[0].data.reg.reg = reg1;
- }
- else if (
- opcode == PC_EXTSH &&
- scan->args[1].data.reg.reg == reg0 &&
- val2 == 0 &&
- val3 > 16 &&
- val3 < val4
- )
- {
- change_opcode(scan, PC_MR);
- if ((PCODE_FLAG_SET_F(scan) & fRecordBit) && !flag1) {
- pcsetrecordbit(instr);
- scan->flags &= ~fRecordBit;
- scan->flags |= fIsMove;
- change_num_operands(scan, 2);
- }
- }
- else if (
- opcode == PC_EXTSB &&
- scan->args[1].data.reg.reg == reg0 &&
- val2 == 0 &&
- val3 > 24 &&
- val3 < val4
- )
- {
- change_opcode(scan, PC_MR);
- if ((PCODE_FLAG_SET_F(scan) & fRecordBit) && !flag1) {
- pcsetrecordbit(instr);
- scan->flags &= ~fRecordBit;
- scan->flags |= fIsMove;
- change_num_operands(scan, 2);
- }
- }
-
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (PC_OP_IS_WRITE_REGISTER(op, RegClass_GPR, reg0)) {
- scan = block->lastPCode;
- break;
- }
-
- if (PC_OP_IS_WRITE_REGISTER(op, RegClass_GPR, reg1))
- flag2 = 1;
-
- if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0))
- flag1 = 1;
- }
- }
-
- } else if (
- instr->op == PC_EXTSB &&
- (reg0 = instr->args[0].data.reg.reg) != (reg1 = instr->args[1].data.reg.reg)
- )
- {
- short flag = 0;
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- if (
- (scan->op >= PC_STB && scan->op <= PC_STBUX) &&
- scan->args[0].data.reg.reg == reg0
- )
- {
- scan->args[0].data.reg.reg = reg1;
- }
- else if (
- (scan->op == PC_EXTSH || scan->op == PC_EXTSB) &&
- scan->args[1].data.reg.reg == reg0
- )
- {
- change_opcode(scan, PC_MR);
- if ((PCODE_FLAG_SET_F(scan) & fRecordBit) && !flag) {
- pcsetrecordbit(instr);
- scan->flags &= ~fRecordBit;
- scan->flags |= fIsMove;
- change_num_operands(scan, 2);
- }
- }
-
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (
- PC_OP_IS_WRITE_ANY_REGISTER(op, RegClass_GPR) &&
- (op->data.reg.reg == reg0 || op->data.reg.reg == reg1)
- )
- {
- scan = block->lastPCode;
- break;
- }
-
- if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0))
- flag = 1;
- }
- }
- } else if (
- instr->op == PC_EXTSH &&
- (reg0 = instr->args[0].data.reg.reg) != (reg1 = instr->args[1].data.reg.reg)
- )
- {
- short flag = 0;
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- if (
- ((scan->op >= PC_STB && scan->op <= PC_STBUX) || (scan->op >= PC_STH && scan->op <= PC_STHUX)) &&
- scan->args[0].data.reg.reg == reg0
- )
- {
- scan->args[0].data.reg.reg = reg1;
- }
- else if (scan->op == PC_EXTSH && scan->args[1].data.reg.reg == reg0)
- {
- change_opcode(scan, PC_MR);
- if ((PCODE_FLAG_SET_F(scan) & fRecordBit) && !flag) {
- pcsetrecordbit(instr);
- scan->flags &= ~fRecordBit;
- scan->flags |= fIsMove;
- change_num_operands(scan, 2);
- }
- }
-
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (
- PC_OP_IS_WRITE_ANY_REGISTER(op, RegClass_GPR) &&
- (op->data.reg.reg == reg0 || op->data.reg.reg == reg1)
- )
- {
- scan = block->lastPCode;
- break;
- }
-
- if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0))
- flag = 1;
- }
- }
- } else if (
- instr->op == PC_ADDI &&
- (reg0 = instr->args[0].data.reg.reg) == (reg1 = instr->args[1].data.reg.reg) &&
- instr->args[2].kind == PCOp_IMMEDIATE
- )
- {
- Boolean flag1 = 0;
- Boolean flag2 = 0;
- SInt32 val2 = instr->args[2].data.imm.value;
-
- for (scan = instr->nextPCode; scan; scan = scan->nextPCode) {
- if ((scan->flags & fIsWrite) && scan->args[0].data.reg.reg == reg0)
- break;
-
- if (
- (scan->flags & (fIsRead | fIsWrite)) &&
- scan->args[1].data.reg.reg == reg0 &&
- scan->args[2].kind == PCOp_IMMEDIATE &&
- FITS_IN_SHORT(val2 + scan->args[2].data.imm.value)
- )
- {
- scan->args[2].data.imm.value += val2;
- tmp = instr->prevPCode;
- if (
- (scan->flags & fIsRead) &&
- scan->args[0].data.reg.reg == reg0 &&
- scan->args[0].kind == PCOp_REGISTER &&
- scan->args[0].arg == RegClass_GPR
- )
- {
- deletepcode(instr);
- } else {
- deletepcode(instr);
- insertpcodeafter(scan, instr);
- }
- instr = tmp;
- break;
- }
-
- if (
- scan->op == PC_ADDI &&
- scan->args[1].data.reg.reg == reg0 &&
- scan->args[2].kind == PCOp_IMMEDIATE &&
- FITS_IN_SHORT(val2 + scan->args[2].data.imm.value)
- )
- {
- scan->args[2].data.imm.value += val2;
- tmp = instr->prevPCode;
- if (scan->args[0].data.reg.reg == reg0) {
- deletepcode(instr);
- } else {
- deletepcode(instr);
- insertpcodeafter(scan, instr);
- }
- instr = tmp;
- break;
- }
-
- if (scan->flags & (fIsBranch | fIsCall)) {
- if (flag1 && scan->prevPCode != instr) {
- tmp = instr->prevPCode;
- deletepcode(instr);
- insertpcodebefore(scan, instr);
- instr = tmp;
- }
- break;
- }
-
- for (op = scan->args, i = scan->argCount; i--; op++) {
- if (PC_OP_IS_R_OR_W_REGISTER(op, RegClass_GPR, reg0)) {
- if (flag1 && scan->prevPCode != instr) {
- tmp = instr->prevPCode;
- deletepcode(instr);
- insertpcodebefore(scan, instr);
- instr = tmp;
- }
- flag2 = 1;
- break;
- }
- }
-
- if (flag2)
- break;
-
- if (scan->op != PC_ADDI)
- flag1 = 1;
-
- if (flag1 && !scan->nextPCode) {
- tmp = instr->prevPCode;
- deletepcode(instr);
- appendpcode(block, instr);
- instr = tmp;
- break;
- }
- }
- }
-
- if (instr)
- instr = instr->nextPCode;
- else
- instr = block->firstPCode;
- }
-}
-
-static void installpattern(Opcode opcode, PeepholeFunc func) {
- Pattern *pattern = lalloc(sizeof(Pattern));
- pattern->func = func;
- pattern->next = peepholepatterns[opcode];
- peepholepatterns[opcode] = pattern;
-}
-
-static void installpeepholepatterns(void) {
- int i;
-
- for (i = 0; i < OPCODE_MAX; i++)
- peepholepatterns[i] = NULL;
-
- installpattern(PC_AND, NOT_AND);
- installpattern(PC_MR, LI_MR);
- installpattern(PC_MR, L_MR);
- installpattern(PC_FMR, L_FMR);
- installpattern(PC_MR, MR_MR);
- installpattern(PC_MR, MR_Rx_Rx);
- installpattern(PC_FMR, FMR_FMR);
- installpattern(PC_FMR, FMR_Fx_Fx);
- installpattern(PC_VMR, VMR_VMRP);
- installpattern(PC_VMR, VMR_VMR);
- installpattern(PC_VMR, VMR_Vx_Vx);
- installpattern(PC_VMR, VSPLTIS_VMR);
- installpattern(PC_CMPI, MR_CMPI);
- installpattern(PC_RLWIMI, RLWINM_RLWINM);
- installpattern(PC_RLWINM, RLWINM_RLWINM);
- installpattern(PC_RLWINM, EXTSB_RLWINM);
- installpattern(PC_RLWINM, EXTSH_RLWINM);
- installpattern(PC_RLWINM, LBZ_RLWINM);
- installpattern(PC_RLWINM, LHZ_RLWINM);
- installpattern(PC_EXTSH, LHA_EXTSH);
- installpattern(PC_STW, RLWINM_RLWIMI_STW);
- installpattern(PC_STWX, RLWINM_RLWIMI_STW);
- installpattern(PC_STH, RLWINM_RLWIMI_STH);
- installpattern(PC_STHX, RLWINM_RLWIMI_STH);
- installpattern(PC_LBZ, ADDI_L_S);
- installpattern(PC_LHZ, ADDI_L_S);
- installpattern(PC_LHA, ADDI_L_S);
- installpattern(PC_LWZ, ADDI_L_S);
- installpattern(PC_STB, ADDI_L_S);
- installpattern(PC_STH, ADDI_L_S);
- installpattern(PC_STW, ADDI_L_S);
- installpattern(PC_LFS, ADDI_L_S);
- installpattern(PC_LFD, ADDI_L_S);
- installpattern(PC_STFS, ADDI_L_S);
- installpattern(PC_STFD, ADDI_L_S);
- installpattern(PC_LBZU, ADDI_LU_SU);
- installpattern(PC_LHZU, ADDI_LU_SU);
- installpattern(PC_LHAU, ADDI_LU_SU);
- installpattern(PC_LWZU, ADDI_LU_SU);
- installpattern(PC_STBU, ADDI_LU_SU);
- installpattern(PC_STHU, ADDI_LU_SU);
- installpattern(PC_STWU, ADDI_LU_SU);
- installpattern(PC_LFSU, ADDI_LU_SU);
- installpattern(PC_LFDU, ADDI_LU_SU);
- installpattern(PC_STFSU, ADDI_LU_SU);
- installpattern(PC_STFDU, ADDI_LU_SU);
- installpattern(PC_LBZ, L_S_ADDI);
- installpattern(PC_LHZ, L_S_ADDI);
- installpattern(PC_LHA, L_S_ADDI);
- installpattern(PC_LWZ, L_S_ADDI);
- installpattern(PC_STB, L_S_ADDI);
- installpattern(PC_STH, L_S_ADDI);
- installpattern(PC_STW, L_S_ADDI);
- installpattern(PC_LFS, L_S_ADDI);
- installpattern(PC_LFD, L_S_ADDI);
- installpattern(PC_STFS, L_S_ADDI);
- installpattern(PC_STFD, L_S_ADDI);
- installpattern(PC_STB, L_S);
- installpattern(PC_STH, L_S);
- installpattern(PC_STW, L_S);
- installpattern(PC_STFS, L_S);
- installpattern(PC_STFD, L_S);
- installpattern(PC_STBX, L_S);
- installpattern(PC_STHX, L_S);
- installpattern(PC_STWX, L_S);
- installpattern(PC_STFSX, L_S);
- installpattern(PC_STFDX, L_S);
- installpattern(PC_BT, LBZ_EXTSB_CMPI_BC);
- installpattern(PC_BF, LBZ_EXTSB_CMPI_BC);
- installpattern(PC_BT, RLWINM_CMPLI_BC);
- installpattern(PC_BF, RLWINM_CMPLI_BC);
- installpattern(PC_BT, LI_CMP_BC);
- installpattern(PC_BF, LI_CMP_BC);
- installpattern(PC_RLWINM, RLWINM_RLWINM);
- installpattern(PC_MULLI, MULLI_MULLI);
- installpattern(PC_ADDI, ADDI_ADDI);
- installpattern(PC_SRAWI, SRAWI_SRAWI);
- installpattern(PC_MR, MR_ADDI);
- installpattern(PC_OR, SRW_SUBFIC_RLW_OR);
-}
-
-void peepholeoptimizeforward(Object *func) {
- PCodeBlock *block;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (block->pcodeCount >= 2)
- adjustforward(block);
- }
-}
-
-void peepholemergeblocks(Object *func, Boolean flag) {
- PCodeBlock *block;
- PCodeBlock *next;
- Boolean flag2;
- PCode *instr;
- PCode *nextinstr;
- PCLink *link;
- PCLink *link2;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- flag2 = 0;
- next = block->nextBlock;
-
- if (!flag) {
- flag2 = next && (next->flags & fIsEpilogue);
- if (block->flags & fIsProlog)
- continue;
- }
-
- if (block->pcodeCount > 0) {
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->flags & (fIsCall | fSideEffects))
- break;
- }
-
- if (instr)
- continue;
-
- instr = block->lastPCode;
- if (instr && instr->op == PC_B) {
- if (instr->args[0].kind == PCOp_LABEL && instr->args[0].data.label.label->block == next)
- deletepcode(instr);
- else
- continue;
- }
-
- instr = block->lastPCode;
- if (instr && (instr->flags & fIsBranch) && instr->op != PC_B)
- continue;
-
- while (
- block->successors->block == next &&
- block->successors->nextLink == NULL &&
- next->predecessors->block == block &&
- next->predecessors->nextLink == NULL &&
- !flag2 &&
- !(next->flags & fPCBlockFlag8000) &&
- (block->pcodeCount + next->pcodeCount) <= 100
- )
- {
- if (next->pcodeCount > 0) {
- for (instr = next->firstPCode; instr; instr = nextinstr) {
- nextinstr = instr->nextPCode;
- if (instr->flags & (fIsCall | fSideEffects))
- break;
-
- deletepcode(instr);
- if (instr->op != PC_B) {
- appendpcode(block, instr);
- } else if (instr->args[0].kind == PCOp_LABEL) {
- if (instr->args[0].data.label.label->block != next->nextBlock)
- appendpcode(block, instr);
- } else {
- appendpcode(block, instr);
- }
- }
- }
-
- if (next->pcodeCount != 0)
- break;
- if (next == epilogue)
- break;
-
- block->successors = next->successors;
-
- for (link = block->successors; link; link = link->nextLink) {
- for (link2 = link->block->predecessors; link2; link2 = link2->nextLink) {
- if (link2->block == next) {
- link2->block = block;
- break;
- }
- }
- }
-
- block->nextBlock = next->nextBlock;
- if (block->nextBlock)
- block->nextBlock->prevBlock = block;
-
- next->flags |= fDeleted;
- next = block->nextBlock;
-
- if (!flag)
- flag2 = next && (next->flags & fIsEpilogue);
- }
- }
- }
-}
-
-void peepholeoptimizepcode(Object *func) {
- PCodeBlock *block;
-
- installpeepholepatterns();
- computeliveregisters(func);
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (block->pcodeCount >= 1) {
- computeinstructionpredecessors(block);
- peepholeoptimizeblock(block);
- freeoheap();
- }
- }
-}
diff --git a/compiler_and_linker/unsorted/RegisterInfo.c b/compiler_and_linker/unsorted/RegisterInfo.c
deleted file mode 100644
index 177c2e0..0000000
--- a/compiler_and_linker/unsorted/RegisterInfo.c
+++ /dev/null
@@ -1,381 +0,0 @@
-#include "compiler/RegisterInfo.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/PCode.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-short last_exception_register[RegClassMax];
-short first_fe_temporary_register[RegClassMax];
-short last_argument_register[RegClassMax];
-short _FP_;
-short _CALLER_SP_;
-char *special_register_names[RegClassMax][RegisterMax];
-static short used_regs_before_coloring;
-static UInt8 save_state[RegisterMax];
-
-short spr_to_sysreg[4] = {1, 8, 9, 0x100};
-
-void asm_used_register(RegClass rclass, short reg) {
- int i;
-
- if ((reg < n_real_registers[rclass]) && (reg_state[rclass][reg] == RegState0)) {
- if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]]) {
- if (assignable_registers[rclass] > 0)
- assignable_registers[rclass]--;
- reg_state[rclass][reg] = RegState1;
- used_nonvolatile_registers[rclass]++;
- } else {
- for (i = used_nonvolatile_registers[rclass]; i < n_nonvolatile_registers[rclass]; i++) {
- if (reg == nonvolatile_registers[rclass][i]) {
- reg_state[rclass][reg] = RegState1;
- if (assignable_registers[rclass] > 0)
- assignable_registers[rclass]--;
- }
- }
- }
- }
-}
-
-void retain_register(Object *obj, RegClass rclass, short reg) {
- VarInfo *vi;
-
- CError_ASSERT(95, (short) reg < RegisterMax);
-
- if (reg_state[rclass][reg] == RegState0) {
- assignable_registers[rclass]--;
- reg_state[rclass][reg] = RegState1;
- if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]])
- used_nonvolatile_registers[rclass]++;
- }
-
- if (obj) {
- vi = Registers_GetVarInfo(obj);
- vi->rclass = rclass;
- vi->flags |= VarInfoFlag2;
- vi->reg = reg;
- }
-}
-
-void retain_GPR_pair(Object *obj, short reg, short regHi) {
- VarInfo *vi;
-
- retain_register(NULL, RegClass_GPR, reg);
- retain_register(NULL, RegClass_GPR, regHi);
-
- if (obj) {
- vi = Registers_GetVarInfo(obj);
- vi->rclass = RegClass_GPR;
- vi->flags |= VarInfoFlag2 | VarInfoFlag4;
- vi->reg = reg;
- vi->regHi = regHi;
- }
-}
-
-int is_register_object(Object *obj) {
- return obj->sclass == TK_REGISTER;
-}
-
-int GetABIFirstNonVolatile(RegClass rclass) {
- switch (rclass) {
- case RegClass_SPR: return 3;
- case RegClass_CRFIELD: return 2;
- case RegClass_VR: return 20;
- case RegClass_GPR: return 13;
- case RegClass_FPR: return 14;
- default: return -1;
- }
-}
-
-char GetRegisterClassName(RegClass rclass) {
- switch (rclass) {
- case RegClass_VR: return 'v';
- case RegClass_GPR: return 'r';
- case RegClass_FPR: return 'f';
- default:
- CError_FATAL(242);
- return '?';
- }
-}
-
-static int first_nonvolatile_reg(RegClass rclass) {
- return GetABIFirstNonVolatile(rclass);
-}
-
-void setup_diagnostic_reg_strings(void) {
- register_class_name[RegClass_SPR] = "SPR";
- register_class_format[RegClass_SPR] = "spr%" PRId32;
- register_class_name[RegClass_CRFIELD] = "CRFIELD";
- register_class_format[RegClass_CRFIELD] = "cr%" PRId32;
- register_class_name[RegClass_VR] = "VR";
- register_class_format[RegClass_VR] = "vr%" PRId32;
- register_class_name[RegClass_FPR] = "FPR";
- register_class_format[RegClass_FPR] = "f%" PRId32;
- register_class_name[RegClass_GPR] = "GPR";
- register_class_format[RegClass_GPR] = "r%" PRId32;
-}
-
-void init_target_registers(void) {
- int reg;
- int end;
- RegClass rclass;
-
- static int last_nonvolatile_reg[] = {3, 5, 31, 31, 31};
- static int nonvol_reserve[] = {0, 0, 0, 4, 3};
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- for (reg = 0; reg < RegisterMax; reg++)
- special_register_names[rclass][reg] = NULL;
- }
-
- special_register_names[RegClass_SPR][0] = "XER";
- special_register_names[RegClass_SPR][1] = "LR";
- special_register_names[RegClass_SPR][2] = "CTR";
- special_register_names[RegClass_SPR][3] = "VRSAVE";
- special_register_names[RegClass_GPR][1] = "SP";
-
- setup_diagnostic_reg_strings();
- n_real_registers[RegClass_SPR] = 4;
- n_real_registers[RegClass_CRFIELD] = 8;
- n_real_registers[RegClass_VR] = 32;
- n_real_registers[RegClass_FPR] = 32;
- n_real_registers[RegClass_GPR] = 32;
- reg_state[RegClass_GPR][1] = RegState2;
- reg_state[RegClass_GPR][2] = RegState2;
- reg_state[RegClass_CRFIELD][5] = RegState2;
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- n_nonvolatile_registers[rclass] = 0;
- if (last_nonvolatile_reg[rclass] >= 0) {
- end = first_nonvolatile_reg(rclass);
- for (reg = last_nonvolatile_reg[rclass]; reg >= end; reg--) {
- if (reg_state[rclass][reg] == RegState0) {
- nonvolatile_registers[rclass][n_nonvolatile_registers[rclass]++] = reg;
- }
- }
- }
-
- assignable_registers[rclass] = n_nonvolatile_registers[rclass] - nonvol_reserve[rclass];
- if (assignable_registers[rclass] < 0)
- assignable_registers[rclass] = 0;
-
- n_scratch_registers[rclass] = 0;
- for (reg = 0; reg < n_real_registers[rclass]; reg++) {
- if (reg < GetABIFirstNonVolatile(rclass) || reg > last_nonvolatile_reg[rclass]) {
- if (reg_state[rclass][reg] == RegState0) {
- scratch_registers[rclass][n_scratch_registers[rclass]++] = reg;
- }
- }
- }
- }
-
- _FP_ = -1;
- _CALLER_SP_ = -1;
- optimizing = (copts.optimizationlevel > 0) && !disable_optimizer;
-}
-
-void assign_register_by_type(Object *obj) {
- VarInfo *vi;
- Type *ty;
- Boolean flag;
-
- ty = obj->type;
- vi = Registers_GetVarInfo(obj);
- flag = 0;
- vi->rclass = RegClassMax;
- vi->reg = 0;
- vi->regHi = 0;
-
- if ((ty->type == TYPEINT) || (ty->type == TYPEENUM) || ((ty->type == TYPEPOINTER || ty->type == TYPEARRAY) && (ty->type != TYPEARRAY)) || ((ty->type == TYPEMEMBERPOINTER) && (ty->size == 4U))) {
- if (((ty->type == TYPEINT) || (ty->type == TYPEENUM)) && (ty->size == 8))
- flag = 1;
- vi->rclass = RegClass_GPR;
- } else if (ty->type == TYPEFLOAT) {
- vi->rclass = RegClass_FPR;
- } else if ((ty->type == TYPESTRUCT) && (TYPE_STRUCT(ty)->stype >= STRUCT_VECTOR_UCHAR) && (TYPE_STRUCT(ty)->stype <= STRUCT_VECTOR_PIXEL)) {
- vi->rclass = RegClass_VR;
- } else {
- return;
- }
-
- if (vi->rclass < RegClassMax) {
- if (flag) {
- CError_ASSERT(520, vi->rclass == RegClass_GPR);
- if (assignable_registers[vi->rclass] > 1)
- assign_GPR_pair(obj);
- } else {
- if (assignable_registers[vi->rclass] > 0)
- assign_register_to_variable(obj, vi->rclass);
- }
- }
-}
-
-void assign_GPR_pair(Object *obj) {
- VarInfo *vi;
- short reg;
- short regHi;
-
- vi = Registers_GetVarInfo(obj);
- if (optimizing) {
- reg = used_virtual_registers[RegClass_GPR]++;
- regHi = used_virtual_registers[RegClass_GPR]++;
- } else {
- CError_ASSERT(554, assignable_registers[RegClass_GPR] >= 2);
- reg = obtain_nonvolatile_register(RegClass_GPR);
- regHi = obtain_nonvolatile_register(RegClass_GPR);
- retain_GPR_pair(obj, reg, regHi);
- }
-
- vi->rclass = RegClass_GPR;
- if (reg > 0 && regHi > 0) {
- vi->flags |= VarInfoFlag2 | VarInfoFlag4;
- vi->reg = reg;
- vi->regHi = regHi;
- } else {
- CError_FATAL(567);
- }
-}
-
-void open_fe_temp_registers(void) {
- int r;
-
- r = used_virtual_registers[RegClass_GPR];
- first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = r;
- r = used_virtual_registers[RegClass_FPR];
- first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = r;
- r = used_virtual_registers[RegClass_VR];
- first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = r;
-}
-
-void set_last_exception_registers(void) {
- last_exception_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR] - 1;
- last_exception_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR] - 1;
- last_exception_register[RegClass_VR] = used_virtual_registers[RegClass_VR] - 1;
-}
-
-static VarInfo *Registers_GetNewVarInfo(void) {
- VarInfo *vi = galloc(sizeof(VarInfo));
- memclrw(vi, sizeof(VarInfo));
- return vi;
-}
-
-VarInfo *Registers_GetVarInfo(Object *obj) {
- switch (obj->datatype) {
- case DDATA:
- if (!obj->u.data.info)
- obj->u.data.info = Registers_GetNewVarInfo();
- return obj->u.data.info;
- case DNONLAZYPTR:
- if (!obj->u.toc.info) {
- CError_FATAL(639);
- obj->u.toc.info = CodeGen_GetNewVarInfo();
- }
- return obj->u.toc.info;
- case DLOCAL:
- if (!obj->u.var.info)
- CError_FATAL(647);
- return obj->u.var.info;
- case DABSOLUTE:
- // not sure if this is the right union
- if (!obj->u.data.info)
- obj->u.data.info = Registers_GetNewVarInfo();
- return obj->u.data.info;
- default:
- CError_FATAL(660);
- return NULL;
- }
-}
-
-int used_vrstate_VRs(void) {
- int count = 0;
- int i;
- for (i = 0; i < RegisterMax; i++) {
- if (reg_state[RegClass_VR][i])
- count++;
- }
- return count;
-}
-
-UInt32 colored_vrs_as_vrsave(PCodeBlock *block) {
- PCode *pc;
- UInt32 mask;
- int i;
-
- mask = 0;
- if (copts.altivec_vrsave == 2)
- return 0xFFFFFFFF;
- if (copts.altivec_vrsave == 0)
- return 0;
-
- while (block) {
- for (pc = block->firstPCode; pc; pc = pc->nextPCode) {
- if (pc->flags & fOpTypeVR) {
- for (i = 0; i < pc->argCount; i++) {
- if (pc->args[i].kind == PCOp_REGISTER && pc->args[i].arg == RegClass_VR)
- mask |= 1 << (31 - pc->args[i].data.reg.reg);
- }
- }
- }
- block = block->nextBlock;
- }
-
- return mask;
-}
-
-void save_before_coloring_nonvolatile_registers(RegClass rclass) {
- used_regs_before_coloring = used_nonvolatile_registers[rclass];
- memcpy(save_state, reg_state[rclass], sizeof(save_state));
-}
-
-void reset_nonvolatile_registers(RegClass rclass) {
- used_nonvolatile_registers[rclass] = used_regs_before_coloring;
- memcpy(reg_state[rclass], save_state, sizeof(save_state));
-}
-
-int is_nonvolatile_register(RegClass rclass, int reg) {
- int i;
-
- for (i = 0; i < n_nonvolatile_registers[rclass]; i++) {
- if (reg == nonvolatile_registers[rclass][i])
- return 1;
- }
-
- return 0;
-}
-
-void init_endian(void) {
- if (copts.littleendian) {
- high_offset = 4;
- low_offset = 0;
- high_reg = 4;
- low_reg = 3;
- high_reg2 = 6;
- low_reg2 = 5;
- } else {
- high_offset = 0;
- low_offset = 4;
- high_reg = 3;
- low_reg = 4;
- high_reg2 = 5;
- low_reg2 = 6;
- }
-}
-
-void update_asm_nonvolatile_registers(void) {
- RegClass rclass;
- int i;
- int reg;
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- reg = n_nonvolatile_registers[rclass];
- for (i = n_nonvolatile_registers[rclass] - 1; i >= 0; i--) {
- if (reg_state[rclass][nonvolatile_registers[rclass][i]] == RegState1)
- break;
- reg--;
- }
- if (reg > used_nonvolatile_registers[rclass])
- used_nonvolatile_registers[rclass] = reg;
- }
-}
diff --git a/compiler_and_linker/unsorted/Scheduler.c b/compiler_and_linker/unsorted/Scheduler.c
deleted file mode 100644
index 23b580f..0000000
--- a/compiler_and_linker/unsorted/Scheduler.c
+++ /dev/null
@@ -1,547 +0,0 @@
-#include "compiler/Scheduler.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/Alias.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/Registers.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct DGNode {
- struct DGNode *x0;
- struct DGNode *x4;
- struct DGSuccessor *successors;
- PCode *instr;
- UInt16 x10;
- UInt16 x12;
- UInt16 x14;
- UInt16 x16;
- short predCount;
-} DGNode;
-
-typedef struct DGSuccessor {
- struct DGSuccessor *next;
- DGNode *node;
- UInt16 x8;
-} DGSuccessor;
-
-typedef struct DGNodeList {
- struct DGNodeList *next;
- DGNode *node;
-} DGNodeList;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static DGNodeList **register_uses[RegClassMax];
-static DGNodeList **register_defs[RegClassMax];
-static DGNodeList *memory_uses;
-static DGNodeList *memory_defs;
-static DGNodeList *side_effects;
-static DGNodeList *volatile_refs;
-static DGNode *defaultsuccessor;
-static UInt16 criticalpath;
-static MachineInfo *MI;
-
-static void initresources(void) {
- int rclass;
- int i;
-
- for (rclass = 0; (char) rclass < RegClassMax; rclass++) {
- register_uses[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]);
- register_defs[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]);
- for (i = 0; i < used_virtual_registers[(char) rclass]; i++) {
- register_uses[(char) rclass][i] = register_defs[(char) rclass][i] = NULL;
- }
- }
-
- memory_uses = memory_defs = NULL;
- side_effects = NULL;
- volatile_refs = NULL;
- criticalpath = 0;
-}
-
-static DGNode *makedgnode(PCode *instr) {
- DGNode *node;
-
- node = oalloc(sizeof(DGNode));
- node->x0 = NULL;
- node->x4 = NULL;
- node->successors = NULL;
- node->instr = instr;
- node->x10 = node->x16 = MI->latency(instr);
- node->x12 = 0;
- node->x14 = 0;
- node->predCount = 0;
- return node;
-}
-
-static DGNode *adddgnode(DGNode *head, DGNode *node) {
- if (head)
- head->x4 = node;
- node->x0 = head;
- return node;
-}
-
-static DGNode *removedgnode(DGNode *head, DGNode *node) {
- if (node->x4)
- node->x4->x0 = node->x0;
- else
- head = node->x0;
-
- if (node->x0)
- node->x0->x4 = node->x4;
-
- return head;
-}
-
-static void addtolist(DGNodeList **list, DGNode *node) {
- DGNodeList *entry = oalloc(sizeof(DGNodeList));
- entry->node = node;
- entry->next = *list;
- *list = entry;
-}
-
-static DGNodeList *makedglistnode(DGNode *node) {
- DGNodeList *list = oalloc(sizeof(DGNodeList));
- list->next = NULL;
- list->node = node;
- return list;
-}
-
-int is_same_operand(PCodeArg *a, PCodeArg *b) {
- if (a->kind != b->kind)
- return 0;
-
- switch (a->kind) {
- case PCOp_IMMEDIATE:
- if (a->data.imm.value != b->data.imm.value)
- return 0;
- break;
- case PCOp_REGISTER:
- if ((char) a->arg != (char) b->arg)
- return 0;
- if (a->data.reg.reg != b->data.reg.reg)
- return 0;
- break;
- case PCOp_MEMORY:
- if (a->data.mem.offset != b->data.mem.offset)
- return 0;
- if (a->data.mem.obj != b->data.mem.obj)
- return 0;
- break;
- case PCOp_LABEL:
- if (a->data.label.label != b->data.label.label)
- return 0;
- break;
- }
-
- return 1;
-}
-
-static void addsuccessor(DGNode *a, DGNode *b, Boolean flag) {
- int v6;
- int r29;
- DGSuccessor *succ;
-
- if (flag)
- v6 = a->x10;
- else
- v6 = 0;
-
- if (a != b) {
- r29 = (v6 > 0) ? v6 : 0;
- for (succ = a->successors; succ; succ = succ->next) {
- if (succ->node == b) {
- if (succ->x8 < r29) {
- succ->x8 = r29;
- if (b->x16 + succ->x8 > a->x16)
- a->x16 = b->x16 + succ->x8;
- }
- return;
- }
- }
-
- succ = oalloc(sizeof(DGSuccessor));
- succ->node = b;
- succ->next = a->successors;
- a->successors = succ;
- succ->x8 = r29;
-
- if (flag && (succ->node->instr->flags & fIsBranch))
- succ->x8 += MI->x8;
-
- b->predCount++;
-
- if (b->x16 + succ->x8 > a->x16)
- a->x16 = b->x16 + succ->x8;
- }
-}
-
-static void serializeall(DGNode *nodes, DGNode *node) {
- DGNode *scan;
-
- for (scan = nodes; scan; scan = scan->x0)
- addsuccessor(node, scan, 0);
-}
-
-static void serializelist(DGNode *node, DGNodeList *list) {
- while (list) {
- if (list->node != node)
- addsuccessor(node, list->node, 0);
- list = list->next;
- }
-}
-
-static void serializeregister(int rclass, DGNode *node, DGNodeList **defs, DGNodeList **uses, int isWrite) {
- DGNodeList *list;
-
- if (isWrite) {
- for (list = *uses; list; list = list->next) {
- if (list->node != node)
- addsuccessor(node, list->node, 1);
- }
- for (list = *defs; list; list = list->next) {
- if (list->node != node)
- addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0));
- }
-
- list = makedglistnode(node);
- list->next = *defs;
- *defs = list;
- } else {
- for (list = *defs; list; list = list->next) {
- if (list->node != node)
- addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0));
- }
-
- list = makedglistnode(node);
- list->next = *uses;
- *uses = list;
- }
-}
-
-static void serialize_load(DGNode *node) {
- DGNodeList *list;
-
- for (list = memory_defs; list; list = list->next) {
- if (may_alias(node->instr, list->node->instr))
- addsuccessor(node, list->node, 1);
- }
-
- addtolist(&memory_uses, node);
-}
-
-static void serialize_store(DGNode *node) {
- DGNodeList *list;
-
- for (list = memory_uses; list; list = list->next) {
- if (may_alias(node->instr, list->node->instr))
- addsuccessor(node, list->node, 1);
- }
- for (list = memory_defs; list; list = list->next) {
- if (may_alias(node->instr, list->node->instr))
- addsuccessor(node, list->node, 1);
- }
-
- addtolist(&memory_defs, node);
- if (node->instr->flags & fPCodeFlag40000)
- addtolist(&memory_uses, node);
-}
-
-static void findsuccessors(DGNode *nodes, DGNode *node) {
- PCode *instr;
- PCodeArg *op;
- int i;
-
- instr = node->instr;
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- switch (op->kind) {
- case PCOp_IMMEDIATE:
- case PCOp_MEMORY:
- break;
- case PCOp_REGISTER:
- if (
- op->data.reg.reg < 0 ||
- op->data.reg.reg > used_virtual_registers[(char) op->arg]
- )
- {
- CError_FATAL(491);
- }
-
- if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
- if (op->data.reg.reg == Register2)
- break;
- if (op->data.reg.reg == Register0 && !(op->data.reg.effect & (EffectRead | EffectWrite)))
- break;
- }
-
- serializeregister(
- op->arg,
- node,
- &register_defs[(char) op->arg][op->data.reg.reg],
- &register_uses[(char) op->arg][op->data.reg.reg],
- op->data.reg.effect & EffectWrite
- );
-
- break;
- }
- }
-
- if (instr->flags & (fIsRead | fPCodeFlag20000))
- serialize_load(node);
- else if (instr->flags & (fIsWrite | fPCodeFlag40000))
- serialize_store(node);
-
- if (instr->flags & fIsVolatile) {
- serializelist(node, volatile_refs);
- addtolist(&volatile_refs, node);
- }
-
- if (
- ((instr->flags & fIsCall | fIsBranch) && (instr->flags & fLink)) ||
- (instr->flags & fSideEffects) ||
- MI->serializes(instr)
- )
- {
- serializeall(nodes, node);
- addtolist(&side_effects, node);
- }
-
- if (side_effects)
- serializelist(node, side_effects);
-
- if (!node->successors && defaultsuccessor)
- addsuccessor(node, defaultsuccessor, 0);
-
- if (node->x16 > criticalpath)
- criticalpath = node->x16;
-}
-
-static void computedeadlines(DGNode *nodes) {
- while (nodes) {
- nodes->x14 = criticalpath - nodes->x16;
- nodes = nodes->x0;
- }
-}
-
-static int uncovering(DGNode *node) {
- int counter;
- DGSuccessor *succ;
-
- counter = 0;
- for (succ = node->successors; succ; succ = succ->next) {
- if (succ->node->predCount == 1)
- counter++;
- }
-
- return counter;
-}
-
-static DGNode *selectinstruction(DGNode *nodes, UInt16 counter) {
- DGNode *node;
- DGNode *node2;
- int a;
- int b;
-
- node = nodes;
- while (node) {
- if (node->predCount == 0 && node->x12 <= counter && MI->can_issue(node->instr))
- break;
- node = node->x0;
- }
-
- if (!node)
- return NULL;
-
- for (node2 = node->x0; node2; node2 = node2->x0) {
- if (
- node2->predCount == 0 &&
- node2->x12 <= counter &&
- MI->can_issue(node2->instr) &&
- (node->x14 > counter || node2->x14 <= counter)
- )
- {
- if (node->x14 > counter && node2->x14 <= counter) {
- node = node2;
- continue;
- }
-
- if ((a = uncovering(node)) > (b = uncovering(node2)))
- continue;
-
- if (a < b) {
- node = node2;
- continue;
- }
-
- if (node->x16 > node2->x16)
- continue;
-
- if (node->x16 < node2->x16) {
- node = node2;
- continue;
- }
-
- if (coloring) {
- if (opcodeinfo[node->instr->op].x9 < opcodeinfo[node2->instr->op].x9)
- continue;
-
- if (opcodeinfo[node->instr->op].x9 > opcodeinfo[node2->instr->op].x9)
- node = node2;
- }
- }
- }
-
- return node;
-}
-
-static void holdoffsuccessors(DGNode *node, UInt16 counter) {
- DGSuccessor *succ;
- DGNode *n;
-
- for (succ = node->successors; succ; succ = succ->next) {
- n = succ->node;
- n->predCount--;
- if (n->x12 < counter + succ->x8)
- n->x12 = counter + succ->x8;
- }
-}
-
-static void scheduleblock(PCodeBlock *block) {
- DGNode *node;
- UInt16 counter;
- PCode *instr;
- UInt16 i;
- DGNode *head;
-
- initresources();
- defaultsuccessor = NULL;
- head = NULL;
-
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- DGNode *n = makedgnode(instr);
- findsuccessors(head, n);
- if (instr->flags & fIsBranch)
- defaultsuccessor = n;
- head = adddgnode(head, n);
- }
-
- computedeadlines(head);
- block->firstPCode = block->lastPCode = NULL;
- block->pcodeCount = 0;
-
- MI->initialize();
- counter = 0;
- while (head != NULL) {
- for (i = 0; i < MI->x0; i++) {
- if (head == NULL)
- break;
-
- node = selectinstruction(head, counter);
- if (!node)
- break;
-
- instr = node->instr;
- if (node->successors)
- holdoffsuccessors(node, counter);
-
- appendpcode(block, instr);
- MI->issue(instr);
- head = removedgnode(head, node);
- }
-
- MI->advance_clock();
- counter++;
- }
-
- freeoheap();
-}
-
-void scheduleinstructions(Boolean flag) {
- PCodeBlock *block;
- int cpu;
-
- cpu = copts.scheduling;
- if (cpu == 10) {
- MI = &machine7450;
- } else if (copts.altivec_model != 0 || cpu == 7) {
- MI = &machine7400;
- } else if (cpu == 2) {
- MI = &machine603;
- } else if (cpu == 5) {
- MI = &machine603e;
- } else if (cpu == 3) {
- MI = &machine604;
- } else if (cpu == 6) {
- MI = &machine604;
- } else if (cpu == 4) {
- MI = &machine750;
- } else if (cpu == 1) {
- MI = &machine601;
- } else if (cpu == 9) {
- MI = &machine821;
- } else {
- MI = &machine603;
- }
-
- gather_alias_info();
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (
- block->pcodeCount > 2 &&
- (flag || !(block->flags & (fIsProlog | fIsEpilogue))) &&
- !(block->flags & fScheduled)
- )
- {
- scheduleblock(block);
- block->flags |= fScheduled;
- }
- }
-}
-
-int is_dependent(PCode *a, PCode *b, char rclass) {
- int i;
- int reg;
- PCodeArg *op;
-
- if (
- b &&
- b->argCount >= 1 &&
- b->args[0].kind == PCOp_REGISTER &&
- (char) b->args[0].arg == rclass &&
- (b->args[0].data.reg.effect & EffectWrite)
- )
- {
- reg = b->args[0].data.reg.reg;
- for (i = 0; i < a->argCount; i++) {
- op = &a->args[i];
- if (
- op->kind == PCOp_REGISTER &&
- (char) op->arg == rclass &&
- (op->data.reg.effect & (EffectRead | EffectWrite)) &&
- op->data.reg.reg == reg
- )
- return 1;
- }
- }
-
- return 0;
-}
-
-int uses_vpermute_unit(PCode *instr) {
- int cpu;
-
- cpu = copts.scheduling;
- if (cpu == 10)
- return machine7450.uses_vpermute_unit(instr);
- if (copts.altivec_model != 0 || cpu == 7)
- return machine7400.uses_vpermute_unit(instr);
- return 0;
-}
-
-int default_uses_vpermute_unit(PCode *instr) {
- return 0;
-}
diff --git a/compiler_and_linker/unsorted/SpillCode.c b/compiler_and_linker/unsorted/SpillCode.c
deleted file mode 100644
index 69e7e43..0000000
--- a/compiler_and_linker/unsorted/SpillCode.c
+++ /dev/null
@@ -1,452 +0,0 @@
-#include "compiler/SpillCode.h"
-#include "compiler/CError.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Coloring.h"
-#include "compiler/InterferenceGraph.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Registers.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/objects.h"
-
-static int last_unused_vreg_before_spilling;
-static short rTEMP_for_VR_spill;
-
-void estimatespillcosts(void) {
- PCodeBlock *block;
- PCode *instr;
- IGNode *node;
- PCodeArg *op;
- int i;
- int weight;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (copts.optimizesize)
- weight = 1;
- else
- weight = block->loopWeight;
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class)) {
- node = interferencegraph[op->data.reg.reg];
- if (node->instr8 || copts.optimizesize)
- node->spillCost += weight;
- else
- node->spillCost += weight * 2;
- }
- op++;
- }
-
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class)) {
- node = interferencegraph[op->data.reg.reg];
- if (node->instr8 || (instr->flags & fIsArgInit))
- node->spillCost -= weight;
- else
- node->spillCost += weight;
- }
- op++;
- }
- }
- }
-}
-
-static Object *makespilltemporary(Type *type) {
- Object *obj = lalloc(sizeof(Object));
- memclrw(obj, sizeof(Object));
-
- obj->otype = OT_OBJECT;
- obj->access = ACCESSPUBLIC;
- obj->datatype = DLOCAL;
- obj->type = type;
- obj->name = CParser_GetUniqueName();
- obj->u.var.info = CodeGen_GetNewVarInfo();
- obj->u.var.uid = 0;
-
- return obj;
-}
-
-static PCode *rematerialize_spilled_register(short reg, IGNode *node) {
- PCode *instr = copypcode(node->instr8);
-
- CError_ASSERT(128, instr->args[0].kind == PCOp_REGISTER);
-
- instr->args[0].data.reg.reg = reg;
- return instr;
-}
-
-static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node) {
- Type *type;
- Opcode opcode;
- Object *object;
- PCode *newInstr;
- PCode *newInstr2;
- SInt32 offset;
- Operand operand;
-
- type = node->spillTemporary->type;
- switch (coloring_class) {
- case RegClass_CRFIELD:
- case RegClass_GPR:
- switch (type->size) {
- case 1:
- opcode = PC_LBZ;
- break;
- case 2:
- opcode = is_unsigned(type) ? PC_LHZ : PC_LHA;
- break;
- case 4:
- opcode = PC_LWZ;
- break;
- case 8:
- opcode = PC_LWZ;
- break;
- default:
- CError_FATAL(187);
- }
-
- memclrw(&operand, sizeof(Operand));
- operand.optype = OpndType_Symbol;
- operand.object = node->spillTemporary;
- CError_ASSERT(222, node->spillTemporary->datatype == DLOCAL);
-
- coerce_to_addressable(&operand);
-
- CError_ASSERT(233, operand.optype == OpndType_GPR_ImmOffset);
-
- CError_ASSERT(237, node->spillTemporary->datatype == DLOCAL);
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
- insertpcodebefore(instr, makepcode(opcode, reg, operand.reg, operand.object, operand.immOffset + offset));
- break;
-
- case RegClass_FPR:
- CError_ASSERT(253, node->spillTemporary->datatype == DLOCAL);
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
-
- object = node->spillTemporary;
- insertpcodebefore(
- instr,
- makepcode(
- (type->size == 8) ? PC_LFD : PC_LFS,
- reg,
- local_base_register(object),
- object,
- offset
- )
- );
- break;
-
- case RegClass_VR:
- CError_ASSERT(320, node->spillTemporary->datatype == DLOCAL);
-
- object = node->spillTemporary;
- newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
- newInstr2 = makepcode(PC_LVX, reg, 0, rTEMP_for_VR_spill);
- insertpcodebefore(instr, newInstr);
- insertpcodeafter(newInstr, newInstr2);
- break;
-
- default:
- CError_FATAL(333);
- }
-}
-
-static void insert_store_spilled_register(PCode *instr, Boolean flag, short reg, IGNode *node) {
- Object *object; // r31
- Opcode opcode; // r30
- SInt32 offset; // r26
- PCode *newInstr2; // r26
- PCode *newInstr; // r25
- Type *type; // r25
-
- object = node->spillTemporary;
- type = object->type;
-
- switch (coloring_class) {
- case RegClass_CRFIELD:
- case RegClass_GPR:
- switch (type->size) {
- case 1:
- opcode = PC_STB;
- break;
- case 2:
- opcode = PC_STH;
- break;
- case 4:
- opcode = PC_STW;
- break;
- case 8:
- opcode = PC_STW;
- break;
- default:
- CError_FATAL(391);
- }
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
-
- newInstr = makepcode(opcode, reg, local_base_register(object), object, offset);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
-
- break;
-
- case RegClass_FPR:
- newInstr = makepcode((type->size == 8) ? PC_STFD : PC_STFS, reg, local_base_register(object), object, 0);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
-
- break;
-
- case RegClass_VR:
- newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
- newInstr2 = makepcode(PC_STVX, reg, 0, rTEMP_for_VR_spill);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
- insertpcodeafter(newInstr, newInstr2);
-
- break;
-
- default:
- CError_FATAL(527);
- }
-}
-
-static void spillinstruction(PCodeBlock *block, PCode *instr) {
- int reg;
- int reg2;
- int regs;
- IGNode *node;
- PCodeArg *op;
- int i;
- PCodeArg *op2;
- int j;
- int readCounter;
- int writeCounter;
- Boolean flag;
-
- regs = used_virtual_registers[coloring_class];
- flag = 0;
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- CError_ASSERT(563, instr->block != NULL);
-
- if (
- PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
- (reg = op->data.reg.reg) < regs &&
- ((node = interferencegraph[op->data.reg.reg])->flags & fSpilled)
- )
- {
- reg2 = used_virtual_registers[coloring_class]++;
- readCounter = 0;
- writeCounter = 0;
-
- for (j = i, op2 = op; j < instr->argCount; j++, op2++) {
- if (PC_OP_IS_REGISTER(op2, coloring_class, reg)) {
- if (op2->data.reg.effect & EffectRead)
- readCounter++;
- if (op2->data.reg.effect & EffectWrite)
- writeCounter++;
- op2->data.reg.reg = reg2;
- op2->data.reg.effect |= Effect40;
- }
- }
-
- if (readCounter) {
- if (node->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(reg2, node));
- else
- insert_load_spilled_register(instr, reg2, node);
- }
-
- if (writeCounter) {
- if (node->instr8 || (instr->flags & fIsArgInit))
- flag = 1;
- else
- insert_store_spilled_register(instr, 0, reg2, node);
- }
- }
- }
-
- if (flag)
- deletepcode(instr);
-}
-
-static void spillcopy(PCodeBlock *block, PCode *instr) {
- IGNode *node1;
- IGNode *node2;
- int reg;
-
- node1 = interferencegraph[instr->args[1].data.reg.reg];
- node2 = interferencegraph[instr->args[0].data.reg.reg];
-
- if (node1->flags & fSpilled) {
- if (node2->flags & fSpilled) {
- reg = used_virtual_registers[coloring_class]++;
- if (node1->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(reg, node1));
- else
- insert_load_spilled_register(instr, reg, node1);
- insert_store_spilled_register(instr, 1, reg, node2);
- } else {
- if (node1->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(instr->args[0].data.reg.reg, node1));
- else
- insert_load_spilled_register(instr, instr->args[0].data.reg.reg, node1);
- }
- } else {
- insert_store_spilled_register(instr, 1, instr->args[1].data.reg.reg, node2);
- }
-
- deletepcode(instr);
-}
-
-static void spillcall(PCodeBlock *block, PCode *instr) {
- PCodeArg *opSrc;
- PCodeArg *opDst;
- int opCount;
- int volatileCount;
- int i;
-
- opCount = instr->argCount;
- volatileCount = branch_count_volatiles();
-
- opDst = instr->args + volatileCount;
- opSrc = instr->args + volatileCount;
- for (i = volatileCount; i < opCount; i++) {
- if (
- PC_OP_IS_ANY_REGISTER(opSrc, coloring_class) &&
- opSrc->data.reg.reg >= n_real_registers[coloring_class] &&
- (interferencegraph[opSrc->data.reg.reg]->flags & fSpilled)
- )
- {
- instr->argCount--;
- } else {
- *opDst = *opSrc;
- opDst++;
- }
- opSrc++;
- }
-
- spillinstruction(block, instr);
-}
-
-static void assign_spill_locations(void) {
- UInt32 i;
- IGNode *node;
- Type *type;
-
- last_unused_vreg_before_spilling = used_virtual_registers[coloring_class];
- for (i = n_real_registers[coloring_class]; i < last_unused_vreg_before_spilling; i++) {
- node = interferencegraph[i];
- if (node->flags & fCoalesced)
- continue;
- if (!(node->flags & fSpilled))
- continue;
-
- if (!node->spillTemporary) {
- switch (coloring_class) {
- case RegClass_GPR:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_CRFIELD:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_FPR:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_VR:
- type = TYPE(&stvectorunsignedchar);
- break;
- default:
- CError_FATAL(771);
- }
-
- node->spillTemporary = makespilltemporary(type);
- }
-
- if (node->spillTemporary->datatype == DLOCAL && !(node->spillTemporary->u.var.info->flags & VarInfoFlag1))
- assign_local_memory(node->spillTemporary);
-
- if (node->flags & fPairHigh)
- Registers_GetVarInfo(node->spillTemporary)->regHi = Register0;
- else
- Registers_GetVarInfo(node->spillTemporary)->reg = Register0;
- }
-}
-
-void insertspillcode(void) {
- PCodeBlock *block;
- PCode *instr;
- PCode *nextInstr;
- PCodeArg *op;
- UInt32 i;
- int flag;
-
- rTEMP_for_VR_spill = 0;
- assign_spill_locations();
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- flag = 0;
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
- op->data.reg.reg < last_unused_vreg_before_spilling &&
- (interferencegraph[op->data.reg.reg]->flags & fSpilled)
- )
- {
- flag = 1;
- break;
- }
- op++;
- }
-
- if (flag) {
- if (coloring_class == RegClass_VR && rTEMP_for_VR_spill == 0)
- rTEMP_for_VR_spill = used_virtual_registers[RegClass_GPR]++;
-
- if (instr->flags & fIsMove)
- spillcopy(block, instr);
- else if (instr->flags & fIsCall)
- spillcall(block, instr);
- else
- spillinstruction(block, instr);
- }
- }
- }
-}
diff --git a/compiler_and_linker/unsorted/StackFrame.c b/compiler_and_linker/unsorted/StackFrame.c
deleted file mode 100644
index 6fa4524..0000000
--- a/compiler_and_linker/unsorted/StackFrame.c
+++ /dev/null
@@ -1,1252 +0,0 @@
-#include "compiler/StackFrame.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-#define ALIGN(thing, alignment) ( ~((alignment) - 1) & ((thing) + (alignment) - 1) )
-#define ALIGN_REMAINDER(thing, alignment) ( ALIGN(thing, alignment) - (thing) )
-
-Boolean requires_frame;
-Boolean makes_call;
-Boolean uses_globals;
-Boolean dynamic_stack;
-Boolean large_stack;
-static SInt32 out_param_alignment;
-static SInt32 in_parameter_size;
-static SInt32 in_param_alignment;
-static SInt32 frame_alignment;
-static SInt32 alloca_alignment;
-static SInt32 linkage_area_size;
-static SInt32 parameter_area_size;
-static SInt32 parameter_area_size_estimate;
-static SInt32 local_data_size;
-static SInt32 local_data_limit;
-static SInt32 large_data_near_size;
-static SInt32 large_data_far_size;
-static ObjectList *local_objects[ObjClassMax];
-static ObjectList *local_objects_tail[ObjClassMax];
-static SInt32 non_volatile_save_offset[RegClassMax];
-static SInt32 VRSAVE_save_offset;
-static SInt32 LR_save_offset;
-static SInt32 nonvolatile_save_size;
-static UInt32 vrsave_mask;
-static SInt32 frame_size;
-static SInt32 frame_size_estimate;
-static SInt32 genuine_frame_size;
-static Object *dummylocal;
-static Boolean dynamic_align_stack;
-static Boolean has_varargs;
-static Boolean compressing_data_area;
-static PCode *setup_caller_sp;
-static PCode *align_instr1;
-static PCode *align_instr2;
-static short vrsave_register;
-static PCode *loadvrsave;
-static PCode *storevrsave;
-Object *dummyvaparam;
-void *dummyprofiler;
-
-// forward declarations
-static void insert_local_object(UInt8 oclass, Object *obj);
-static void compress_data_area(void);
-static UInt32 align_bits(UInt32 value, UInt8 bitcount);
-static Boolean use_helper_function(char rclass);
-static Boolean need_link_register(void);
-static void call_helper_function(char *name, char rclass, short effect);
-static void save_nonvolatile_FPRs(int reg, SInt32 offset);
-static void save_nonvolatile_VRs(int reg, SInt32 offset);
-static void restore_nonvolatile_FPRs(int reg, SInt32 offset);
-static void restore_nonvolatile_VRs(int reg, SInt32 offset);
-static void save_nonvolatile_GPRs(int reg, SInt32 offset);
-static void restore_nonvolatile_GPRs(int reg, SInt32 offset);
-static void do_allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size);
-
-void init_stack_globals(Object *funcobj) {
- RegClass rclass;
- ObjClass oclass;
-
- requires_frame = 0;
- makes_call = 0;
- uses_globals = 0;
- dynamic_stack = 0;
- large_stack = 0;
- vrsave_register = -1;
- dynamic_align_stack = 0;
- compressing_data_area = 0;
- align_instr1 = NULL;
- align_instr2 = NULL;
- setup_caller_sp = NULL;
- dummyvaparam = NULL;
- loadvrsave = NULL;
- storevrsave = NULL;
- local_data_size = 0;
- local_data_limit = 0x2000;
- large_data_near_size = 0;
- large_data_far_size = 0;
- frame_size_estimate = 0;
- in_parameter_size = 0;
- parameter_area_size = 0;
- parameter_area_size_estimate = 0;
- frame_alignment = 8;
- out_param_alignment = 8;
- in_param_alignment = 8;
- alloca_alignment = 0;
- has_varargs = 0;
- linkage_area_size = 0;
- frame_size = 0;
- genuine_frame_size = 0;
- nonvolatile_save_size = -1;
- VRSAVE_save_offset = -1;
- LR_save_offset = -1;
-
- for (rclass = 0; rclass < RegClassMax; rclass++)
- non_volatile_save_offset[rclass] = -1;
-
- dummyprofiler = NULL;
- dummyvaparam = NULL;
- dummylocal = NULL;
-
- for (oclass = 0; oclass < ObjClassMax; oclass++) {
- local_objects[oclass] = NULL;
- local_objects_tail[oclass] = NULL;
- }
-}
-
-void init_frame_sizes(Boolean has_varargs) {
- ObjectList *scan;
- Object *obj;
- SInt32 r30;
- SInt32 align;
- SInt32 mask;
-
- r30 = in_parameter_size + parameter_area_size_estimate;
- frame_size_estimate = r30 + 2484;
- for (scan = locals; scan; scan = scan->next) {
- obj = scan->object;
- {
- align = CMach_AllocationAlignment(obj->type, obj->qual) - 1;
- mask = ~align;
- }
- frame_size_estimate = (frame_size_estimate + align) & mask;
- frame_size_estimate += obj->type->size;
- }
-
- if (frame_size_estimate > 0x8000) {
- dynamic_stack = 1;
- large_stack = 1;
- requires_frame = 1;
- }
-
- local_data_limit = 0x8000 - (r30 + 2484);
-
- if (dynamic_stack) {
- requires_frame = 1;
- dummylocal = galloc(sizeof(Object));
- memclrw(dummylocal, sizeof(Object));
- dummylocal->type = (Type *) &stvoid;
- dummylocal->otype = OT_OBJECT;
- dummylocal->name = GetHashNameNode("<dummy>");
- dummylocal->datatype = DLOCAL;
- dummylocal->u.var.info = CodeGen_GetNewVarInfo();
- dummylocal->u.var.info->flags |= VarInfoFlag80;
- dummylocal->u.var.info->noregister = 1;
- }
-
- if (dynamic_stack) {
- retain_register(NULL, RegClass_GPR, 31);
- _FP_ = 31;
- } else {
- _FP_ = 1;
- }
-}
-
-void assign_local_memory(Object *obj) {
- // some misassigned registers x.x
- short align;
- VarInfo *vi;
-
- align = CMach_AllocationAlignment(obj->type, obj->qual);
- if (!compressing_data_area && (obj->u.var.info->flags & VarInfoFlag80))
- return;
-
- update_frame_align(align);
- if (local_data_size + (ALIGN_REMAINDER(local_data_size, align) + ALIGN(obj->type->size, align)) < local_data_limit) {
- local_data_size = ALIGN(local_data_size, align);
- vi = Registers_GetVarInfo(obj);
- vi->flags &= ~VarInfoFlag2;
- vi->flags |= VarInfoFlag80;
- obj->u.var.uid = local_data_size;
- local_data_size += ALIGN(obj->type->size, align);
- insert_local_object(ObjClass0, obj);
- return;
- }
- if (compressing_data_area || obj->type->size <= 32) {
- large_data_near_size = ALIGN(large_data_near_size, align);
- vi = Registers_GetVarInfo(obj);
- vi->flags &= ~VarInfoFlag2;
- vi->flags |= VarInfoFlag80;
- obj->u.var.uid = 0x8000 + large_data_near_size;
- large_data_near_size += ALIGN(obj->type->size, align);
- insert_local_object(ObjClass1, obj);
- } else {
- large_data_far_size = ALIGN(large_data_far_size, align);
- vi = Registers_GetVarInfo(obj);
- vi->flags &= ~VarInfoFlag2;
- vi->flags |= VarInfoFlag80;
- obj->u.var.uid = 0x10000 + large_data_far_size;
- large_data_far_size += ALIGN(obj->type->size, align);
- insert_local_object(ObjClass2, obj);
- }
-}
-
-void assign_locals_to_memory(ObjectList *first) {
- ObjectList *list;
- Object *obj;
- SInt32 i;
-
- for (i = 1; i < 1024; i <<= 1) {
- for (list = first; list; list = list->next) {
- obj = list->object;
- if (Registers_GetVarInfo(obj)->used) {
- if ((Registers_GetVarInfo(obj) ? Registers_GetVarInfo(obj)->reg : 0) == 0) {
- if (obj->type->size <= i)
- assign_local_memory(obj);
- }
- }
- }
- }
-
- for (list = first; list; list = list->next) {
- obj = list->object;
- if (Registers_GetVarInfo(obj)->used) {
- if ((Registers_GetVarInfo(obj) ? Registers_GetVarInfo(obj)->reg : 0) == 0) {
- assign_local_memory(list->object);
- }
- }
-
- if (obj->type && IS_TYPE_ARRAY(obj->type) && IS_TYPE_VECTOR(TYPE_POINTER(obj->type)->target))
- has_altivec_arrays = 1;
- }
-}
-
-void compute_frame_sizes(void) {
- SInt32 altivec_size;
- SInt32 altivec_offset;
-
- CError_ASSERT(897, alloca_alignment == 0 || alloca_alignment == frame_alignment);
-
- update_asm_nonvolatile_registers();
- LR_save_offset = 8;
- non_volatile_save_offset[RegClass_FPR] = -(used_nonvolatile_registers[RegClass_FPR] * 8);
- non_volatile_save_offset[RegClass_GPR] = -(((15 - non_volatile_save_offset[RegClass_FPR]) & ~15) + used_nonvolatile_registers[RegClass_GPR] * 4);
- nonvolatile_save_size = -non_volatile_save_offset[RegClass_GPR];
- non_volatile_save_offset[RegClass_CRFIELD] = 4;
- VRSAVE_save_offset = -1;
- non_volatile_save_offset[RegClass_VR] = -1;
-
- if (copts.altivec_model) {
- if (vrsave_mask) {
- VRSAVE_save_offset = non_volatile_save_offset[RegClass_GPR] - 4;
- nonvolatile_save_size = nonvolatile_save_size + 4;
- }
- altivec_size = used_nonvolatile_registers[RegClass_VR] * 16;
- if (altivec_size > 0)
- nonvolatile_save_size = ALIGN(nonvolatile_save_size + altivec_size, frame_alignment);
- }
-
- if (parameter_area_size)
- requires_frame = 1;
-
- compress_data_area();
- local_data_size = ALIGN(local_data_size, frame_alignment);
- nonvolatile_save_size = ALIGN(nonvolatile_save_size, frame_alignment);
- if (!requires_frame && (local_data_size + nonvolatile_save_size) <= 224) {
- CError_ASSERT(1005, !dynamic_align_stack);
- linkage_area_size = 0;
- frame_size = 0;
- genuine_frame_size = local_data_size + nonvolatile_save_size;
- } else {
- requires_frame = 1;
- if (parameter_area_size < 32)
- parameter_area_size = 32;
- parameter_area_size = ALIGN(parameter_area_size + 24, frame_alignment) - 24;
- if (large_stack) {
- CError_ASSERT(1019, !large_data_far_size);
- large_data_near_size += parameter_area_size;
- parameter_area_size = 0;
- }
- linkage_area_size = 24;
- frame_size = nonvolatile_save_size + (altivec_offset = parameter_area_size + 24 + local_data_size);
- if (copts.altivec_model && used_nonvolatile_registers[RegClass_VR])
- non_volatile_save_offset[RegClass_VR] = altivec_offset;
- frame_size += ALIGN_REMAINDER(frame_size, 16);
- frame_size = ALIGN(frame_size, frame_alignment);
- genuine_frame_size = frame_size;
- }
- if (!large_stack && frame_size > 0x7FFF)
- CError_ErrorTerm(CErrorStr210);
-}
-
-static void allocate_new_frame(int reg1, int reg2) {
- if (dynamic_align_stack) {
- CError_ASSERT(1116, reg1 != _CALLER_SP_);
- emitpcode(PC_RLWINM, reg1, 1, 0, align_bits(frame_alignment, 1), 31);
- if (frame_size > 0x7FFF) {
- CError_FATAL(1122);
- return;
- }
-
- if (frame_size)
- emitpcode(PC_SUBFIC, reg1, reg1, -frame_size);
- else
- emitpcode(PC_SUBFIC, reg1, reg1, -genuine_frame_size);
-
- if (reg2)
- emitpcode(PC_MR, reg2, 1);
-
- emitpcode(PC_STWUX, 1, 1, reg1);
- } else {
- if (frame_size > 0x7FFF)
- CError_FATAL(1153);
- else
- emitpcode(PC_STWU, 1, 1, 0, -frame_size);
-
- if (reg2)
- emitpcode(PC_MR, reg2, 1);
- }
-}
-
-void generate_prologue(PCodeBlock *block, Boolean has_varargs) {
- PCodeBlock *save_block;
- Boolean needs_lr;
- Statement *save_statement;
- Statement stmt;
- UInt32 vrsave_low;
- UInt32 vrsave_high;
-
- save_block = pclastblock;
- needs_lr = need_link_register();
- save_statement = current_statement;
- stmt.sourceoffset = functionbodyoffset;
- current_statement = &stmt;
- pclastblock = block;
-
- if (setup_caller_sp && setup_caller_sp->block) {
- if (
- setup_caller_sp->op == PC_MR &&
- setup_caller_sp->args[1].kind == PCOp_REGISTER &&
- setup_caller_sp->args[1].arg == RegClass_GPR &&
- setup_caller_sp->args[1].data.reg.reg == _FP_
- )
- CError_FATAL(1197);
-
- _CALLER_SP_ = setup_caller_sp->args[0].data.reg.reg;
- deletepcode(setup_caller_sp);
- setup_caller_sp = NULL;
- } else if (_CALLER_SP_ != _FP_) {
- _CALLER_SP_ = -1;
- }
-
- if (align_instr1 && align_instr1->block) {
- deletepcode(align_instr1);
- align_instr1 = NULL;
- }
-
- if (align_instr2 && align_instr2->block) {
- deletepcode(align_instr2);
- align_instr2 = NULL;
- }
-
- if (loadvrsave && loadvrsave->block) {
- deletepcode(loadvrsave);
- loadvrsave = NULL;
- }
-
- if (storevrsave && storevrsave->block) {
- deletepcode(storevrsave);
- storevrsave = NULL;
- }
-
- if (needs_lr)
- emitpcode(PC_MFLR, 0);
-
- if (used_nonvolatile_registers[RegClass_CRFIELD]) {
- emitpcode(PC_MFCR, 12);
- emitpcode(PC_STW, 12, 1, 0, non_volatile_save_offset[RegClass_CRFIELD]);
- }
-
- if (used_nonvolatile_registers[RegClass_FPR])
- save_nonvolatile_FPRs(1, 0);
- if (used_nonvolatile_registers[RegClass_GPR])
- save_nonvolatile_GPRs(1, 0);
- if (needs_lr)
- emitpcode(PC_STW, 0, 1, 0, 8);
-
- if (frame_size) {
- if (vrsave_mask) {
- emitpcode(PC_MFSPR, 0, 256);
- emitpcode(PC_STW, 0, 1, 0, VRSAVE_save_offset);
- vrsave_register = 0;
- }
- allocate_new_frame(12, (_CALLER_SP_ > 0 && _CALLER_SP_ != _FP_) ? _CALLER_SP_ : 0);
- } else {
- CError_ASSERT(1326, !dynamic_align_stack);
- if (vrsave_mask)
- emitpcode(PC_MFSPR, vrsave_register, 256);
- }
-
- if (vrsave_mask) {
- vrsave_high = vrsave_mask >> 16;
- vrsave_low = vrsave_mask & 0xFFFF;
- if (vrsave_mask == 0xFFFFFFFF) {
- emitpcode(PC_LI, 0, -1);
- } else {
- if (vrsave_high)
- emitpcode(PC_ORIS, 0, vrsave_register, vrsave_high);
- if (vrsave_low)
- emitpcode(PC_ORI, 0, 0, vrsave_low);
- }
- emitpcode(PC_MTSPR, 256, 0);
- }
-
- if (used_nonvolatile_registers[RegClass_VR])
- save_nonvolatile_VRs(1, 0);
-
- if (dynamic_stack)
- emitpcode(PC_MR, 31, 1);
-
- if (large_stack)
- do_allocate_dynamic_stack_space(1, 11, 0, large_data_near_size);
-
- block->flags |= fIsProlog;
- pclastblock = save_block;
- current_statement = save_statement;
-}
-
-void generate_epilogue(PCodeBlock *block, Boolean add_blr) {
- PCodeBlock *save_block;
- Boolean needs_lr;
- Statement *save_statement;
- Statement stmt;
-
- save_block = pclastblock;
- needs_lr = need_link_register();
- save_statement = current_statement;
- if (!save_statement) {
- stmt.sourceoffset = current_linenumber;
- current_statement = &stmt;
- }
- pclastblock = block;
-
- if (used_nonvolatile_registers[RegClass_VR])
- restore_nonvolatile_VRs(_FP_, 0);
-
- if (dynamic_align_stack) {
- load_store_register(PC_LWZ, 1, 1, NULL, 0);
- setpcodeflags(fSideEffects);
- if (needs_lr)
- load_store_register(PC_LWZ, 0, 1, 0, 8);
- } else {
- if (needs_lr)
- load_store_register(PC_LWZ, 0, _FP_, 0, frame_size + 8);
- if (frame_size > 0) {
- if (dynamic_stack) {
- load_store_register(PC_LWZ, 1, 1, 0, 0);
- setpcodeflags(fSideEffects);
- } else {
- emitpcode(PC_ADDI, 1, 1, 0, frame_size);
- setpcodeflags(fSideEffects);
- }
- }
- }
-
- if (used_nonvolatile_registers[RegClass_CRFIELD]) {
- load_store_register(PC_LWZ, 12, 1, NULL, non_volatile_save_offset[RegClass_CRFIELD]);
- emitpcode(PC_MTCRF, 255, 12);
- }
-
- if (vrsave_mask) {
- if (!requires_frame) {
- emitpcode(PC_MTSPR, 256, vrsave_register);
- } else {
- emitpcode(PC_LWZ, 11, 1, 0, VRSAVE_save_offset);
- emitpcode(PC_MTSPR, 256, 11);
- }
- }
-
- if (used_nonvolatile_registers[RegClass_FPR])
- restore_nonvolatile_FPRs(1, 0);
- if (needs_lr && !use_helper_function(RegClass_GPR))
- emitpcode(PC_MTLR, 0);
-
- if (used_nonvolatile_registers[RegClass_GPR])
- restore_nonvolatile_GPRs(1, 0);
- if (needs_lr && use_helper_function(RegClass_GPR))
- emitpcode(PC_MTLR, 0);
-
- if (add_blr) {
- emitpcode(PC_BLR);
- setpcodeflags(fIsVolatile);
- }
-
- block->flags |= fIsEpilogue;
- pclastblock = save_block;
- current_statement = save_statement;
-}
-
-static void load_base_offset(int dest_reg, int base_reg, SInt32 offset) {
- if (offset)
- emitpcode(PC_ADDI, dest_reg, base_reg, 0, offset);
- else
- emitpcode(PC_MR, dest_reg, base_reg);
-}
-
-static void save_nonvolatile_FPRs(int reg, SInt32 offset) {
- short i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_FPR];
-
- if (!use_helper_function(RegClass_FPR)) {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_FPR]; i++) {
- emitpcode(PC_STFD, 32 - i, reg, NULL, o + (used_nonvolatile_registers[RegClass_FPR] - i) * 8);
- setpcodeflags(fIsVolatile);
- }
- } else {
- load_base_offset(11, reg, o + used_nonvolatile_registers[RegClass_FPR] * 8);
- call_helper_function("__save_fpr_%d", RegClass_FPR, EffectRead);
- }
-}
-
-static void save_nonvolatile_VRs(int reg, SInt32 offset) {
- short i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_VR];
-
- if (!use_helper_function(RegClass_VR)) {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_VR]; i++) {
- emitpcode(PC_LI, 0, o + (used_nonvolatile_registers[RegClass_VR] - i) * 16);
- emitpcode(PC_STVX, 32 - i, reg, 0);
- setpcodeflags(fIsVolatile);
- }
- } else {
- load_base_offset(0, reg, o + used_nonvolatile_registers[RegClass_VR] * 16);
- call_helper_function("__savev%d", RegClass_VR, EffectRead);
- }
-}
-
-static void restore_nonvolatile_FPRs(int reg, SInt32 offset) {
- short i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_FPR];
-
- if (!use_helper_function(RegClass_FPR)) {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_FPR]; i++) {
- load_store_register(PC_LFD, 32 - i, reg, NULL, o + (used_nonvolatile_registers[RegClass_FPR] - i) * 8);
- setpcodeflags(fIsVolatile);
- }
- } else {
- load_base_offset(11, reg, o + used_nonvolatile_registers[RegClass_FPR] * 8);
- call_helper_function("__restore_fpr_%d", RegClass_FPR, EffectWrite);
- }
-}
-
-static void restore_nonvolatile_VRs(int reg, SInt32 offset) {
- short i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_VR];
-
- if (!use_helper_function(RegClass_VR)) {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_VR]; i++) {
- emitpcode(PC_LI, 0, o + (used_nonvolatile_registers[RegClass_VR] - i) * 16);
- setpcodeflags(fIsVolatile);
- emitpcode(PC_LVX, 32 - i, reg, 0);
- setpcodeflags(fIsVolatile);
- }
- } else {
- load_base_offset(0, reg, o + used_nonvolatile_registers[RegClass_VR] * 16);
- call_helper_function("__restv%d", RegClass_VR, EffectWrite);
- }
-}
-
-static void save_nonvolatile_GPRs(int reg, SInt32 offset) {
- int i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_GPR];
-
- if (!use_helper_function(RegClass_GPR)) {
- if (copts.use_lmw_stmw && ((used_nonvolatile_registers[RegClass_GPR] > 4) || (copts.optimizesize && (used_nonvolatile_registers[RegClass_GPR] > 1)))) {
- emitpcode(PC_STMW, used_nonvolatile_registers[RegClass_GPR] - 1, 32 - used_nonvolatile_registers[RegClass_GPR], reg, 0, o);
- } else {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_GPR]; i++) {
- emitpcode(PC_STW, 32 - i, reg, 0, o + (used_nonvolatile_registers[RegClass_GPR] - i) * 4);
- }
- }
- } else {
- load_base_offset(11, reg, o + used_nonvolatile_registers[RegClass_GPR] * 4);
- call_helper_function("__savegpr_%d", RegClass_GPR, EffectRead);
- }
-}
-
-static void restore_nonvolatile_GPRs(int reg, SInt32 offset) {
- int i;
- SInt32 o;
-
- o = offset + non_volatile_save_offset[RegClass_GPR];
-
- if (!use_helper_function(RegClass_GPR)) {
- if (copts.use_lmw_stmw && ((used_nonvolatile_registers[RegClass_GPR] > 4) || (copts.optimizesize && (used_nonvolatile_registers[RegClass_GPR] > 1)))) {
- emitpcode(PC_LMW, used_nonvolatile_registers[RegClass_GPR] - 1, 32 - used_nonvolatile_registers[RegClass_GPR], reg, 0, o);
- setpcodeflags(fIsVolatile);
- } else {
- for (i = 1; i <= used_nonvolatile_registers[RegClass_GPR]; i++) {
- emitpcode(PC_LWZ, 32 - i, reg, 0, o + (used_nonvolatile_registers[RegClass_GPR] - i) * 4);
- setpcodeflags(fIsVolatile);
- }
- }
- } else {
- load_base_offset(11, reg, o + used_nonvolatile_registers[RegClass_GPR] * 4);
- call_helper_function("__restgpr_%d", RegClass_GPR, EffectWrite);
- }
-}
-
-static void do_allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size) {
- load_store_register(PC_LWZ, reg2, 1, NULL, 0);
- if (isConstantSize) {
- size = ALIGN(size, frame_alignment);
- if (size < 0x8000) {
- emitpcode(PC_STWU, reg2, 1, 0, -size);
- } else {
- emitpcode(PC_LIS, reg1, 0, (short) HIGH_PART(-size));
- if (-size)
- emitpcode(PC_ADDI, reg1, reg1, 0, LOW_PART(-size));
- emitpcode(PC_STWUX, reg2, 1, reg1);
- setpcodeflags(fIsVolatile | fSideEffects);
- }
- } else {
- emitpcode(PC_STWUX, reg2, 1, reg1);
- setpcodeflags(fIsVolatile | fSideEffects);
- }
-}
-
-void allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size) {
- if (copts.altivec_model)
- update_frame_align(16);
- do_allocate_dynamic_stack_space(isConstantSize, reg1, reg2, size);
- add_immediate(reg1, 1, dummylocal, 0);
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct Traceback {
- UInt8 x0;
- UInt8 x1;
- UInt8 x2;
- UInt8 x3;
- UInt8 x4;
- UInt8 x5;
-
- UInt8 x6_0 : 2;
- UInt8 x6_1 : 1; // set to 1
- UInt8 x6_2 : 5;
-
- UInt8 x7_0 : 1;
- UInt8 x7_1 : 1; // set to 1
- UInt8 has_dynamic_stack : 1; // set to 1 if dynamic_stack
- UInt8 x7_3 : 3;
- UInt8 uses_CRs : 1; // set to 1 if CRs used
- UInt8 needs_link_register : 1; // set to 1 if link register used
-
- UInt8 has_frame_size : 1; // set to 1 if frame_size is nonzero
- UInt8 x8_1 : 1; // set to 0
- UInt8 used_FPRs : 6; // stores non-volatile FPRs used
-
- UInt8 x9_0 : 1; // set to 0
- UInt8 x9_1 : 1; // set to 1 if VRs or vrsave used
- UInt8 used_GPRs : 6; // stores non-volatile GPRs used
-
- UInt8 xA;
- UInt8 xB;
-
- SInt32 funcsize;
- SInt16 namelen;
- char name[0];
-} Traceback;
-
-typedef struct TracebackExtra {
- UInt8 used_VRs : 6;
- UInt8 has_vrsave_mask : 1;
- UInt8 is_varargs : 1;
- UInt8 vec_arg_count : 7;
- UInt8 has_vrsave_mask_or_used_VRs : 1;
-} TracebackExtra;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-char *generate_traceback(SInt32 funcsize, char *funcname, SInt32 *tbsize, Object *func) {
- char *work;
- short namelen;
- Traceback *buf;
- SInt32 bufsize;
-
- namelen = strlen(funcname);
- bufsize = ALIGN(sizeof(Traceback) + namelen + (dynamic_stack ? 1 : 0) + ((used_nonvolatile_registers[RegClass_VR] || vrsave_mask) ? sizeof(TracebackExtra) : 0), 4);
- buf = lalloc(bufsize);
- memclrw(buf, bufsize);
-
- buf->x4 = 0;
- buf->x5 = copts.cplusplus ? 9 : 0;
- buf->x6_1 = 1;
- buf->x7_1 = 1;
- if (dynamic_stack)
- buf->has_dynamic_stack = 1;
- if (used_nonvolatile_registers[RegClass_CRFIELD])
- buf->uses_CRs = 1;
- if (need_link_register())
- buf->needs_link_register = 1;
- if (frame_size)
- buf->has_frame_size = 1;
- buf->used_FPRs = used_nonvolatile_registers[RegClass_FPR];
- buf->used_GPRs = used_nonvolatile_registers[RegClass_GPR];
- buf->x8_1 = 0;
- buf->x9_0 = 0;
- buf->x9_1 = (used_nonvolatile_registers[RegClass_VR] || vrsave_mask) != 0;
- buf->funcsize = funcsize;
- buf->namelen = namelen;
-
- work = buf->name;
- strcpy(work, funcname);
- work += namelen;
- if (dynamic_stack) {
- *(work++) = 31;
- }
-
- if (vrsave_mask || used_nonvolatile_registers[RegClass_VR]) {
- TracebackExtra *extra;
- Boolean is_varargs;
- int vec_count;
- FuncArg *args, *scan;
- Type *type;
-
- extra = (TracebackExtra *) work;
- vec_count = 0;
- args = TYPE_FUNC(func->type)->args;
- scan = args;
- while (scan && scan != &elipsis)
- scan = scan->next;
- is_varargs = scan == &elipsis;
- while (args) {
- if ((type = args->type) && IS_TYPE_VECTOR(type))
- vec_count++;
- args = args->next;
- }
- extra->used_VRs = used_nonvolatile_registers[RegClass_VR];
- extra->has_vrsave_mask = vrsave_mask != 0;
- extra->is_varargs = is_varargs;
- extra->vec_arg_count = vec_count;
- extra->has_vrsave_mask_or_used_VRs = vrsave_mask || used_nonvolatile_registers[RegClass_VR];
- }
-
- *tbsize = bufsize;
- return (char *) buf;
-}
-
-static SInt32 localsbase(void) {
- SInt32 size = parameter_area_size;
- if (frame_size || dynamic_align_stack)
- size += linkage_area_size;
- else
- size -= genuine_frame_size;
- return size;
-}
-
-static SInt32 parametersbase(int flag) {
- if (flag)
- return 24;
-
- return frame_size ? (genuine_frame_size + 24) : 24;
-}
-
-void check_dynamic_aligned_frame(void) {
- PCode *pc;
-
- if (used_nonvolatile_registers[RegClass_VR]) {
- update_frame_align(16);
- requires_frame = 1;
- }
-
- if (frame_alignment > in_param_alignment) {
- dynamic_align_stack = 1;
- requires_frame = 1;
- CError_ASSERT(2091, !has_varargs || _CALLER_SP_ != -1);
- CError_ASSERT(2096, _CALLER_SP_ != _FP_);
- if (setup_caller_sp && setup_caller_sp->block) {
- align_instr1 = makepcode(PC_RLWINM, 12, 1, 0, 5, 31);
- insertpcodebefore(setup_caller_sp, align_instr1);
- align_instr2 = makepcode(PC_STWUX, 1, 1, 12);
- insertpcodeafter(setup_caller_sp, align_instr2);
- }
- } else {
- dynamic_align_stack = 0;
- if (setup_caller_sp && setup_caller_sp->block) {
- pc = makepcode(PC_MR, _CALLER_SP_, _FP_);
- insertpcodebefore(setup_caller_sp, pc);
- deletepcode(setup_caller_sp);
- setup_caller_sp = pc;
- }
- _CALLER_SP_ = _FP_;
- }
-
- vrsave_mask = 0;
- if (copts.altivec_model) {
- vrsave_mask = colored_vrs_as_vrsave(pcbasicblocks);
- if (!requires_frame && vrsave_mask) {
- vrsave_register = 11;
- loadvrsave = makepcode(PC_LWZ, 11, 1, 0, -4);
- appendpcode(prologue, loadvrsave);
- storevrsave = makepcode(PC_STW, 11, 1, 0, -4);
- appendpcode(epilogue, storevrsave);
- }
- }
-}
-
-void move_varargs_to_memory(void) {
- short reg;
-
- has_varargs = 1;
- dummyvaparam = galloc(sizeof(Object));
- memclrw(dummyvaparam, sizeof(Object));
-
- dummyvaparam->type = TYPE(&stvoid);
- dummyvaparam->otype = OT_OBJECT;
- dummyvaparam->name = GetHashNameNode("<vaparam>");
- dummyvaparam->datatype = DLOCAL;
- dummyvaparam->u.var.info = CodeGen_GetNewVarInfo();
- dummyvaparam->u.var.uid = 0;
- dummyvaparam->u.var.info->noregister = 1;
- Registers_GetVarInfo(dummyvaparam)->flags = (Registers_GetVarInfo(dummyvaparam)->flags & ~VarInfoFlag1) | VarInfoFlag1;
-
- for (reg = last_argument_register[RegClass_GPR] + 1; (int)reg <= 10; reg++) {
- emitpcode(PC_STW, reg, local_base_register(dummyvaparam), dummyvaparam, (reg - 3) * 4);
- setpcodeflags(fIsPtrOp | fIsArgInit);
- }
-}
-
-void assign_arguments_to_memory(Object *func, UInt8 mysteryFlag, Boolean hasVarargs) {
- // almost matches except for the not/andc issue
- SInt32 pos;
- ObjectList *list;
- Object *obj;
- Type *type;
- short reg;
- SInt32 chk;
- Boolean flag;
-
- pos = 0;
- reg = 2;
-
- for (list = arguments; list; list = list->next) {
- obj = list->object;
- type = obj->type;
- if (!IS_TYPE_VECTOR(type)) {
- obj->datatype = DLOCAL;
- obj->u.var.info = CodeGen_GetNewVarInfo();
- if (IS_TYPE_ARRAY(type) || IS_TYPE_NONVECTOR_STRUCT(type) || IS_TYPE_CLASS(type) ||
- IS_TYPE_12BYTES_MEMBERPOINTER(type)) {
- chk = CMach_ArgumentAlignment(type);
- if (chk > 4) {
- pos = ALIGN(pos, chk);
- update_in_param_align(chk);
- }
- }
- obj->u.var.uid = pos;
- Registers_GetVarInfo(obj)->flags = (Registers_GetVarInfo(obj)->flags & ~VarInfoFlag1) | VarInfoFlag1;
- if (!copts.littleendian && (IS_TYPE_INT(obj->type) || IS_TYPE_ENUM(obj->type)) && obj->type->size < 4)
- obj->u.var.uid += 4 - obj->type->size;
- pos += type->size;
- pos = ALIGN(pos, 4);
- } else {
- obj->u.var.info = CodeGen_GetNewVarInfo();
- obj->u.var.uid = 0;
- obj->datatype = DLOCAL;
- flag = 1;
- if (reg <= 13)
- flag = hasVarargs;
- if (flag) {
- pos = ALIGN(pos + 24, 16) - 24;
- obj->u.var.uid = pos;
- pos += 16;
- update_in_param_align(16);
- Registers_GetVarInfo(obj)->flags = (Registers_GetVarInfo(obj)->flags & ~VarInfoFlag1) | VarInfoFlag1;
- } else {
- assign_local_memory(obj);
- Registers_GetVarInfo(obj)->flags = Registers_GetVarInfo(obj)->flags & ~VarInfoFlag1;
- }
- reg++;
- }
- }
-
- in_parameter_size = (in_parameter_size < pos) ? pos : in_parameter_size;
- CError_ASSERT(2408, !dummyvaparam);
-}
-
-SInt32 set_out_param_displ(SInt32 a, Type *type, Boolean flag, SInt32 *outvar, SInt32 b) {
- // does not match due to errant andc
- SInt32 argAlign;
-
- if (!flag && !b) {
- *outvar = 0;
- return a;
- }
-
- if (IS_TYPE_VECTOR(type)) {
- update_out_param_align(16);
- a = ALIGN(a + 16 + 24, 16) - 24;
- } else if (IS_TYPE_ARRAY(type) || IS_TYPE_NONVECTOR_STRUCT(type) || IS_TYPE_CLASS(type) || IS_TYPE_12BYTES_MEMBERPOINTER(type)) {
- argAlign = CMach_ArgumentAlignment(type);
- if (argAlign > 4) {
- a = ALIGN(a + 24, argAlign) - 24;
- update_in_param_align(argAlign);
- }
- }
-
- *outvar = a;
- a = ALIGN(a + b, 4);
- return a;
-}
-
-SInt32 out_param_displ_to_offset(SInt32 displ) {
- return displ + 24;
-}
-
-Boolean needs_frame(void) {
- return (frame_size > 224) || requires_frame;
-}
-
-void update_out_param_size(SInt32 size) {
- if (size < 32)
- size = 32;
- if (parameter_area_size < size)
- parameter_area_size = size;
-}
-
-void estimate_out_param_size(SInt32 size) {
- if (parameter_area_size_estimate < size)
- parameter_area_size_estimate = size;
-}
-
-void update_out_param_align(SInt32 align) {
- if (out_param_alignment < align)
- out_param_alignment = align;
- update_frame_align(align);
-}
-
-void update_in_param_align(SInt32 align) {
- if (in_param_alignment < align)
- in_param_alignment = align;
-}
-
-void update_frame_align(SInt32 align) {
- if (frame_alignment < align)
- frame_alignment = align;
-}
-
-SInt32 local_offset_32(Object *obj) {
- short align;
- SInt32 offset;
-
- if (obj->u.var.info->flags & VarInfoFlag1)
- align = CMach_ArgumentAlignment(obj->type);
- else
- align = CMach_AllocationAlignment(obj->type, obj->qual);
-
- offset = obj->u.var.uid;
- if (offset > 0x7FFF)
- offset = 0x8000 - offset - ALIGN(obj->type->size, align);
-
- if (obj->u.var.info->flags & VarInfoFlag1)
- return offset + parametersbase(local_base_register(obj) != _FP_);
- else
- return offset + localsbase();
-}
-
-SInt32 local_offset_lo(Object *obj, SInt32 offset) {
- SInt32 combo = offset + local_offset_32(obj);
- return LOW_PART(combo);
- //return (SInt16) (offset + local_offset_32(obj));
-}
-
-SInt32 local_offset_ha(Object *obj, SInt32 offset) {
- SInt32 combo = offset + local_offset_32(obj);
- return HIGH_PART(combo);
- //return (SInt16) ((combo >> 16) + ((combo & 0x8000) >> 15));
-}
-
-SInt32 local_offset_16(Object *obj) {
- SInt32 offset32 = local_offset_32(obj);
- SInt16 offset16 = (SInt16) offset32;
- CError_ASSERT(2662, offset32 == offset16);
- return offset16;
-}
-
-Boolean local_is_16bit_offset(Object *obj) {
- SInt32 offset32 = local_offset_32(obj);
- SInt16 offset16 = (SInt16) offset32;
- return offset32 == offset16;
-}
-
-int local_base_register(Object *obj) {
- PCode *pc;
-
- if (obj->u.var.info->flags & VarInfoFlag1) {
- if (coloring && _CALLER_SP_ == -1) {
- _CALLER_SP_ = used_virtual_registers[RegClass_GPR]++;
- pc = makepcode(PC_LWZ, _CALLER_SP_, 1, 0, 0);
- setup_caller_sp = pc;
- appendpcode(prologue, pc);
- }
- return _CALLER_SP_;
- } else {
- return _FP_;
- }
-}
-
-static UInt32 align_bits(UInt32 value, UInt8 bitcount) {
- UInt32 base = bitcount != 0;
- switch (value) {
- case 0x0002: return base + 30;
- case 0x0004: return base + 29;
- case 0x0008: return base + 28;
- case 0x0010: return base + 27;
- case 0x0020: return base + 26;
- case 0x0040: return base + 25;
- case 0x0080: return base + 24;
- case 0x0100: return base + 23;
- case 0x0200: return base + 22;
- case 0x0400: return base + 21;
- case 0x0800: return base + 20;
- case 0x1000: return base + 19;
- case 0x2000: return base + 18;
- default:
- CError_FATAL(2754);
- return base + 27;
- }
-}
-
-Boolean is_large_frame(void) {
- CError_ASSERT(2769, frame_size != -1);
- return large_stack;
-}
-
-void no_frame_for_asm(void) {
- frame_size = 0;
-}
-
-Boolean can_add_displ_to_local(Object *obj, SInt32 displ) {
- if (obj->datatype != DLOCAL)
- return 0;
-
- if (local_offset_32(obj) == (short) local_offset_32(obj))
- if ((displ + local_offset_32(obj)) == (short) (displ + local_offset_32(obj)))
- return 1;
-
- return 0;
-}
-
-SInt32 get_alloca_alignment(void) {
- SInt32 align = frame_alignment;
- if (copts.altivec_model)
- align = ALIGN(align, 16);
-
- if (!alloca_alignment)
- alloca_alignment = align;
- else
- CError_ASSERT(2825, alloca_alignment == align);
-
- return align_bits(align, 0);
-}
-
-static Boolean use_helper_function(char rclass) {
- if (copts.no_register_save_helpers)
- return 0;
-
- switch (rclass) {
- case RegClass_GPR:
- if (copts.use_lmw_stmw)
- return 0;
- return (used_nonvolatile_registers[RegClass_GPR] > 4) || (copts.optimizesize && used_nonvolatile_registers[RegClass_GPR] > 2);
- case RegClass_FPR:
- return (used_nonvolatile_registers[RegClass_FPR] > 3) || (copts.optimizesize && used_nonvolatile_registers[RegClass_FPR] > 2);
- case RegClass_VR:
- return (used_nonvolatile_registers[RegClass_VR] > 3) || (copts.optimizesize && used_nonvolatile_registers[RegClass_VR] > 2);
- default:
- CError_FATAL(2862);
- return 0;
- }
-}
-
-static Boolean need_link_register(void) {
- if (copts.codegen_pic && uses_globals)
- return 1;
-
- if (makes_call)
- return 1;
-
- return use_helper_function(RegClass_FPR) || use_helper_function(RegClass_GPR) || use_helper_function(RegClass_VR);
-}
-
-static void call_helper_function(char *name, char rclass, short effect) {
- char str[32];
- Object *func;
- NameSpace *save_scope;
- PCode *pc;
- int extra_args;
- PCodeArg *arg;
- short i;
-
- extra_args = 1;
- if (rclass == RegClass_VR)
- extra_args = 2;
-
- sprintf(str, name, 32 - used_nonvolatile_registers[rclass]);
-
- save_scope = cscope_current;
- cscope_current = cscope_root;
- func = CParser_NewRTFunc(&stvoid, NULL, 2, 0);
- cscope_current = save_scope;
-
- func->name = GetHashNameNodeExport(str);
-
- pc = makepcode(PC_BL, extra_args + used_nonvolatile_registers[rclass], func, 0);
- for (i = 1, arg = &pc->args[1]; i <= used_nonvolatile_registers[rclass]; i++, arg++) {
- arg->kind = PCOp_REGISTER;
- arg->arg = rclass;
- arg->data.reg.reg = n_real_registers[rclass] - i;
- arg->data.reg.effect = effect;
- }
-
- if (rclass == RegClass_VR) {
- arg[1].kind = PCOp_REGISTER;
- arg[1].arg = RegClass_GPR;
- arg[1].data.reg.reg = 12;
- arg[1].data.reg.effect = EffectWrite;
- arg[2].kind = PCOp_REGISTER;
- arg[2].arg = RegClass_GPR;
- arg[2].data.reg.reg = 0;
- arg[2].data.reg.effect = EffectRead;
- } else {
- arg[1].kind = PCOp_REGISTER;
- arg[1].arg = RegClass_GPR;
- arg[1].data.reg.reg = 11;
- arg[1].data.reg.effect = EffectRead;
- }
-
- appendpcode(pclastblock, pc);
- setpcodeflags(fSideEffects);
-}
-
-static SInt32 nearest_power_of_two(SInt32 n) {
- SInt32 power = 1;
- do {
- power <<= 1;
- } while (power && power < n);
-
- CError_ASSERT(2933, power != 0);
- return power;
-}
-
-static void compress_data_area(void) {
- // doesn't quite match
- SInt32 r0;
- SInt32 r7;
- ObjectList *list;
- Object *obj;
- PCodeBlock *block;
- PCode *pc;
- int i;
-
- compressing_data_area = 1;
-
- if (large_stack) {
- r0 = 0;
- } else {
- r0 = parameter_area_size;
- if (r0 < 32)
- r0 = 32;
- }
- r7 = ALIGN(r0 + 24, frame_alignment) - 24;
- local_data_limit = 0x8000 - ALIGN(24 + in_parameter_size + nonvolatile_save_size + r7, frame_alignment);
-
- if (local_objects_tail[ObjClass0]) {
- if (local_objects[ObjClass1]) {
- local_objects_tail[ObjClass0]->next = local_objects[ObjClass1];
- local_objects_tail[ObjClass0] = local_objects_tail[ObjClass1];
- }
- if (local_objects[ObjClass2]) {
- local_objects_tail[ObjClass0]->next = local_objects[ObjClass2];
- local_objects_tail[ObjClass0] = local_objects_tail[ObjClass2];
- }
- } else if (local_objects_tail[ObjClass1]) {
- local_objects[ObjClass0] = local_objects[ObjClass1];
- local_objects_tail[ObjClass0] = local_objects_tail[ObjClass1];
- if (local_objects[ObjClass2]) {
- local_objects_tail[ObjClass0]->next = local_objects[ObjClass2];
- local_objects_tail[ObjClass0] = local_objects_tail[ObjClass2];
- }
- } else {
- local_objects[ObjClass0] = local_objects[ObjClass2];
- local_objects_tail[ObjClass0] = local_objects_tail[ObjClass2];
- }
-
- for (list = local_objects[ObjClass0]; list; list = list->next)
- Registers_GetVarInfo(list->object)->used = 0;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (pc = block->firstPCode; pc; pc = pc->nextPCode) {
- for (i = 0; i < pc->argCount; i++) {
- if (pc->args[i].kind == PCOp_MEMORY && pc->args[i].data.mem.obj && pc->args[i].data.mem.obj->datatype == DLOCAL)
- Registers_GetVarInfo(pc->args[i].data.mem.obj)->used = 1;
- }
- }
- }
-
- local_data_size = 0;
- large_data_near_size = 0;
- large_data_far_size = 0;
-
- for (list = local_objects[ObjClass0]; list; list = list->next) {
- obj = list->object;
- if (Registers_GetVarInfo(obj)->used)
- assign_local_memory(obj);
- }
-}
-
-static void insert_local_object(UInt8 oclass, Object *obj) {
- ObjectList *list;
-
- if (!compressing_data_area) {
- list = lalloc(sizeof(ObjectList));
- memclrw(list, sizeof(ObjectList));
- list->object = obj;
- if (!local_objects[oclass])
- local_objects[oclass] = list;
- if (local_objects_tail[oclass])
- local_objects_tail[oclass]->next = list;
- local_objects_tail[oclass] = list;
- }
-}
diff --git a/compiler_and_linker/unsorted/StrengthReduction.c b/compiler_and_linker/unsorted/StrengthReduction.c
deleted file mode 100644
index 2b68dca..0000000
--- a/compiler_and_linker/unsorted/StrengthReduction.c
+++ /dev/null
@@ -1,751 +0,0 @@
-#include "compiler/StrengthReduction.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/LoopDetection.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/Registers.h"
-#include "compiler/UseDefChains.h"
-
-int strengthreducedloops;
-
-static PCode *findinitializer(Loop *loop, short reg) {
- UInt32 *vec;
- PCode *best;
- RegUseOrDef *list;
-
- vec = usedefinfo[loop->body->blockIndex].defvec8;
- best = NULL;
-
- for (list = reg_Defs[RegClass_GPR][reg]; list; list = list->next) {
- if (
- !(bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)) &&
- bitvectorgetbit(list->id, vec)
- )
- {
- if (best)
- return NULL;
- best = Defs[list->id].pcode;
- }
- }
-
- if (best) {
- if (best->op == PC_LI || best->op == PC_ADDI || best->op == PC_ADD)
- return best;
- }
-
- return NULL;
-}
-
-static int isbasicinductionvariable(Loop *loop, short reg, SInt32 step) {
- RegUseOrDef *list;
- PCode *instr;
-
- for (list = reg_Defs[RegClass_GPR][reg]; list; list = list->next) {
- instr = Defs[list->id].pcode;
- if (bitvectorgetbit(instr->block->blockIndex, loop->memberblocks)) {
- if (instr->op != PC_ADDI)
- return 0;
- if (instr->args[1].data.reg.reg != reg)
- return 0;
- if (instr->args[2].data.imm.value != step)
- return 0;
- }
- }
-
- return 1;
-}
-
-static void addbasicinductionvariable(Loop *loop, short reg, SInt32 step) {
- BasicInductionVar *biv;
- RegUseOrDef *list;
- PCode *instr;
- InstrList *instrList;
-
- for (biv = loop->basicInductionVars; biv; biv = biv->next) {
- if (biv->reg == reg)
- return;
- }
-
- biv = oalloc(sizeof(BasicInductionVar));
- biv->next = loop->basicInductionVars;
- loop->basicInductionVars = biv;
-
- biv->loop = loop;
- biv->inductionVars = NULL;
- biv->instrsC = NULL;
- biv->step = step;
- biv->reg = reg;
-
- for (list = reg_Defs[RegClass_GPR][reg]; list; list = list->next) {
- instr = Defs[list->id].pcode;
- if (bitvectorgetbit(instr->block->blockIndex, loop->memberblocks)) {
- instrList = oalloc(sizeof(InstrList));
- instrList->next = biv->instrsC;
- biv->instrsC = instrList;
- instrList->instr = instr;
- }
- }
-
- biv->initializer = findinitializer(loop, reg);
-}
-
-static void findbasicinductionvariables(Loop *loop) {
- SInt16 step;
- BlockList *block;
- PCode *instr;
- short reg;
-
- for (block = loop->blocks; block; block = block->next) {
- for (instr = block->block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr->op == PC_ADDI) {
- if (
- (reg = instr->args[0].data.reg.reg) >= 32 &&
- instr->args[1].data.reg.reg == reg &&
- isbasicinductionvariable(loop, reg, step = instr->args[2].data.imm.value)
- )
- addbasicinductionvariable(loop, reg, step);
- }
- }
- }
-}
-
-static void findallbasicinductionvariables(Loop *loop) {
- while (loop) {
- if (loop->children)
- findallbasicinductionvariables(loop->children);
- findbasicinductionvariables(loop);
- loop = loop->nextSibling;
- }
-}
-
-static int isinductionvariable(BasicInductionVar *biv, int useID, SInt32 *result1, short *result2, short *result3, Loop **result4) {
- RegUseOrDef *list;
- int counter;
- Loop *loop;
- Loop *scanloop;
- PCode *instr;
-
- instr = Uses[useID].pcode;
- *result2 = 0;
- *result3 = 0;
- *result4 = NULL;
-
- switch (instr->op) {
- case PC_MULLI:
- *result1 = instr->args[2].data.imm.value;
- break;
-
- case PC_RLWINM:
- if (instr->args[3].data.imm.value)
- return 0;
- if (instr->args[2].data.imm.value > 15)
- return 0;
- if (instr->args[4].data.imm.value != (31 - instr->args[2].data.imm.value))
- return 0;
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- return 0;
- *result1 = 1 << instr->args[2].data.imm.value;
- break;
-
- case PC_LBZX:
- case PC_LHZX:
- case PC_LHAX:
- case PC_LWZX:
- case PC_STBX:
- case PC_STHX:
- case PC_STWX:
- case PC_LFSX:
- case PC_LFDX:
- case PC_STFSX:
- case PC_STFDX:
- *result2 = 0;
- *result3 = 0;
- if (instr->args[1].data.reg.reg == biv->reg) {
- *result2 = 1;
- *result3 = 2;
- } else if (instr->args[2].data.reg.reg == biv->reg) {
- *result2 = 2;
- *result3 = 1;
- }
-
- counter = 0;
- for (list = reg_Defs[RegClass_GPR][instr->args[*result3].data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, biv->loop->memberblocks))
- counter++;
- }
- if (counter)
- return 0;
-
- loop = biv->loop;
- for (scanloop = loop->parent; scanloop; scanloop = scanloop->parent) {
- counter = 0;
- for (list = reg_Defs[RegClass_GPR][instr->args[*result3].data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, scanloop->memberblocks))
- counter++;
- }
- if (!biv->initializer || bitvectorgetbit(biv->initializer->block->blockIndex, scanloop->memberblocks))
- counter++;
- if (counter)
- break;
- loop = scanloop;
- }
-
- *result4 = loop;
- *result1 = 1;
- return 1;
-
- default:
- return 0;
- }
-
- counter = 0;
- for (list = reg_Defs[RegClass_GPR][instr->args[0].data.reg.reg]; list; list = list->next) {
- if (bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, biv->loop->memberblocks))
- counter++;
- }
-
- return counter == 1;
-}
-
-static void addinductionvariable(BasicInductionVar *biv, PCode *instr, SInt32 val1, short val2, short val3, Loop *val4) {
- InductionVar *iv;
-
- iv = oalloc(sizeof(InductionVar));
- iv->next = biv->inductionVars;
- biv->inductionVars = iv;
-
- iv->basicVar = biv;
- iv->instr = instr;
- iv->instrC = NULL;
- iv->step = val1;
- iv->x18 = val2;
- iv->x1A = val3;
- iv->someloop = val4;
- if (instr->flags & (fIsRead | fIsWrite))
- iv->x1C = -1;
- else
- iv->x1C = instr->args[0].data.reg.reg;
- iv->x1E = -1;
-}
-
-static void findnonbasicinductionvariables(Loop *loop) {
- BasicInductionVar *biv;
- RegUseOrDef *list;
- SInt32 result1;
- short result2;
- short result3;
- Loop *result4;
-
- for (biv = loop->basicInductionVars; biv; biv = biv->next) {
- for (list = reg_Uses[RegClass_GPR][biv->reg]; list; list = list->next) {
- if (bitvectorgetbit(Uses[list->id].pcode->block->blockIndex, loop->memberblocks)) {
- if (isinductionvariable(biv, list->id, &result1, &result2, &result3, &result4))
- addinductionvariable(biv, Uses[list->id].pcode, result1, result2, result3, result4);
- }
- }
- }
-}
-
-static void findallnonbasicinductionvariables(Loop *loop) {
- while (loop) {
- if (loop->children)
- findallnonbasicinductionvariables(loop->children);
- if (loop->basicInductionVars)
- findnonbasicinductionvariables(loop);
- loop = loop->nextSibling;
- }
-}
-
-static void initializeinductionvariable(InductionVar *iv) {
- BasicInductionVar *biv; // r31
- PCode *instr; // r27
- PCodeBlock *preheader; // r30
- SInt32 value30; // r30
- short reg29; // r29
- short reg26; // r26
-
- biv = iv->basicVar;
- preheader = biv->loop->preheader;
-
- if (iv->x1A) {
- reg29 = iv->instr->args[iv->x1A].data.reg.reg;
- reg26 = iv->instr->args[iv->x18].data.reg.reg;
- instr = NULL;
-
- if (
- biv->initializer &&
- biv->initializer->op == PC_LI &&
- biv->initializer->block == preheader
- )
- {
- if (biv->initializer->args[1].data.imm.value == 0)
- instr = makepcode(PC_MR, iv->x1E, reg29);
- else if (FITS_IN_SHORT(biv->initializer->args[1].data.imm.value))
- instr = makepcode(PC_ADDI, iv->x1E, reg29, 0, biv->initializer->args[1].data.imm.value);
- }
-
- if (!instr)
- instr = makepcode(PC_ADD, iv->x1E, reg29, reg26);
-
- if (biv->initializer && instr->op != PC_ADD)
- insertpcodeafter(biv->initializer, instr);
- else if (iv->someloop && iv->someloop->preheader->lastPCode)
- insertpcodebefore(iv->someloop->preheader->lastPCode, instr);
- else
- insertpcodebefore(preheader->lastPCode, instr);
-
- iv->instrC = instr;
- iv->x1C = reg29;
- return;
- }
-
- if (!biv->initializer || biv->initializer->op != PC_LI) {
- instr = copypcode(iv->instr);
- instr->args[0].data.reg.reg = iv->x1E;
- insertpcodebefore(preheader->lastPCode, instr);
- } else {
- value30 = biv->initializer->args[1].data.imm.value * iv->step;
- if (!FITS_IN_SHORT(value30)) {
- instr = makepcode(PC_LIS, iv->x1E, 0, HIGH_PART(value30));
- insertpcodeafter(biv->initializer, instr);
- if (value30 != 0)
- insertpcodeafter(instr, makepcode(PC_ADDI, iv->x1E, iv->x1E, 0, LOW_PART(value30)));
- } else {
- instr = makepcode(PC_LI, iv->x1E, value30);
- insertpcodeafter(biv->initializer, instr);
- }
- }
-}
-
-static void incrementinductionvariable(InductionVar *iv) {
- SInt32 value;
- BasicInductionVar *biv;
- PCode *instr;
- InstrList *list;
-
- biv = iv->basicVar;
- value = iv->step * biv->step;
- for (list = biv->instrsC; list; list = list->next) {
- if (!FITS_IN_SHORT(value)) {
- instr = makepcode(PC_ADDIS, iv->x1E, iv->x1E, 0, HIGH_PART(value));
- insertpcodeafter(list->instr, instr);
-
- if (value != 0) {
- instr = makepcode(PC_ADDI, iv->x1E, iv->x1E, 0, LOW_PART(value));
- insertpcodeafter(list->instr->nextPCode, instr);
- }
- } else {
- instr = makepcode(PC_ADDI, iv->x1E, iv->x1E, 0, value);
- insertpcodeafter(list->instr, instr);
- }
- }
-}
-
-static void copyinductionvariable(InductionVar *iv) {
- if (iv->instr->flags & (fIsRead | fIsWrite)) {
- iv->instr->op -= 2;
- iv->instr->args[1].data.reg.reg = iv->x1E;
- iv->instr->args[2].kind = PCOp_IMMEDIATE;
- iv->instr->args[2].data.imm.value = 0;
- iv->instr->args[2].data.imm.obj = NULL;
- } else {
- insertpcodeafter(iv->instr, makepcode(PC_MR, iv->x1C, iv->x1E));
- deletepcode(iv->instr);
- }
-}
-
-static int testnestediv(InductionVar *iv, SInt32 step1, int reg, SInt32 step2, Loop *loop1, Loop *loop2) {
- SInt32 addend;
- BlockList *list;
- PCode *instr;
- PCodeArg *op;
- int i;
-
- if (iv->instrC && iv->x1C == reg) {
- if (iv->instrC->op == PC_MR)
- addend = 0;
- else if (iv->instrC->op == PC_ADDI)
- addend = iv->instrC->args[2].data.imm.value;
- else
- return 0;
-
- if (step2 == (addend + (step1 * iv->step * loop2->iterationCount))) {
- for (list = loop1->blocks; list && list->block != loop2->blocks->block; list = list->next) {
- for (instr = list->block->firstPCode; instr; instr = instr->nextPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg == reg
- )
- return 0;
- op++;
- }
- }
- }
- return 1;
- }
- }
-
- return 0;
-}
-
-static void strengthreducenestediv(short reg, SInt32 step, PCode *initializer, Loop *loop) {
- Loop *scanloop;
- BasicInductionVar *biv;
- InductionVar *iv;
- PCode *instr;
- PCodeArg *op;
- int i;
-
- for (scanloop = loop->children; scanloop; scanloop = scanloop->nextSibling) {
- if (
- scanloop->isKnownCountingLoop &&
- scanloop->x4F &&
- bitvectorgetbit(scanloop->body->blockIndex, loop->vec2C)
- )
- {
- for (biv = scanloop->basicInductionVars; biv; biv = biv->next) {
- for (iv = biv->inductionVars; iv; iv = iv->next) {
- if (testnestediv(iv, biv->step, reg, step, loop, scanloop)) {
- deletepcode(iv->instrC);
- if (initializer) {
- insertpcodeafter(initializer, iv->instrC);
- } else if (loop->body->lastPCode) {
- for (instr = loop->body->lastPCode; instr; instr = instr->prevPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite) &&
- op->data.reg.reg == reg
- )
- break;
- op++;
- }
- }
-
- if (instr)
- insertpcodeafter(instr, iv->instrC);
- else
- insertpcodebefore(loop->body->firstPCode, iv->instrC);
- } else {
- appendpcode(loop->body, iv->instrC);
- }
- }
- }
- }
- }
- }
-}
-
-static void strengthreducenestedbiv(BasicInductionVar *biv) {
- Loop *loop;
- InductionVar *iv;
-
- loop = biv->loop;
- for (iv = biv->inductionVars; iv; iv = iv->next)
- strengthreducenestediv(iv->x1E, iv->step * biv->step, iv->instrC, loop);
-
- strengthreducenestediv(biv->reg, biv->step, biv->initializer, loop);
-}
-
-static void strengthreduceinductionvariable(BasicInductionVar *biv) {
- int counter;
- InductionVar *iv;
- InductionVar *otherIv;
- short reg;
-
- counter = 0;
- for (iv = biv->inductionVars; iv; iv = iv->next) {
- if (iv->step == 1)
- counter++;
- }
-
- for (iv = biv->inductionVars; iv; iv = iv->next) {
- if (
- (counter <= 4 || iv->step != 1) &&
- iv->instr->block &&
- (iv->x1A == 0 || iv->instr->args[2].kind != PCOp_IMMEDIATE)
- )
- {
- if (iv->x1E == -1) {
- iv->x1E = used_virtual_registers[RegClass_GPR]++;
- initializeinductionvariable(iv);
- incrementinductionvariable(iv);
- if (iv->step == 1) {
- reg = iv->instr->args[iv->x1A].data.reg.reg;
- for (otherIv = iv->next; otherIv; otherIv = otherIv->next) {
- if (otherIv->x1A != 0 && otherIv->instr->args[otherIv->x1A].data.reg.reg == reg)
- otherIv->x1E = iv->x1E;
- }
- } else {
- for (otherIv = iv->next; otherIv; otherIv = otherIv->next) {
- if (otherIv->step == iv->step)
- otherIv->x1E = iv->x1E;
- }
- }
- }
-
- copyinductionvariable(iv);
- strengthreducedloops = 1;
- }
- }
-}
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef struct BivInit {
- SInt32 x0;
- short x4;
- short x6;
- short x8;
- Object *xA;
-} BivInit;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static void calc_biv_init(BasicInductionVar *biv, BivInit *init) {
- PCode *instr;
- PCode *scan;
- PCodeArg *op;
- int i;
-
- instr = biv->initializer;
- init->x0 = 0;
- init->x4 = -1;
- init->x6 = -1;
- init->x8 = 0;
- init->xA = NULL;
-
- if (!biv->initializer || (biv->initializer->op != PC_ADDI && biv->initializer->op != PC_ADD))
- return;
-
- if (instr->op == PC_ADDI) {
- if (instr->args[1].data.reg.reg == biv->reg) {
- init->x0 = instr->args[2].data.imm.value;
- for (scan = instr->prevPCode; scan; scan = scan->prevPCode) {
- op = scan->args;
- i = scan->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg == biv->reg &&
- (op->data.reg.effect & EffectWrite)
- )
- {
- if (scan->op == PC_ADD) {
- init->x4 = scan->args[1].data.reg.reg;
- init->x6 = scan->args[2].data.reg.reg;
- } else if (scan->op == PC_ADDI) {
- if (scan->args[2].kind == PCOp_IMMEDIATE) {
- init->x4 = scan->args[1].data.reg.reg;
- init->x8 = scan->args[2].data.imm.value;
- } else if (scan->args[2].kind == PCOp_MEMORY) {
- init->x4 = scan->args[1].data.reg.reg;
- init->x8 = scan->args[2].data.mem.offset;
- init->xA = scan->args[2].data.mem.obj;
- }
- }
- return;
- }
- op++;
- }
- }
- } else {
- if (instr->args[2].kind == PCOp_IMMEDIATE) {
- init->x4 = instr->args[1].data.reg.reg;
- init->x8 = instr->args[2].data.imm.value;
- } else if (instr->args[2].kind == PCOp_MEMORY) {
- init->x4 = instr->args[1].data.reg.reg;
- init->x8 = instr->args[2].data.mem.offset;
- init->xA = instr->args[2].data.mem.obj;
- }
- }
- } else if (instr->op == PC_ADD) {
- if (instr->args[1].data.reg.reg == biv->reg) {
- init->x6 = instr->args[2].data.reg.reg;
- for (scan = instr->prevPCode; scan; scan = scan->prevPCode) {
- op = scan->args;
- i = scan->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg == biv->reg &&
- (op->data.reg.effect & EffectWrite) &&
- scan->op == PC_ADDI
- )
- {
- if (scan->args[2].kind == PCOp_IMMEDIATE) {
- init->x4 = scan->args[1].data.reg.reg;
- init->x8 = scan->args[2].data.imm.value;
- } else if (scan->args[2].kind == PCOp_MEMORY) {
- init->x4 = scan->args[1].data.reg.reg;
- init->x8 = scan->args[2].data.mem.offset;
- init->xA = scan->args[2].data.mem.obj;
- }
- return;
- }
- op++;
- }
- }
- } else {
- init->x4 = instr->args[1].data.reg.reg;
- init->x6 = instr->args[2].data.reg.reg;
- }
- }
-}
-
-static void combineinductionvariables(Loop *loop, BasicInductionVar *biv1, BasicInductionVar *biv2, SInt32 difference) {
- PCode *instr1; // r31
- int reg1; // r30
- int reg2; // r29
- PCode *instr2; // r24
- PCodeBlock *nextBlock; // r24
- BlockList *list;
- PCodeArg *op;
- int i;
- PCode *instr;
-
- instr1 = NULL;
- instr2 = NULL;
-
- reg1 = biv1->reg;
- CError_ASSERT(930, reg1 >= 0);
-
- reg2 = biv2->reg;
- CError_ASSERT(934, reg2 >= 0);
-
- if (!FITS_IN_SHORT(difference))
- return;
-
- for (list = loop->blocks; list; list = list->next) {
- for (instr = list->block->firstPCode; instr; instr = instr->nextPCode) {
- if (instr1) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- op->data.reg.reg == reg1
- )
- return;
- op++;
- }
- }
-
- if (instr->op == PC_ADDI) {
- if (instr->args[0].data.reg.reg == reg1) {
- if (instr1)
- return;
- instr1 = instr;
- } else if (instr->args[0].data.reg.reg == reg2) {
- if (instr2)
- return;
- instr2 = instr;
- }
- }
- }
- }
-
- if (loop->body->lastPCode->flags & fIsBranch) {
- nextBlock = NULL;
-
- for (i = 0; i < loop->body->lastPCode->argCount; i++) {
- if (loop->body->lastPCode->args[i].kind == PCOp_LABEL) {
- nextBlock = loop->body->lastPCode->args[i].data.label.label->block;
- break;
- }
- }
-
- if (!nextBlock)
- return;
- } else {
- nextBlock = loop->body->nextBlock;
- }
-
- deletepcode(instr1);
- instr1->args[1].data.reg.reg = reg2;
- instr1->args[2].data.imm.value = difference;
-
- if (nextBlock->firstPCode)
- insertpcodebefore(nextBlock->firstPCode, instr1);
- else
- appendpcode(nextBlock, instr1);
-
- biv1->reg = -1;
- strengthreducedloops = 1;
-}
-
-static void strengthreduceinductionvariables(Loop *loop) {
- BasicInductionVar *biv1;
- BasicInductionVar *biv2;
- BivInit init1;
- BivInit init2;
-
- for (biv1 = loop->basicInductionVars; biv1; biv1 = biv1->next) {
- if (biv1->inductionVars)
- strengthreduceinductionvariable(biv1);
- strengthreducenestedbiv(biv1);
- }
-
- for (biv1 = loop->basicInductionVars; biv1; biv1 = biv1->next) {
- if (biv1->reg != -1) {
- calc_biv_init(biv1, &init1);
- if (init1.x4 != -1) {
- for (biv2 = loop->basicInductionVars; biv2; biv2 = biv2->next) {
- if (biv2->reg != -1 && biv2 != biv1) {
- calc_biv_init(biv2, &init2);
- if (
- init2.x4 != -1 &&
- init1.x4 == init2.x4 &&
- init1.x6 == init2.x6 &&
- init1.x8 == init2.x8 &&
- init1.xA == init2.xA &&
- biv1->step == biv2->step
- )
- {
- if (init1.x0 < init2.x0) {
- combineinductionvariables(loop, biv2, biv1, init2.x0 - init1.x0);
- } else {
- combineinductionvariables(loop, biv1, biv2, init1.x0 - init2.x0);
- break;
- }
- }
- }
- }
- }
- }
- }
-}
-
-static void strengthreduceallinductionvariables(Loop *loop) {
- while (loop) {
- if (loop->children)
- strengthreduceallinductionvariables(loop->children);
- if (loop->basicInductionVars)
- strengthreduceinductionvariables(loop);
- loop = loop->nextSibling;
- }
-}
-
-void strengthreduceloops(void) {
- strengthreducedloops = 0;
- if (loopsinflowgraph) {
- computeusedefchains(0);
- findallbasicinductionvariables(loopsinflowgraph);
- findallnonbasicinductionvariables(loopsinflowgraph);
- strengthreduceallinductionvariables(loopsinflowgraph);
- freeoheap();
- }
-}
diff --git a/compiler_and_linker/unsorted/StructMoves.c b/compiler_and_linker/unsorted/StructMoves.c
deleted file mode 100644
index 7c28b88..0000000
--- a/compiler_and_linker/unsorted/StructMoves.c
+++ /dev/null
@@ -1,792 +0,0 @@
-#include "compiler/StructMoves.h"
-#include "compiler/CError.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Registers.h"
-
-void make_addressable(Operand *opnd, SInt32 offset, int unusedArg) {
- int reg;
-
- if (opnd->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(opnd);
-
- if (opnd->optype != OpndType_IndirectGPR_ImmOffset || (opnd->immOffset + offset) > 0x7FFF) {
- reg = used_virtual_registers[RegClass_GPR]++;
- load_address(reg, opnd);
- opnd->optype = OpndType_IndirectGPR_ImmOffset;
- opnd->reg = reg;
- opnd->object = NULL;
- opnd->immOffset = 0;
- }
-}
-
-static void load_displaced_address(Operand *opnd, SInt32 offset) {
- int reg;
-
- reg = used_virtual_registers[RegClass_GPR]++;
- if (opnd->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(opnd);
-
- if (opnd->optype == OpndType_IndirectGPR_ImmOffset) {
- offset += opnd->immOffset;
- if (!FITS_IN_SHORT(offset)) {
- add_immediate(reg, opnd->reg, opnd->object, opnd->immOffset);
- emitpcode(PC_ADDI, reg, reg, 0, offset - opnd->immOffset);
- } else {
- add_immediate(reg, opnd->reg, opnd->object, offset);
- }
- } else if (opnd->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(PC_ADD, reg, opnd->reg, opnd->regOffset);
- emitpcode(PC_ADDI, reg, reg, 0, offset);
- } else {
- CError_FATAL(80);
- }
-
- opnd->optype = OpndType_IndirectGPR_ImmOffset;
- opnd->reg = reg;
- opnd->object = NULL;
- opnd->immOffset = 0;
-}
-
-static void move_block_via_load_store(Operand *dst, Operand *src, SInt32 len, SInt32 align) {
- SInt32 step;
- SInt32 pos;
- int floatReg;
- int reg;
-
- if (src->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(src);
- if (dst->optype == OpndType_IndirectSymbol)
- coerce_to_addressable(dst);
-
- if (len == 8) {
- floatReg = used_virtual_registers[RegClass_FPR]++;
- if (src->optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(PC_LFD, floatReg, src->reg, src->object, src->immOffset);
- setpcodeflags(src->flags);
- } else if (src->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(PC_LFDX, floatReg, src->reg, src->regOffset);
- setpcodeflags(src->flags);
- } else {
- CError_FATAL(145);
- }
-
- if (dst->optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(PC_STFD, floatReg, dst->reg, dst->object, dst->immOffset);
- setpcodeflags(dst->flags);
- } else if (dst->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(PC_STFDX, floatReg, dst->reg, dst->regOffset);
- setpcodeflags(dst->flags);
- } else {
- CError_FATAL(157);
- }
-
- return;
- }
-
- if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) {
- SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align;
- step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2;
- } else {
- step = ((UInt32) len > 4) ? 4 : ((UInt32) len <= 2) ? len : 2;
- }
-
- if (step != len) {
- if (dst->optype == OpndType_IndirectGPR_Indexed)
- make_addressable(dst, len, 0);
- if (src->optype == OpndType_IndirectGPR_Indexed)
- make_addressable(src, len, 0);
- }
-
- for (pos = 0; len != 0; len -= step, pos += step) {
- reg = used_virtual_registers[RegClass_GPR]++;
- if (src->optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg,
- src->reg,
- src->object,
- src->immOffset + pos
- );
- setpcodeflags(src->flags);
- } else if (src->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(
- (step == 1) ? PC_LBZX : (step == 2) ? PC_LHZX : PC_LWZX,
- reg,
- src->reg,
- src->regOffset
- );
- setpcodeflags(src->flags);
- } else {
- CError_FATAL(183);
- }
-
- if (dst->optype == OpndType_IndirectGPR_ImmOffset) {
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg,
- dst->reg,
- dst->object,
- dst->immOffset + pos
- );
- setpcodeflags(dst->flags);
- } else if (dst->optype == OpndType_IndirectGPR_Indexed) {
- emitpcode(
- (step == 1) ? PC_STBX : (step == 2) ? PC_STHX : PC_STWX,
- reg,
- dst->reg,
- dst->regOffset
- );
- setpcodeflags(dst->flags);
- } else {
- CError_FATAL(195);
- }
- }
-}
-
-static void move_block_via_load_store_sequence(Operand *dst, Operand *src, SInt32 len, SInt32 align) {
- SInt32 pos;
- int i;
- SInt32 step;
-
- pos = 0;
- make_addressable(dst, len, 0);
- make_addressable(src, len, 0);
-
- if ((align % 8) == 0) {
- while (len >= 16) {
- int reg1 = used_virtual_registers[RegClass_FPR]++;
- int reg2 = used_virtual_registers[RegClass_FPR]++;
- load_store_register(PC_LFD, reg1, src->reg, src->object, src->immOffset + pos);
- setpcodeflags(src->flags);
- load_store_register(PC_LFD, reg2, src->reg, src->object, src->immOffset + pos + 8);
- setpcodeflags(src->flags);
-
- load_store_register(PC_STFD, reg1, dst->reg, dst->object, dst->immOffset + pos);
- setpcodeflags(dst->flags);
- load_store_register(PC_STFD, reg2, dst->reg, dst->object, dst->immOffset + pos + 8);
- setpcodeflags(dst->flags);
-
- pos += 16;
- len -= 16;
- }
- }
-
- while (len >= 8) {
- if ((align % 8) == 0) {
- int reg = used_virtual_registers[RegClass_FPR]++;
-
- load_store_register(PC_LFD, reg, src->reg, src->object, src->immOffset + pos);
- setpcodeflags(src->flags);
-
- load_store_register(PC_STFD, reg, dst->reg, dst->object, dst->immOffset + pos);
- setpcodeflags(dst->flags);
-
- pos += 8;
- len -= 8;
- } else {
- if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) {
- SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align;
- step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp > 2) ? 2 : 1;
- } else {
- step = 4;
- }
-
- for (i = 0; i < 8; i += (step * 2)) {
- int reg1 = used_virtual_registers[RegClass_GPR]++;
- int reg2 = used_virtual_registers[RegClass_GPR]++;
-
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg1,
- src->reg,
- src->object,
- src->immOffset + pos
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg2,
- src->reg,
- src->object,
- src->immOffset + pos + step
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg1,
- dst->reg,
- dst->object,
- dst->immOffset + pos
- );
- setpcodeflags(dst->flags);
-
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg2,
- dst->reg,
- dst->object,
- dst->immOffset + pos + step
- );
- setpcodeflags(dst->flags);
-
- pos += (step * 2);
- len -= (step * 2);
- }
- }
- }
-
- while (len) {
- int reg;
-
- if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) {
- SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align;
- step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2;
- } else {
- step = ((UInt32) len > 4) ? 4 : ((UInt32) len <= 2) ? len : 2;
- }
-
- reg = used_virtual_registers[RegClass_GPR]++;
-
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg,
- src->reg,
- src->object,
- src->immOffset + pos
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg,
- dst->reg,
- dst->object,
- dst->immOffset + pos
- );
- setpcodeflags(dst->flags);
-
- len -= step;
- pos += step;
- }
-}
-
-static void move_block_via_inline_loop(Operand *dst, Operand *src, SInt32 len, SInt32 align) {
- PCodeLabel *label; // r25
- SInt32 pos; // r25
- SInt32 step; // r24
- int reg1; // r22
- int reg2; // r23
- SInt32 remainder; // r23
-
- label = makepclabel();
-
- if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) {
- SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align;
- step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2;
- } else {
- step = 4;
- }
-
- load_displaced_address(dst, -step);
- load_displaced_address(src, -step);
-
- CError_ASSERT(377, (len / step) != 0);
-
- reg1 = used_virtual_registers[RegClass_GPR]++;
- load_immediate(reg1, len / (step * 2));
- emitpcode(PC_MTCTR, reg1);
- branch_label(label);
-
- reg1 = used_virtual_registers[RegClass_GPR]++;
- reg2 = used_virtual_registers[RegClass_GPR]++;
-
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg1,
- src->reg,
- NULL,
- step
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_LBZU : (step == 2) ? PC_LHZU : PC_LWZU,
- reg2,
- src->reg,
- NULL,
- step * 2
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg1,
- dst->reg,
- NULL,
- step
- );
- setpcodeflags(dst->flags);
-
- load_store_register(
- (step == 1) ? PC_STBU : (step == 2) ? PC_STHU : PC_STWU,
- reg2,
- dst->reg,
- NULL,
- step * 2
- );
- setpcodeflags(dst->flags);
-
- branch_decrement_always(PC_BDNZ, label);
-
- for (remainder = len & 7, pos = step; remainder != 0; remainder -= step, pos += step) {
- int reg;
-
- if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) {
- SInt32 tmp = (align == 0) ? 1 : (align > remainder) ? remainder : align;
- step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2;
- } else {
- step = ((UInt32) remainder > 4) ? 4 : ((UInt32) remainder <= 2) ? remainder : 2;
- }
-
- reg = used_virtual_registers[RegClass_GPR]++;
-
- load_store_register(
- (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ,
- reg,
- src->reg,
- NULL,
- pos
- );
- setpcodeflags(src->flags);
-
- load_store_register(
- (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW,
- reg,
- dst->reg,
- NULL,
- pos
- );
- setpcodeflags(dst->flags);
- }
-}
-
-void move_block(Operand *dst, Operand *src, SInt32 len, SInt32 align) {
- Operand myDst;
-
- myDst = *dst;
-
- CError_ASSERT(447, myDst.optype >= OpndType_IndirectGPR_ImmOffset);
- CError_ASSERT(449, src->optype >= OpndType_IndirectGPR_ImmOffset);
-
- if (len == 1 || len == 2 || len == 4)
- move_block_via_load_store(&myDst, src, len, align);
- else if (len == 8 && align == 8)
- move_block_via_load_store(&myDst, src, len, align);
- else if (len <= 16 || (copts.optimizesize == 0 && len <= 64))
- move_block_via_load_store_sequence(&myDst, src, len, align);
- else
- move_block_via_inline_loop(&myDst, src, len, align);
-}
-
-static void load_word_of_small_struct(short dstReg, short srcReg, Operand *opnd, SInt32 offset, SInt32 len, SInt32 align) {
- short tmpReg;
- short extra = 0;
-
- switch (len) {
- case 1:
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7);
- setpcodeflags(opnd->flags);
- break;
- case 2:
- case 3:
- if (align > 1) {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset);
- extra += 2;
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWINM, dstReg, tmpReg, 16, 0, 15);
- setpcodeflags(opnd->flags);
- } else {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 1);
- extra += 2;
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 16, 8, 15);
- setpcodeflags(opnd->flags);
- }
- if (len == 3) {
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + extra);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 8, 16, 23);
- setpcodeflags(opnd->flags);
- }
- break;
- case 4:
- if (align > 2) {
- load_store_register(PC_LWZ, dstReg, srcReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- } else if (align > 1) {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWINM, dstReg, tmpReg, 16, 0, 15);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset + 2);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 0, 16, 31);
- setpcodeflags(opnd->flags);
- } else {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 1);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 16, 8, 15);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 2);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 8, 16, 23);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 3);
- setpcodeflags(opnd->flags);
- emitpcode(PC_RLWIMI, dstReg, tmpReg, 0, 24, 31);
- setpcodeflags(opnd->flags);
- }
- break;
- }
-}
-
-void load_small_block_into_reg(short dstReg, Operand *srcOpnd, Type *type, SInt32 align) {
- short finalReg;
- short tmpReg;
- SInt32 absAddress;
-
- coerce_to_addressable(srcOpnd);
-
- if (srcOpnd->optype == OpndType_IndirectGPR_Indexed) {
- CError_FATAL(557);
-
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_address(tmpReg, srcOpnd);
- srcOpnd->optype = OpndType_IndirectGPR_ImmOffset;
- srcOpnd->reg = tmpReg;
- srcOpnd->object = NULL;
- srcOpnd->immOffset = 0;
- }
-
- if (copts.misaligned_mem_access)
- align = 4;
-
- switch (srcOpnd->optype) {
- case OpndType_GPRPair:
- return;
- case OpndType_GPR:
- return;
- case OpndType_GPR_ImmOffset:
- finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++;
- add_immediate(finalReg, srcOpnd->reg, srcOpnd->object, srcOpnd->immOffset);
- break;
- case OpndType_GPR_Indexed:
- finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_ADD, finalReg, srcOpnd->reg, srcOpnd->regOffset);
- break;
- case OpndType_Absolute:
- finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++;
- absAddress = srcOpnd->immediate;
- if (FITS_IN_SHORT(absAddress)) {
- emitpcode(PC_LI, finalReg, absAddress);
- } else {
- tmpReg = finalReg;
- if (copts.optimizationlevel > 1 && absAddress)
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LIS, tmpReg, 0, HIGH_PART(absAddress));
- if (absAddress)
- emitpcode(PC_ADDI, finalReg, tmpReg, 0, LOW_PART(absAddress));
- }
- break;
- case OpndType_IndirectGPR_ImmOffset:
- finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++;
- load_word_of_small_struct(finalReg, srcOpnd->reg, srcOpnd, srcOpnd->immOffset, type->size, align);
- break;
- default:
- CError_FATAL(606);
- }
-
- srcOpnd->optype = OpndType_GPR;
- srcOpnd->reg = finalReg;
-}
-
-void load_small_block_into_reg_pair(short dstRegLo, short dstRegHi, Operand *srcOpnd, Type *type, SInt32 align) {
- short finalRegLo;
- short finalRegHi;
- short tmpRegLo;
- short tmpRegHi;
- short tmpReg;
- SInt32 absAddress;
-
- finalRegHi = -1;
- coerce_to_addressable(srcOpnd);
-
- if (srcOpnd->optype == OpndType_IndirectGPR_Indexed) {
- CError_FATAL(624);
-
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_address(tmpReg, srcOpnd);
- srcOpnd->optype = OpndType_IndirectGPR_ImmOffset;
- srcOpnd->reg = tmpReg;
- srcOpnd->object = NULL;
- srcOpnd->immOffset = 0;
- }
-
- if (copts.misaligned_mem_access)
- align = 4;
-
- switch (srcOpnd->optype) {
- case OpndType_GPRPair:
- if (dstRegLo != 0 && dstRegHi == 0)
- dstRegHi = used_virtual_registers[RegClass_GPR]++;
- if (dstRegHi != 0 && dstRegLo == 0)
- dstRegLo = used_virtual_registers[RegClass_GPR]++;
-
- if (srcOpnd->reg != dstRegLo || srcOpnd->regHi != dstRegHi) {
- tmpRegLo = dstRegLo ? dstRegLo : srcOpnd->reg;
- tmpRegHi = dstRegHi ? dstRegHi : srcOpnd->regHi;
-
- if (tmpRegLo != srcOpnd->reg) {
- if (tmpRegLo == srcOpnd->regHi) {
- CError_ASSERT(657, tmpRegLo != tmpRegHi);
- emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi);
- emitpcode(PC_MR, tmpRegLo, srcOpnd->reg);
- } else {
- emitpcode(PC_MR, tmpRegLo, srcOpnd->reg);
- if (srcOpnd->regHi != tmpRegHi)
- emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi);
- }
- } else if (tmpRegHi != srcOpnd->regHi) {
- if (tmpRegHi == srcOpnd->reg) {
- CError_ASSERT(671, tmpRegLo != tmpRegHi);
- emitpcode(PC_MR, tmpRegLo, srcOpnd->reg);
- emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi);
- } else {
- emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi);
- if (srcOpnd->reg != tmpRegLo)
- emitpcode(PC_MR, tmpRegLo, srcOpnd->reg);
- }
- }
- }
-
- finalRegLo = srcOpnd->reg;
- finalRegHi = srcOpnd->regHi;
- break;
- case OpndType_GPR:
- CError_FATAL(688);
- break;
- case OpndType_GPR_ImmOffset:
- CError_FATAL(691);
- break;
- case OpndType_GPR_Indexed:
- CError_FATAL(694);
- break;
- case OpndType_Absolute:
- finalRegLo = dstRegLo ? dstRegLo : used_virtual_registers[RegClass_GPR]++;
- absAddress = srcOpnd->immediate;
- if (FITS_IN_SHORT(absAddress)) {
- emitpcode(PC_LI, finalRegLo, absAddress);
- } else {
- tmpReg = finalRegLo;
- if (copts.optimizationlevel > 1 && absAddress)
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_LIS, tmpReg, 0, HIGH_PART(absAddress));
- if (absAddress)
- emitpcode(PC_ADDI, finalRegLo, tmpReg, 0, LOW_PART(absAddress));
- }
-
- finalRegHi = dstRegHi ? dstRegHi : used_virtual_registers[RegClass_GPR]++;
- if (is_unsigned(type) || absAddress >= 0)
- load_immediate(finalRegHi, 0);
- else
- load_immediate(finalRegHi, -1);
-
- break;
- case OpndType_IndirectGPR_ImmOffset:
- finalRegLo = dstRegLo ? dstRegLo : used_virtual_registers[RegClass_GPR]++;
- finalRegHi = dstRegHi ? dstRegHi : used_virtual_registers[RegClass_GPR]++;
- if (srcOpnd->reg == finalRegHi) {
- if (srcOpnd->reg == finalRegLo) {
- CError_FATAL(726);
- } else {
- load_word_of_small_struct(
- finalRegLo, srcOpnd->reg, srcOpnd,
- srcOpnd->immOffset + low_offset, type->size - 4, align);
- load_word_of_small_struct(
- finalRegHi, srcOpnd->reg, srcOpnd,
- srcOpnd->immOffset + high_offset, 4, align);
- }
- } else {
- load_word_of_small_struct(
- finalRegHi, srcOpnd->reg, srcOpnd,
- srcOpnd->immOffset + high_offset, 4, align);
- load_word_of_small_struct(
- finalRegLo, srcOpnd->reg, srcOpnd,
- srcOpnd->immOffset + low_offset, type->size - 4, align);
- }
- break;
- default:
- CError_FATAL(737);
- }
-
- if (finalRegHi == -1) {
- CError_FATAL(741);
- } else {
- srcOpnd->optype = OpndType_GPRPair;
- srcOpnd->reg = finalRegLo;
- srcOpnd->regHi = finalRegHi;
- }
-}
-
-static void store_word_of_small_struct(short srcReg, short dstReg, Operand *opnd, SInt32 offset, SInt32 len, SInt32 align) {
- short tmpReg;
- short extra = 0;
-
- switch (len) {
- case 1:
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- break;
- case 2:
- case 3:
- if (align > 1) {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 16, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STH, tmpReg, dstReg, opnd->object, offset);
- extra += 2;
- setpcodeflags(opnd->flags);
- } else {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
-
- emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 1);
- extra += 2;
- setpcodeflags(opnd->flags);
- }
- if (len == 3) {
- emitpcode(PC_RLWINM, tmpReg, srcReg, 24, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + extra);
- setpcodeflags(opnd->flags);
- }
- break;
- case 4:
- if (align > 2) {
- load_store_register(PC_STW, srcReg, dstReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
- } else if (align > 1) {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 16, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STH, tmpReg, dstReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_STH, srcReg, dstReg, opnd->object, offset + 2);
- setpcodeflags(opnd->flags);
- } else {
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset);
- setpcodeflags(opnd->flags);
-
- emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 1);
- setpcodeflags(opnd->flags);
-
- emitpcode(PC_RLWINM, tmpReg, srcReg, 24, 24, 31);
- setpcodeflags(opnd->flags);
- load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 2);
- setpcodeflags(opnd->flags);
-
- load_store_register(PC_STB, srcReg, dstReg, opnd->object, offset + 3);
- setpcodeflags(opnd->flags);
- }
- break;
- }
-}
-
-void store_small_block_from_reg(short srcReg, Operand *dstOpnd, Type *type, SInt32 align) {
- short tmpReg;
-
- coerce_to_addressable(dstOpnd);
-
- if (dstOpnd->optype == OpndType_IndirectGPR_Indexed) {
- CError_FATAL(839);
-
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_address(tmpReg, dstOpnd);
- dstOpnd->optype = OpndType_IndirectGPR_ImmOffset;
- dstOpnd->reg = tmpReg;
- dstOpnd->object = NULL;
- dstOpnd->immOffset = 0;
- }
-
- if (copts.misaligned_mem_access)
- align = 4;
-
- store_word_of_small_struct(srcReg, dstOpnd->reg, dstOpnd, dstOpnd->immOffset, type->size, align);
-}
-
-void store_small_block_from_reg_pair(short srcRegLo, short srcRegHi, Operand *dstOpnd, Type *type, SInt32 align) {
- short tmpReg;
-
- coerce_to_addressable(dstOpnd);
-
- if (dstOpnd->optype == OpndType_IndirectGPR_Indexed) {
- CError_FATAL(860);
-
- tmpReg = used_virtual_registers[RegClass_GPR]++;
- load_address(tmpReg, dstOpnd);
- dstOpnd->optype = OpndType_IndirectGPR_ImmOffset;
- dstOpnd->reg = tmpReg;
- dstOpnd->object = NULL;
- dstOpnd->immOffset = 0;
- }
-
- if (copts.misaligned_mem_access)
- align = 4;
-
- store_word_of_small_struct(
- srcRegLo, dstOpnd->reg, dstOpnd,
- dstOpnd->immOffset + low_offset, type->size - 4, align);
- store_word_of_small_struct(
- srcRegHi, dstOpnd->reg, dstOpnd,
- dstOpnd->immOffset + high_offset, 4, align);
-}
diff --git a/compiler_and_linker/unsorted/Switch.c b/compiler_and_linker/unsorted/Switch.c
deleted file mode 100644
index 4bbd82e..0000000
--- a/compiler_and_linker/unsorted/Switch.c
+++ /dev/null
@@ -1,518 +0,0 @@
-#include "compiler/Switch.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInt64.h"
-#include "compiler/CParser.h"
-#include "compiler/InstrSelection.h"
-#include "compiler/ObjGenMachO.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/TOC.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/objects.h"
-
-ObjectList *switchtables;
-static SwitchCase **caselabels;
-static CaseRange *caseranges;
-static SInt32 ncases;
-static SInt32 nranges_minus1;
-static CInt64 min;
-static CInt64 max;
-static CInt64 first;
-static short selector_gpr;
-static short selector_gprHi;
-static Type *selector_type;
-static PCodeLabel *defaultlabel;
-static CInt64 range;
-
-static int compare_cases(const void *a, const void *b) {
- const SwitchCase **casea = (const SwitchCase **) a;
- const SwitchCase **caseb = (const SwitchCase **) b;
-
- if (CInt64_Less((*casea)->min, (*caseb)->min))
- return -1;
- if (CInt64_Greater((*casea)->min, (*caseb)->min))
- return 1;
- return 0;
-}
-
-static void build_case_ranges(Type *type, SwitchCase *cases, CLabel *label) {
- SwitchCase **caseptr;
- SInt32 i;
- SwitchCase *curcase;
- CaseRange *currange;
-
- if (type->size == 8) {
- min.lo = 0;
- min.hi = 0x80000000;
- max.lo = 0xFFFFFFFF;
- max.hi = 0x7FFFFFFF;
- } else if (type->size == 4) {
- CInt64_SetLong(&min, 0x80000000);
- CInt64_SetLong(&max, 0x7FFFFFFF);
- } else if (is_unsigned(type)) {
- min.hi = 0;
- min.lo = 0;
- max.hi = 0;
- max.lo = 0xFFFF;
- } else {
- CInt64_SetLong(&min, -0x8000);
- CInt64_SetLong(&max, 0x7FFF);
- }
-
- caselabels = lalloc(sizeof(SwitchCase *) * ncases);
- caseptr = caselabels;
- while (cases) {
- *caseptr = cases;
- cases = cases->next;
- ++caseptr;
- }
-
- caseranges = lalloc(((ncases * 2) + 2) * sizeof(CaseRange));
- if (type->size < 8) {
- for (i = 0; i < ncases; i++)
- CInt64_SetLong(&caselabels[i]->min, caselabels[i]->min.lo);
- }
-
- qsort(caselabels, ncases, sizeof(SwitchCase *), &compare_cases);
-
- currange = caseranges;
- currange->min = min;
- currange->range = CInt64_Sub(max, min);
- currange->label = label->pclabel;
-
- for (i = 0; i < ncases; i++) {
- curcase = caselabels[i];
- if (CInt64_GreaterEqual(curcase->min, min) && CInt64_LessEqual(curcase->min, max)) {
- if (CInt64_Equal(currange->min, min))
- first = curcase->min;
- range = CInt64_Sub(curcase->min, first);
-
- if (CInt64_Greater(curcase->min, currange->min)) {
- currange->range = CInt64_Sub(CInt64_Sub(curcase->min, currange->min), cint64_one);
- (++currange)->min = curcase->min;
- } else if (CInt64_Greater(currange->min, min) && curcase->label->pclabel == currange[-1].label) {
- currange[-1].range = CInt64_Add(currange[-1].range, cint64_one);
- if (CInt64_Equal(currange->range, cint64_zero)) {
- currange--;
- } else {
- currange->min = CInt64_Add(currange->min, cint64_one);
- currange->range = CInt64_Sub(currange->range, cint64_one);
- }
- continue;
- }
-
- currange->range = cint64_zero;
- currange->label = curcase->label->pclabel;
-
- if (CInt64_Less(curcase->min, max)) {
- currange++;
- currange->min = CInt64_Add(curcase->min, cint64_one);
- currange->range = CInt64_Sub(max, currange->min);
- currange->label = label->pclabel;
- }
- }
- }
-
- nranges_minus1 = currange - caseranges;
-}
-
-static void treecompare(SInt32 start, SInt32 end) {
- SInt32 r30;
- SInt32 r29;
- CaseRange *currange;
- int count;
-
- count = end - start;
- CError_ASSERT(175, selector_type->size <= 4);
-
- r29 = start + (count >> 1) + 1;
- currange = caseranges + r29;
-
- if (CInt64_Equal(currange[-1].range, cint64_zero) && (!(count & 1) || (CInt64_NotEqual(currange->range, cint64_zero) && count > 1))) {
- currange--;
- r29--;
- }
-
- r30 = r29 - 1;
-
- if (selector_type->size < 4 && is_unsigned(selector_type)) {
- emitpcode(PC_CMPLI, 0, selector_gpr, CInt64_GetULong(&currange->min));
- } else if (FITS_IN_SHORT((SInt32) CInt64_GetULong(&currange->min))) {
- emitpcode(PC_CMPI, 0, selector_gpr, CInt64_GetULong(&currange->min));
- } else {
- SInt32 value = CInt64_GetULong(&currange->min);
- int reg = ALLOC_GPR();
- load_immediate(reg, value);
- emitpcode(PC_CMP, 0, selector_gpr, reg);
- }
-
- if (CInt64_Equal(currange->range, cint64_zero) && r29 < end) {
- branch_conditional(0, EEQU, 1, currange->label);
- r29++;
- }
-
- if (r29 == end) {
- if (start == r30) {
- if (caseranges[start].label == caseranges[end].label) {
- branch_always(caseranges[start].label);
- } else {
- branch_conditional(0, EGREATEREQU, 1, caseranges[end].label);
- branch_always(caseranges[start].label);
- }
- } else {
- branch_conditional(0, EGREATEREQU, 1, caseranges[end].label);
- treecompare(start, r30);
- }
- } else {
- if (start == r30) {
- branch_conditional(0, ELESS, 1, caseranges[start].label);
- treecompare(r29, end);
- } else {
- PCodeLabel *label = makepclabel();
- branch_conditional(0, EGREATEREQU, 1, label);
- treecompare(start, r30);
- branch_label(label);
- treecompare(r29, end);
- }
- }
-}
-
-static void I8_treecompare(SInt32 start, SInt32 end) {
- SInt32 r30;
- SInt32 r29;
- CaseRange *currange;
- int count;
-
- count = end - start;
-
- r29 = start + (count >> 1) + 1;
- currange = caseranges + r29;
-
- if (CInt64_Equal(currange[-1].range, cint64_zero) && (!(count & 1) || (CInt64_NotEqual(currange->range, cint64_zero) && count > 1))) {
- currange--;
- r29--;
- }
-
- r30 = r29 - 1;
-
- if (CInt64_Equal(currange->range, cint64_zero) && r29 < end) {
- short a = ALLOC_GPR();
- short b = ALLOC_GPR();
- load_immediate(a, currange->min.lo);
- load_immediate(b, currange->min.hi);
- emitpcode(PC_XOR, a, selector_gpr, a);
- emitpcode(PC_XOR, b, selector_gprHi, b);
- emitpcode(PC_OR, b, a, b);
- emitpcode(PC_CMPI, 0, b, 0);
- branch_conditional(0, EEQU, 1, currange->label);
- r29++;
- }
-
- if (r29 == end) {
- if (start == r30) {
- if (caseranges[start].label == caseranges[end].label) {
- branch_always(caseranges[start].label);
- } else {
- short a = ALLOC_GPR();
- short b = ALLOC_GPR();
- short c = ALLOC_GPR();
- short d = ALLOC_GPR();
- load_immediate(a, currange->min.lo);
- load_immediate(b, currange->min.hi);
- if (TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG && TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG) {
- emitpcode(PC_XORIS, c, selector_gprHi, 0x8000);
- emitpcode(PC_XORIS, d, b, 0x8000);
- } else {
- c = selector_gprHi;
- d = b;
- }
- emitpcode(PC_SUBFC, a, a, selector_gpr);
- emitpcode(PC_SUBFE, b, d, c);
- emitpcode(PC_SUBFE, b, a, a);
- emitpcode(PC_NEG, b, b);
- emitpcode(PC_CMPI, 0, b, 0);
- branch_conditional(0, EEQU, 1, caseranges[end].label);
- branch_always(caseranges[start].label);
- }
- } else {
- short a = ALLOC_GPR();
- short b = ALLOC_GPR();
- short c = ALLOC_GPR();
- short d = ALLOC_GPR();
- load_immediate(a, currange->min.lo);
- load_immediate(b, currange->min.hi);
- if (TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG && TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG) {
- emitpcode(PC_XORIS, c, selector_gprHi, 0x8000);
- emitpcode(PC_XORIS, d, b, 0x8000);
- } else {
- c = selector_gprHi;
- d = b;
- }
- emitpcode(PC_SUBFC, a, a, selector_gpr);
- emitpcode(PC_SUBFE, b, d, c);
- emitpcode(PC_SUBFE, b, a, a);
- emitpcode(PC_NEG, b, b);
- emitpcode(PC_CMPI, 0, b, 0);
- branch_conditional(0, EEQU, 1, caseranges[end].label);
- I8_treecompare(start, r30);
- }
- } else {
- if (start == r30) {
- short a = ALLOC_GPR();
- short b = ALLOC_GPR();
- short c = ALLOC_GPR();
- short d = ALLOC_GPR();
- load_immediate(a, currange->min.lo);
- load_immediate(b, currange->min.hi);
- if (TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG && TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG) {
- emitpcode(PC_XORIS, c, selector_gprHi, 0x8000);
- emitpcode(PC_XORIS, d, b, 0x8000);
- } else {
- c = selector_gprHi;
- d = b;
- }
- emitpcode(PC_SUBFC, a, selector_gpr, a);
- emitpcode(PC_SUBFE, b, c, d);
- emitpcode(PC_SUBFE, b, a, a);
- emitpcode(PC_NEG, b, b);
- emitpcode(PC_CMPI, 0, b, 0);
- branch_conditional(0, ENOTEQU, 1, caseranges[end].label);
- I8_treecompare(r29, end);
- } else {
- PCodeLabel *label;
- short a = ALLOC_GPR();
- short b = ALLOC_GPR();
- short c = ALLOC_GPR();
- short d = ALLOC_GPR();
- load_immediate(a, currange->min.lo);
- load_immediate(b, currange->min.hi);
- if (TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG && TYPE_INTEGRAL(selector_type)->integral != IT_ULONGLONG) {
- emitpcode(PC_XORIS, c, selector_gprHi, 0x8000);
- emitpcode(PC_XORIS, d, b, 0x8000);
- } else {
- c = selector_gprHi;
- d = b;
- }
- emitpcode(PC_SUBFC, a, a, selector_gpr);
- emitpcode(PC_SUBFE, b, d, c);
- emitpcode(PC_SUBFE, b, a, a);
- emitpcode(PC_NEG, b, b);
- emitpcode(PC_CMPI, 0, b, 0);
- label = makepclabel();
- branch_conditional(0, EEQU, 1, label);
- I8_treecompare(start, r30);
- branch_label(label);
- I8_treecompare(r29, end);
- }
- }
-}
-
-static void generate_tree(ENode *expr) {
- Operand op;
-
- memclrw(&op, sizeof(Operand));
- if (TYPE_IS_8BYTES(expr->rtype)) {
- GEN_NODE(expr, &op);
- coerce_to_register_pair(&op, expr->rtype, 0, 0);
- selector_type = expr->rtype;
- selector_gpr = op.reg;
- selector_gprHi = op.regHi;
- I8_treecompare(0, nranges_minus1);
- } else {
- GEN_NODE(expr, &op);
- if (expr->rtype->size < 4)
- extend32(&op, expr->rtype, 0);
- ENSURE_GPR(&op, expr->rtype, 0);
- selector_type = expr->rtype;
- selector_gpr = op.reg;
- treecompare(0, nranges_minus1);
- }
-}
-
-static Object *create_switch_table(void) {
- Object *obj;
- ObjectList *list;
- UInt32 *outptr;
- CaseRange *currange;
- SInt32 size;
- CInt64 value;
-
- obj = galloc(sizeof(Object));
- list = galloc(sizeof(ObjectList));
- memclrw(obj, sizeof(Object));
- memclrw(list, sizeof(ObjectList));
-
- obj->otype = OT_OBJECT;
- obj->access = ACCESSPUBLIC;
- obj->datatype = DDATA;
- obj->name = CParser_GetUniqueName();
- obj->toc = NULL;
- obj->sclass = TK_STATIC;
- obj->qual = Q_CONST;
- obj->flags |= OBJECT_FLAGS_2 | OBJECT_DEFINED;
- obj->u.data.linkname = obj->name;
- obj->type = NULL;
- createIndirect(obj, 0, 0);
- obj->type = TYPE(&void_ptr);
-
- size = CInt64_GetULong(&range) + 1;
- obj->u.data.u.switchtable.size = size;
- obj->u.data.u.switchtable.data = lalloc(4 * size);
-
- currange = caseranges;
- outptr = (UInt32 *) obj->u.data.u.switchtable.data;
- value = cint64_zero;
- while (CInt64_LessEqual(value, range)) {
- while (CInt64_Greater(CInt64_Add(first, value), CInt64_Add(currange->min, currange->range)))
- currange++;
- *outptr = CTool_CreateIndexFromPointer(currange->label);
- value = CInt64_Add(value, cint64_one);
- outptr++;
- }
-
- list->object = obj;
- list->next = switchtables;
- switchtables = list;
- return list->object;
-}
-
-static void generate_table(ENode *expr, SwitchInfo *info) {
- Object *table;
- SwitchCase *curcase;
- short reg;
- short reg2;
- short reg3;
- Operand op1;
- Operand op2;
-
- CInt64 val3 = {0, 3};
- memclrw(&op1, sizeof(Operand));
- memclrw(&op2, sizeof(Operand));
-
- if (CInt64_Greater(first, cint64_zero) && CInt64_Less(first, val3)) {
- range = CInt64_Add(range, first);
- first = cint64_zero;
- }
-
- table = create_switch_table();
- CError_ASSERT(553, !TYPE_IS_8BYTES(expr->rtype));
-
- GEN_NODE(expr, &op1);
- if (expr->rtype->size < 4)
- extend32(&op1, expr->rtype, 0);
- ENSURE_GPR(&op1, expr->rtype, 0);
-
- reg = op1.reg;
- if (CInt64_NotEqual(first, cint64_zero)) {
- SInt32 value;
- reg = ALLOC_GPR();
- value = -CInt64_GetULong(&first);
- if (!FITS_IN_SHORT(value)) {
- emitpcode(PC_ADDIS, reg, op1.reg, 0, HIGH_PART(value));
- if (value)
- emitpcode(PC_ADDI, reg, reg, 0, LOW_PART(value));
- } else {
- emitpcode(PC_ADDI, reg, op1.reg, 0, value);
- }
- }
-
- if (!FITS_IN_SHORT(CInt64_GetULong(&range))) {
- short tmp = ALLOC_GPR();
- load_immediate(tmp, CInt64_GetULong(&range));
- emitpcode(PC_CMPL, 0, reg, tmp);
- } else {
- emitpcode(PC_CMPLI, 0, reg, CInt64_GetULong(&range));
- }
-
- branch_conditional(0, EGREATER, 1, defaultlabel);
- if (table->toc) {
- op2.optype = OpndType_Symbol;
- op2.object = table->toc;
- indirect(&op2, NULL);
- } else {
- op2.optype = OpndType_Symbol;
- op2.object = table;
- }
-
- if (op2.optype != OpndType_GPR) {
- Coerce_to_register(&op2, TYPE(&void_ptr), reg2 = ALLOC_GPR());
- }
-
- if (op2.optype != OpndType_GPR) {
- CError_FATAL(599);
- } else {
- if (op2.reg != reg2)
- emitpcode(PC_MR, reg2, op2.reg);
- }
-
- if (CInt64_Equal(first, cint64_zero)) {
- reg = ALLOC_GPR();
- emitpcode(PC_RLWINM, reg, op1.reg, 2, 0, 29);
- } else {
- emitpcode(PC_RLWINM, reg, reg, 2, 0, 29);
- }
-
- reg3 = reg2;
- emitpcode(PC_LWZX, reg3, reg3, reg);
- for (curcase = info->cases; curcase; curcase = curcase->next)
- pcbranch(pclastblock, curcase->label->pclabel);
- pcbranch(pclastblock, info->defaultlabel->pclabel);
- emitpcode(PC_MTCTR, reg3);
- branch_indirect(table);
-}
-
-void switchstatement(ENode *expr, SwitchInfo *info) {
- Boolean use_table;
- SwitchCase *swcase;
-
- use_table = copts.switch_tables;
-
- ncases = 0;
- for (swcase = info->cases; swcase; swcase = swcase->next) {
- if (!swcase->label->pclabel)
- swcase->label->pclabel = makepclabel();
- ncases++;
- }
-
- CError_ASSERT(656, ncases >= 0 && ncases <= 0x3333332U);
-
- if (!info->defaultlabel->pclabel)
- info->defaultlabel->pclabel = makepclabel();
- defaultlabel = info->defaultlabel->pclabel;
-
- build_case_ranges(expr->rtype, info->cases, info->defaultlabel);
-
- if (TYPE_IS_8BYTES(expr->rtype)) {
- generate_tree(expr);
- return;
- }
-
- if (!use_table || nranges_minus1 < 8 || (nranges_minus1 * 2) < ((range.lo / 2) + 4))
- generate_tree(expr);
- else
- generate_table(expr, info);
-}
-
-void dumpswitchtables(Object *funcobj) {
- Object *table;
- ObjectList *list;
- SInt32 size;
- UInt32 *array;
-
- for (list = switchtables; list; list = list->next) {
- table = list->object;
- CError_ASSERT(694, table->otype == OT_OBJECT && table->access == ACCESSPUBLIC && table->datatype == DDATA);
-
- size = table->u.data.u.switchtable.size;
- array = (UInt32 *) table->u.data.u.switchtable.data;
- while (size--) {
- *array = CTool_EndianConvertWord32(((PCodeLabel *) CTool_ResolveIndexToPointer(*array))->block->codeOffset);
- array++;
- }
-
- ObjGen_DeclareSwitchTable(table, funcobj);
- }
-}
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);
-}
diff --git a/compiler_and_linker/unsorted/ValueNumbering.c b/compiler_and_linker/unsorted/ValueNumbering.c
deleted file mode 100644
index 0907fa1..0000000
--- a/compiler_and_linker/unsorted/ValueNumbering.c
+++ /dev/null
@@ -1,661 +0,0 @@
-#include "compiler/ValueNumbering.h"
-#include "compiler/Alias.h"
-#include "compiler/PCode.h"
-#include "compiler/Registers.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/CError.h"
-
-typedef struct ValueLabel {
- struct ValueLabel *next;
- PCodeArg op;
-} ValueLabel;
-
-typedef struct AvailableValue {
- struct AvailableValue *next;
- ValueLabel *labelled;
- PCode *pcode;
- int killedregister;
- int aliasnumber;
- int opnumbers[0];
-} AvailableValue;
-
-typedef struct RegValue {
- int number;
- int x4;
- AvailableValue *available;
-} RegValue;
-
-typedef struct State {
- void *stackedvalues;
- int valueceiling;
-} State;
-
-typedef struct StackedValue {
- struct StackedValue *next;
- PCodeArg op;
- RegValue value;
- Alias *alias;
- PCode *valuepcode;
-} StackedValue;
-
-int removedcommonsubexpressions;
-int nextvaluenumber;
-static AvailableValue *opvalue[428];
-static RegValue *regvalue[RegClassMax];
-static StackedValue *stackedvalues;
-static int valueceiling;
-static int moreaggressiveoptimization;
-
-static void allocatecsedatastructures(void) {
- char rclass;
-
- for (rclass = 0; rclass < RegClassMax; rclass++)
- regvalue[(char) rclass] = oalloc(sizeof(RegValue) * used_virtual_registers[(char) rclass]);
-}
-
-static void initializecsedatastructures(void) {
- RegValue *rv;
- char rclass;
- int i;
-
- nextvaluenumber = 0;
-
- for (i = 0; i < 428; i++)
- opvalue[i] = NULL;
-
- for (rclass = 0; rclass < RegClassMax; rclass++) {
- rv = regvalue[(char) rclass];
- for (i = 0; i < used_virtual_registers[(char) rclass]; i++, rv++) {
- rv->number = nextvaluenumber++;
- rv->x4 = 0;
- rv->available = NULL;
- }
- }
-
- initialize_alias_values();
- stackedvalues = NULL;
- valueceiling = 0x7FFFFFFF;
-}
-
-static void labelvalue(AvailableValue *av, PCodeArg *op) {
- ValueLabel *label = oalloc(sizeof(ValueLabel));
- label->op = *op;
- label->next = av->labelled;
- av->labelled = label;
-}
-
-static void unlabelvalue(AvailableValue *av, PCodeArg *op) {
- ValueLabel *labelled;
- ValueLabel **ptr;
-
- ptr = &av->labelled;
- while ((labelled = *ptr)) {
- if (labelled->op.data.reg.reg == op->data.reg.reg)
- *ptr = labelled->next;
- else
- ptr = &labelled->next;
- }
-}
-
-static void stackregistervalue(PCodeArg *op, RegValue *value) {
- StackedValue *stacked = oalloc(sizeof(StackedValue));
- stacked->next = stackedvalues;
- stackedvalues = stacked;
-
- stacked->op = *op;
- stacked->value = *value;
-}
-
-static void stackmemoryvalue(Alias *alias) {
- StackedValue *stacked = oalloc(sizeof(StackedValue));
- stacked->next = stackedvalues;
- stackedvalues = stacked;
-
- stacked->op.kind = PCOp_MEMORY;
- stacked->alias = alias;
- stacked->value.number = alias->valuenumber;
- stacked->valuepcode = alias->valuepcode;
-}
-
-static void unstackvalue(StackedValue *stacked) {
- PCodeArg *op = &stacked->op;
- RegValue *value;
-
- if (stacked->op.kind == PCOp_MEMORY) {
- stacked->alias->valuenumber = stacked->value.number;
- stacked->alias->valuepcode = stacked->valuepcode;
- } else {
- value = &regvalue[op->arg][op->data.reg.reg];
- if (value->available)
- unlabelvalue(value->available, op);
- value->number = stacked->value.number;
- value->x4 = stacked->value.x4;
- value->available = stacked->value.available;
- if (value->available)
- labelvalue(value->available, op);
- }
-}
-
-static int samevalue(PCodeArg *op1, PCodeArg *op2) {
- return regvalue[op1->arg][op1->data.reg.reg].number == regvalue[op2->arg][op2->data.reg.reg].number;
-}
-
-static int killregister(PCodeArg *op) {
- RegValue *value;
-
- value = &regvalue[op->arg][op->data.reg.reg];
- if (value->number < valueceiling && nextvaluenumber >= valueceiling)
- stackregistervalue(op, value);
-
- if (value->available)
- unlabelvalue(value->available, op);
- value->available = NULL;
- value->x4 = 0;
- return value->number = nextvaluenumber++;
-}
-
-void killmemory(Alias *alias, PCode *newValue) {
- if (alias->valuenumber < valueceiling && nextvaluenumber >= valueceiling)
- stackmemoryvalue(alias);
-
- if (newValue) {
- alias->valuenumber = regvalue[newValue->args[0].arg][newValue->args[0].data.reg.reg].number;
- alias->valuepcode = newValue;
- } else {
- alias->valuenumber = nextvaluenumber++;
- alias->valuepcode = NULL;
- }
-}
-
-static void killspecificCSEs(short op) {
- AvailableValue *av;
- ValueLabel *labelled;
-
- for (av = opvalue[op]; av; av = av->next) {
- for (labelled = av->labelled; labelled; labelled = labelled->next)
- killregister(&labelled->op);
- }
-}
-
-static void killallCSEs(void) {
- AvailableValue *av;
- ValueLabel *labelled;
- int i;
-
- for (i = 0; i < 428; i++) {
- for (av = opvalue[i]; av; av = av->next) {
- for (labelled = av->labelled; labelled; labelled = labelled->next)
- killregister(&labelled->op);
- }
- }
-}
-
-static void killregisters(PCode *pcode) {
- PCodeArg *op;
- int i;
-
- for (i = 0, op = pcode->args; i < pcode->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite))
- killregister(op);
- }
-}
-
-static void copyregister(PCodeArg *src, PCodeArg *dest) {
- RegValue *srcvalue;
- RegValue *destvalue;
-
- srcvalue = &regvalue[src->arg][src->data.reg.reg];
- destvalue = &regvalue[dest->arg][dest->data.reg.reg];
-
- if (destvalue->number < valueceiling && nextvaluenumber >= valueceiling)
- stackregistervalue(dest, destvalue);
-
- if (destvalue->available)
- unlabelvalue(destvalue->available, dest);
- destvalue->available = srcvalue->available;
- if (destvalue->available)
- labelvalue(destvalue->available, dest);
-
- destvalue->number = srcvalue->number;
-
- if (srcvalue->x4 && srcvalue->number == regvalue[src->arg][srcvalue->x4].number)
- destvalue->x4 = srcvalue->x4;
- else
- destvalue->x4 = src->data.reg.reg;
-}
-
-static int matchvalues(AvailableValue *av, PCode *match) {
- PCodeArg *avOp;
- PCodeArg *matchOp;
- int i;
-
- for (avOp = &av->pcode->args[0], matchOp = &match->args[0], i = 0; i < match->argCount; i++, avOp++, matchOp++) {
- if (i != 0) {
- switch (avOp->kind) {
- case PCOp_REGISTER:
- if (av->opnumbers[i] != regvalue[matchOp->arg][matchOp->data.reg.reg].number)
- return 0;
- break;
- case PCOp_MEMORY:
- if (matchOp->kind != PCOp_MEMORY)
- return 0;
- if (matchOp->data.mem.obj != avOp->data.mem.obj)
- return 0;
- if (matchOp->data.mem.offset != avOp->data.mem.offset)
- return 0;
- if ((unsigned char) matchOp->arg != (unsigned char) avOp->arg)
- return 0;
- break;
- case PCOp_IMMEDIATE:
- if (matchOp->kind != PCOp_IMMEDIATE)
- return 0;
- if (matchOp->data.imm.value != avOp->data.imm.value)
- return 0;
- break;
- case PCOp_LABEL:
- if (matchOp->kind != PCOp_LABEL)
- return 0;
- if (matchOp->data.label.label != avOp->data.label.label)
- return 0;
- break;
- case PCOp_SYSREG:
- CError_FATAL(572);
- }
- }
- }
-
- if ((match->flags & (fIsRead | fPCodeFlag20000)) && match->alias->valuenumber != av->aliasnumber)
- return 0;
-
- return 1;
-}
-
-static void chooselocation(AvailableValue *av, PCodeArg *op) {
- ValueLabel *labelled;
- PCodeArg *baseop;
-
- baseop = &av->pcode->args[0];
- labelled = av->labelled;
- while (labelled) {
- if (labelled->op.data.reg.reg == baseop->data.reg.reg) {
- *op = labelled->op;
- return;
- }
- labelled = labelled->next;
- }
-
- *op = av->labelled[0].op;
-}
-
-static int findavailablevalue(PCode *pcode, PCodeArg *op) {
- AvailableValue *av;
- PCodeArg tmp1;
- PCodeArg tmp2;
-
- for (av = opvalue[pcode->op]; av; av = av->next) {
- if (av->labelled && av->pcode->flags == pcode->flags && av->pcode->argCount == pcode->argCount) {
- if (!matchvalues(av, pcode)) {
- if (!(pcode->flags & fCommutative))
- continue;
-
- tmp1 = pcode->args[1];
- pcode->args[1] = pcode->args[2];
- pcode->args[2] = tmp1;
-
- if (!matchvalues(av, pcode)) {
- tmp2 = pcode->args[1];
- pcode->args[1] = pcode->args[2];
- pcode->args[2] = tmp2;
- continue;
- }
- }
- chooselocation(av, op);
- return 1;
- }
- }
-
- return 0;
-}
-
-static void addavailablevalue(PCode *pcode) {
- AvailableValue *av;
- PCodeArg *op;
- int i;
-
- av = oalloc(sizeof(AvailableValue) + sizeof(int) * pcode->argCount);
- av->labelled = NULL;
- av->pcode = pcode;
- for (i = 0, op = &pcode->args[0]; i < pcode->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER)
- av->opnumbers[i] = regvalue[op->arg][op->data.reg.reg].number;
- }
-
- if (pcode->flags & (fIsRead | fPCodeFlag20000))
- av->aliasnumber = pcode->alias->valuenumber;
-
- op = &pcode->args[0];
- av->killedregister = killregister(op);
- labelvalue(av, op);
- regvalue[op->arg][op->data.reg.reg].available = av;
- av->next = opvalue[pcode->op];
- opvalue[pcode->op] = av;
-}
-
-static int isCSEop(PCode *pcode) {
- PCodeArg *baseOp;
- PCodeArg *op;
- int i;
-
- baseOp = &pcode->args[0];
-
- switch (pcode->op) {
- case PC_CMPI:
- case PC_CMP:
- case PC_CMPLI:
- case PC_CMPL:
- case PC_FCMPU:
- case PC_FCMPO:
- if (!moreaggressiveoptimization)
- return 0;
- break;
- case PC_LI:
- case PC_LIS:
- if (!moreaggressiveoptimization)
- return 0;
- if (pcode->args[0].data.reg.reg < first_fe_temporary_register[RegClass_GPR] || pcode->args[0].data.reg.reg > last_temporary_register[RegClass_GPR])
- return 0;
- break;
- }
-
- if (PCODE_FLAG_SET_F(pcode) & (fIsVolatile | fSideEffects | fOverflow | fSetsCarry | fRecordBit))
- return 0;
-
- for (i = 0, op = &pcode->args[0]; i < pcode->argCount; i++, op++) {
- if (op != baseOp &&
- op->kind == baseOp->kind &&
- op->arg == baseOp->arg &&
- op->data.reg.reg == baseOp->data.reg.reg)
- return 0;
- }
-
- return 1;
-}
-
-static int isCSEload(PCode *pcode) {
- PCodeArg *op;
- int i;
- int count;
-
- count = 0;
- for (i = 0, op = &pcode->args[0]; i < pcode->argCount; i++, op++) {
- if (op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite))
- count++;
- }
-
- return count == 1;
-}
-
-static void registercopy(PCode *pcode) {
- PCodeArg *op1;
- PCodeArg *op2;
-
- op1 = &pcode->args[0];
- op2 = &pcode->args[1];
- if (samevalue(op2, op1))
- deletepcode(pcode);
- else
- copyregister(op2, op1);
-}
-
-static PCode *recentlystored(Alias *alias, PCodeArg *op) {
- PCode *pc;
- if ((pc = alias->valuepcode) && alias->valuenumber == regvalue[pc->args[0].arg][pc->args[0].data.reg.reg].number) {
- *op = pc->args[0];
- return pc;
- } else {
- return NULL;
- }
-}
-
-static void simpleload(PCode *pcode) {
- PCodeArg *origOp;
- PCodeArg op;
- PCode *rs;
-
- origOp = &pcode->args[0];
- if ((pcode->flags & fIsVolatile) || !isCSEload(pcode)) {
- killregisters(pcode);
- return;
- }
-
- if (findavailablevalue(pcode, &op)) {
- if (!samevalue(origOp, &op)) {
- insertpcodebefore(pcode, makecopyinstruction(&op, origOp));
- copyregister(&op, origOp);
- }
- deletepcode(pcode);
- removedcommonsubexpressions = 1;
- } else if ((rs = recentlystored(pcode->alias, &op)) && can_reuse_stored_value(rs, pcode)) {
- if (!samevalue(origOp, &op)) {
- insertpcodebefore(pcode, makecopyinstruction(&op, origOp));
- copyregister(&op, origOp);
- }
- deletepcode(pcode);
- removedcommonsubexpressions = 1;
- } else {
- addavailablevalue(pcode);
- }
-}
-
-static void simplestore(PCode *pcode) {
- update_alias_value(pcode->alias, pcode);
- killregisters(pcode);
-}
-
-static void pointerload(PCode *pcode) {
- PCodeArg *op;
- PCodeArg buf;
-
- op = &pcode->args[0];
-
- if ((pcode->flags & fIsVolatile) || !isCSEload(pcode)) {
- killregisters(pcode);
- return;
- }
-
- if (findavailablevalue(pcode, &buf)) {
- if (!samevalue(op, &buf)) {
- insertpcodebefore(pcode, makecopyinstruction(&buf, op));
- copyregister(&buf, op);
- }
- deletepcode(pcode);
- removedcommonsubexpressions = 1;
- } else {
- addavailablevalue(pcode);
- }
-}
-
-static void pointerstore(PCode *pcode) {
- update_alias_value(pcode->alias, NULL);
- killregisters(pcode);
-}
-
-static void arithmeticop(PCode *pcode) {
- PCodeArg *op;
- PCodeArg buf;
-
- op = &pcode->args[0];
-
- if (findavailablevalue(pcode, &buf)) {
- if (!samevalue(op, &buf)) {
- insertpcodebefore(pcode, makecopyinstruction(&buf, op));
- copyregister(&buf, op);
- }
- deletepcode(pcode);
- removedcommonsubexpressions = 1;
- } else {
- addavailablevalue(pcode);
- }
-}
-
-static void functioncall(PCode *pcode) {
- killregisters(pcode);
- if (coloring) {
- update_all_alias_values();
- killallCSEs();
- } else {
- update_alias_value(pcode->alias, NULL);
- }
-}
-
-static void operatefrommemory(PCode *pcode) {
- CError_FATAL(980);
-}
-
-static void operatetomemory(PCode *pcode) {
- CError_FATAL(1011);
-}
-
-static void propagatecopiesto(PCode *pcode) {
- PCodeArg *op;
- int i;
-
- for (i = 0, op = &pcode->args[0]; i < pcode->argCount; i++, op++) {
- if (
- op->kind == PCOp_REGISTER &&
- (op->data.reg.effect & (EffectRead | EffectWrite | Effect8)) == EffectRead &&
- op->data.reg.reg >= n_real_registers[op->arg] &&
- regvalue[op->arg][op->data.reg.reg].x4 &&
- regvalue[op->arg][op->data.reg.reg].x4 >= n_real_registers[op->arg] &&
- regvalue[op->arg][op->data.reg.reg].number == regvalue[op->arg][regvalue[op->arg][op->data.reg.reg].x4].number
- ) {
- op->data.reg.reg = regvalue[op->arg][op->data.reg.reg].x4;
- }
- }
-}
-
-static void removecsesfrombasicblock(PCodeBlock *block) {
- PCode *pcode;
- PCode *next;
-
- for (pcode = block->firstPCode; pcode; pcode = next) {
- next = pcode->nextPCode;
- propagatecopiesto(pcode);
- if (pcode->flags & fIsMove) {
- registercopy(pcode);
- } else if ((pcode->flags & fIsCall) && (pcode->flags & (fLink | fSideEffects))) {
- functioncall(pcode);
- } else if (pcode->flags & fIsRead) {
- if (pcode->flags & fIsPtrOp)
- pointerload(pcode);
- else
- simpleload(pcode);
- } else if (pcode->flags & fIsWrite) {
- if (pcode->flags & fIsPtrOp)
- pointerstore(pcode);
- else
- simplestore(pcode);
- } else if (pcode->flags & fPCodeFlag20000) {
- operatefrommemory(pcode);
- } else if (pcode->flags & fPCodeFlag40000) {
- operatetomemory(pcode);
- } else if ((pcode->flags & fIsCSE) && isCSEop(pcode)) {
- arithmeticop(pcode);
- } else {
- killregisters(pcode);
- }
- }
-
- block->flags |= fVisited;
-}
-
-static void getvaluestate(State *state) {
- state->stackedvalues = stackedvalues;
- state->valueceiling = valueceiling;
-}
-
-static void setvaluestate(State *state) {
- stackedvalues = state->stackedvalues;
- valueceiling = state->valueceiling;
-}
-
-static void forkvaluestate(int number) {
- stackedvalues = NULL;
- valueceiling = number;
-}
-
-static void regressvaluestate(void) {
- AvailableValue *av;
- AvailableValue **ptr;
- int i;
- StackedValue *stacked;
-
- for (i = 0; i < 428; i++) {
- ptr = &opvalue[i];
- while ((av = *ptr)) {
- if (av->killedregister >= valueceiling)
- *ptr = av->next;
- else
- ptr = &av->next;
- }
- }
-
- for (stacked = stackedvalues; stacked; stacked = stacked->next)
- unstackvalue(stacked);
-}
-
-static void removecsesfromextendedbasicblock(PCodeBlock *block) {
- PCLink *succ;
- int counter;
- State state;
-
- removecsesfrombasicblock(block);
- while (block->successors &&
- !block->successors->nextLink &&
- block->successors->block->predecessors &&
- !block->successors->block->predecessors->nextLink) {
- block = block->successors->block;
- removecsesfrombasicblock(block);
- }
-
- counter = 0;
- for (succ = block->successors; succ; succ = succ->nextLink) {
- if (!(succ->block->flags & fVisited) && succ->block->predecessors && !succ->block->predecessors->nextLink)
- counter++;
- }
-
- if (counter) {
- getvaluestate(&state);
- forkvaluestate(nextvaluenumber);
- for (succ = block->successors; succ; succ = succ->nextLink) {
- if (!(succ->block->flags & fVisited) && succ->block->predecessors && !succ->block->predecessors->nextLink) {
- removecsesfromextendedbasicblock(succ->block);
- regressvaluestate();
- }
- }
- setvaluestate(&state);
- }
-}
-
-void removecommonsubexpressions(Object *proc, int flag) {
- PCodeBlock *block;
-
- moreaggressiveoptimization = flag;
- removedcommonsubexpressions = 0;
- gather_alias_info();
- allocatecsedatastructures();
-
- for (block = pcbasicblocks; block; block = block->nextBlock)
- block->flags &= ~fVisited;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (!(block->flags & fVisited)) {
- initializecsedatastructures();
- removecsesfromextendedbasicblock(block);
- }
- }
-
- freeoheap();
-}
-
diff --git a/compiler_and_linker/unsorted/VectorArraysToRegs.c b/compiler_and_linker/unsorted/VectorArraysToRegs.c
deleted file mode 100644
index fde27f1..0000000
--- a/compiler_and_linker/unsorted/VectorArraysToRegs.c
+++ /dev/null
@@ -1,548 +0,0 @@
-#include "compiler/VectorArraysToRegs.h"
-#include "compiler/CError.h"
-#include "compiler/CFunc.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/Registers.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-typedef struct LocalVectorArray {
- struct LocalVectorArray *next;
- Object *object;
- unsigned int invalid:1;
- SInt32 arraySize;
- SInt32 elementCount;
- int totalUses;
- int elements[1];
-} LocalVectorArray;
-
-typedef struct VectorPropInfo {
- UInt32 *use;
- UInt32 *def;
- UInt32 *in;
- UInt32 *out;
-} VectorPropInfo;
-
-typedef struct ADDI {
- PCode *instr;
- RegUseOrDef *list;
-} ADDI;
-
-static int number_of_ADDIs;
-static ADDI *ADDIs;
-static VectorPropInfo *vectorpropinfo;
-static int *naddsinblock;
-static int *firstaddinblock;
-static Boolean converted_arrays;
-
-static LocalVectorArray *scanforlocalvectorarrays(void) {
- SInt32 elementCount;
- LocalVectorArray *head;
- LocalVectorArray *array;
- ObjectList *list;
- int i;
- SInt32 arraySize;
-
- head = NULL;
-
- for (list = locals; list; list = list->next) {
- if (
- list->object &&
- !(IS_TYPE_POINTER(list->object->type) ? (TPTR_QUAL(list->object->type) & Q_VOLATILE) : (list->object->qual & Q_VOLATILE)) &&
- list->object->type &&
- IS_TYPE_ARRAY(list->object->type) &&
- IS_TYPE_VECTOR(TPTR_TARGET(list->object->type))
- ) {
- arraySize = list->object->type->size;
- elementCount = arraySize / 16;
- if (elementCount > 0 && elementCount <= 8) {
- array = oalloc(sizeof(int) * (elementCount - 1) + sizeof(LocalVectorArray));
- array->next = head;
- head = array;
-
- array->object = list->object;
- array->arraySize = arraySize;
- array->elementCount = elementCount;
- array->totalUses = 0;
- array->invalid = 0;
-
- for (i = 0; i < elementCount; i++) {
- array->elements[i] = 0;
- }
- }
- }
- }
-
- return head;
-}
-
-static LocalVectorArray *lookup_vector_array_object(LocalVectorArray *arrays, Object *object) {
- while (arrays) {
- if (arrays->object == object)
- return arrays;
- arrays = arrays->next;
- }
- return NULL;
-}
-
-static void scaninstructions(LocalVectorArray *arrays) {
- PCodeBlock *block;
- PCode *instr;
- int counter;
- int i;
- PCodeArg *op;
- LocalVectorArray *array;
- int element;
-
- naddsinblock = oalloc(sizeof(int) * pcblockcount);
- memclrw(naddsinblock, sizeof(int) * pcblockcount);
-
- firstaddinblock = oalloc(sizeof(int) * pcblockcount);
- memclrw(firstaddinblock, sizeof(int) * pcblockcount);
-
- number_of_ADDIs = 0;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- firstaddinblock[block->blockIndex] = number_of_ADDIs;
- counter = 0;
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (!(instr->flags & fIsBranch) && instr->argCount) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- op->kind == PCOp_MEMORY &&
- (PCOpMemoryArg) op->arg == PCOpMemory1 &&
- (array = lookup_vector_array_object(arrays, op->data.mem.obj)) &&
- !array->invalid
- )
- {
- if (instr->op != PC_ADDI) {
- array->invalid = 1;
- } else if (instr->args[0].data.reg.reg < n_real_registers[RegClass_GPR]) {
- array->invalid = 1;
- } else {
- number_of_ADDIs++;
- counter++;
- }
-
- if (!array->invalid) {
- element = op->data.mem.offset / 16;
- if (element < array->elementCount)
- array->elements[element]++;
- else
- array->invalid = 1;
- }
- }
- op++;
- }
- }
- }
- naddsinblock[block->blockIndex] = counter;
- }
-}
-
-static void computeaddilist(LocalVectorArray *arrays) {
- PCodeBlock *block;
- PCode *instr;
- RegUseOrDef *list;
- ADDI *addi;
- UInt32 *vec;
- LocalVectorArray *array;
- UseOrDef *def;
- int defID;
- UseOrDef *use;
- int useID;
-
- ADDIs = oalloc(sizeof(ADDI) * number_of_ADDIs);
- memclrw(ADDIs, sizeof(ADDI) * number_of_ADDIs);
-
- vec = oalloc(4 * ((number_of_Uses + 31) >> 5));
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (naddsinblock[block->blockIndex]) {
- bitvectorcopy(vec, usedefinfo[block->blockIndex].usevec1C, number_of_Uses);
- addi = &ADDIs[firstaddinblock[block->blockIndex] + naddsinblock[block->blockIndex] - 1];
- for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
- if (!(instr->flags & fIsBranch) && instr->argCount) {
- int reg; // r18
- if (
- instr->op == PC_ADDI &&
- (reg = instr->args[0].data.reg.reg) >= n_real_registers[RegClass_GPR] &&
- instr->args[2].kind == PCOp_MEMORY &&
- (PCOpMemoryArg) instr->args[2].arg == PCOpMemory1 &&
- (array = lookup_vector_array_object(arrays, instr->args[2].data.mem.obj)) &&
- !array->invalid
- )
- {
- addi->instr = instr;
- addi->list = NULL;
- for (list = reg_Uses[RegClass_GPR][reg]; list; list = list->next) {
- if (bitvectorgetbit(list->id, vec)) {
- RegUseOrDef *node = oalloc(sizeof(RegUseOrDef));
- node->id = list->id;
- node->next = addi->list;
- addi->list = node;
- }
- }
- addi--;
- }
-
- for (def = &Defs[defID = instr->defID]; defID < number_of_Defs && def->pcode == instr; def++, defID++) {
- if (def->v.kind == PCOp_REGISTER) {
- RegUseOrDef *l;
- for (l = reg_Uses[def->v.arg][def->v.u.reg]; l; l = l->next)
- bitvectorclearbit(l->id, vec);
- }
- }
-
- for (use = &Uses[useID = instr->useID]; useID < number_of_Uses && use->pcode == instr; use++, useID++) {
- if (use->v.kind == PCOp_REGISTER)
- bitvectorsetbit(useID, vec);
- }
- }
- }
- }
- }
-}
-
-static void allocatevectorpropinfo(void) {
- VectorPropInfo *info;
- int i;
-
- vectorpropinfo = oalloc(sizeof(VectorPropInfo) * pcblockcount);
- for (i = 0, info = vectorpropinfo; i < pcblockcount; i++, info++) {
- info->use = oalloc(4 * ((number_of_ADDIs + 31) >> 5));
- info->def = oalloc(4 * ((number_of_ADDIs + 31) >> 5));
- info->in = oalloc(4 * ((number_of_ADDIs + 31) >> 5));
- info->out = oalloc(4 * ((number_of_ADDIs + 31) >> 5));
- }
-}
-
-static void computelocalvectorpropinfo(LocalVectorArray *arrays) {
- VectorPropInfo *info;
- PCodeBlock *block;
- PCode *instr;
- UInt32 *vec0;
- UInt32 *vec4;
- int index;
- PCodeArg *op;
- int i;
- int addi_i;
- ADDI *addi;
- LocalVectorArray *array;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- info = &vectorpropinfo[block->blockIndex];
- vec0 = info->use;
- vec4 = info->def;
- bitvectorinitialize(vec0, number_of_ADDIs, 0);
- bitvectorinitialize(vec4, number_of_ADDIs, 0);
- index = firstaddinblock[block->blockIndex];
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- if (!(instr->flags & fIsBranch) && instr->argCount) {
- i = instr->argCount;
- op = instr->args;
- while (i--) {
- if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR && (op->data.reg.effect & EffectWrite)) {
- for (addi_i = 0, addi = ADDIs; addi_i < number_of_ADDIs; addi_i++, addi++) {
- if (
- addi->instr &&
- addi->instr->args[0].arg == op->arg &&
- addi->instr->args[0].data.reg.reg == op->data.reg.reg
- )
- {
- if (addi->instr->block == block)
- bitvectorclearbit(addi_i, vec0);
- else
- bitvectorsetbit(addi_i, vec4);
- }
- }
- }
- op++;
- }
-
- if (
- instr->op == PC_ADDI &&
- instr->args[2].kind == PCOp_MEMORY &&
- (PCOpMemoryArg) instr->args[2].arg == PCOpMemory1 &&
- (array = lookup_vector_array_object(arrays, instr->args[2].data.mem.obj)) &&
- !array->invalid
- )
- {
- bitvectorsetbit(index, vec0);
- index++;
- }
- }
- }
- }
-}
-
-static void computeglobalvectorpropinfo(void) {
- VectorPropInfo *info;
- PCodeBlock *block;
- UInt32 *vec0;
- UInt32 *vec4;
- UInt32 *vec8;
- UInt32 *vecC;
- int bitvecsize;
- int blockIndex;
- int i;
- int j;
- int flag;
- PCLink *preds;
- UInt32 val;
-
- bitvecsize = (number_of_ADDIs + 31) >> 5;
- flag = 1;
- info = &vectorpropinfo[pcbasicblocks->blockIndex];
- bitvectorinitialize(info->in, number_of_ADDIs, 0);
- bitvectorcopy(info->out, info->use, number_of_ADDIs);
-
- for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
- info = &vectorpropinfo[block->blockIndex];
- vecC = info->out;
- vec4 = info->def;
- for (i = 0; i < bitvecsize; vecC++, vec4++, i++)
- *vecC = ~*vec4;
- }
-
- while (flag) {
- flag = 0;
- for (blockIndex = 0; blockIndex < pcblockcount; blockIndex++) {
- if (depthfirstordering[blockIndex]) {
- info = &vectorpropinfo[depthfirstordering[blockIndex]->blockIndex];
- if ((preds = depthfirstordering[blockIndex]->predecessors)) {
- vec8 = info->in;
- bitvectorcopy(vec8, vectorpropinfo[preds->block->blockIndex].out, number_of_ADDIs);
- for (preds = preds->nextLink; preds; preds = preds->nextLink)
- bitvectorintersect(vec8, vectorpropinfo[preds->block->blockIndex].out, number_of_ADDIs);
- }
-
- vecC = info->out;
- vec8 = info->in;
- vec0 = info->use;
- vec4 = info->def;
- for (j = 0; j < bitvecsize; j++) {
- val = *vec0 | (*vec8 & ~*vec4);
- if (val != *vecC) {
- *vecC = val;
- flag = 1;
- }
- vec8++;
- vecC++;
- vec4++;
- vec0++;
- }
- }
- }
- }
-}
-
-static int precedes(PCode *a, PCode *b) {
- PCode *scan;
-
- for (scan = a->nextPCode; scan; scan = scan->nextPCode) {
- if (scan == b)
- return 1;
- }
-
- return 0;
-}
-
-static int checkvectorstoreorload(int addiID, int useID) {
- PCode *addiInstr;
- UseOrDef *use;
-
- addiInstr = ADDIs[addiID].instr;
- use = Uses + useID;
- if (!addiInstr)
- return 0;
-
- if (addiInstr->args[0].data.reg.reg < n_real_registers[RegClass_GPR])
- return 0;
-
- if (use->pcode->op != PC_LVX && use->pcode->op != PC_STVX)
- return 0;
-
- if (
- use->pcode->args[1].kind != PCOp_REGISTER ||
- use->pcode->args[1].arg != RegClass_GPR ||
- use->pcode->args[1].data.reg.reg != 0
- )
- return 0;
-
- return use->pcode->args[2].data.reg.reg == addiInstr->args[0].data.reg.reg;
-}
-
-static int checkalluses(LocalVectorArray *arrays, int addiID) {
- RegUseOrDef *list;
- PCode *instr;
- LocalVectorArray *array;
-
- instr = ADDIs[addiID].instr;
- for (list = ADDIs[addiID].list; list; list = list->next) {
- if (list && !checkvectorstoreorload(addiID, list->id)) {
- array = lookup_vector_array_object(arrays, instr->args[2].data.mem.obj);
- array->invalid = 1;
- return 0;
- }
- }
-
- return 1;
-}
-
-static void convert_array_to_register(LocalVectorArray *arrays, int addiID) {
- ADDI *addi;
- int newReg;
- RegUseOrDef *list;
- PCode *instr;
- PCode *useInstr;
- LocalVectorArray *array;
- int element;
-
- addi = ADDIs + addiID;
-
- if (!(instr = addi->instr))
- return;
-
- if (
- !(array = lookup_vector_array_object(arrays, instr->args[2].data.mem.obj)) ||
- array->invalid
- )
- return;
-
- element = instr->args[2].data.mem.offset / 16;
- if (element > array->elementCount)
- return;
-
- newReg = array->elements[element];
- for (list = addi->list; list; list = list->next) {
- useInstr = Uses[list->id].pcode;
- if (useInstr->op == PC_LVX) {
- converted_arrays = 1;
- change_opcode(useInstr, PC_VMR);
- change_num_operands(useInstr, 2);
- useInstr->args[1].kind = PCOp_REGISTER;
- useInstr->args[1].arg = RegClass_VR;
- useInstr->args[1].data.reg.reg = newReg;
- useInstr->args[1].data.reg.effect = EffectRead;
- } else if (useInstr->op == PC_STVX) {
- converted_arrays = 1;
- change_opcode(useInstr, PC_VMR);
- change_num_operands(useInstr, 2);
- useInstr->args[1] = useInstr->args[0];
- useInstr->args[0].kind = PCOp_REGISTER;
- useInstr->args[0].arg = RegClass_VR;
- useInstr->args[0].data.reg.reg = newReg;
- useInstr->args[0].data.reg.effect = EffectWrite;
- } else {
- CError_FATAL(661);
- }
- }
- deletepcode(addi->instr);
-}
-
-static void convert_arrays_to_registers(LocalVectorArray *arrays) {
- int i;
- int counter;
- LocalVectorArray **ptr;
- LocalVectorArray *array;
-
- for (i = 0; i < number_of_ADDIs; i++)
- checkalluses(arrays, i);
-
- counter = 0;
- ptr = &arrays;
- array = *ptr;
- while (array) {
- if (array->invalid) {
- *ptr = array->next;
- array = *ptr;
- continue;
- }
-
- counter += array->elementCount;
-
- for (i = 0; i < array->elementCount; i++)
- array->totalUses += array->elements[i];
-
- array = array->next;
- }
-
- if (arrays) {
- while (counter > 32) {
- LocalVectorArray *best;
- int score;
- score = 0;
- best = NULL;
- for (array = arrays; array; array = array->next) {
- if (best) {
- if (array->totalUses < score) {
- score = array->totalUses;
- best = array;
- }
- } else {
- best = array;
- score = array->totalUses;
- }
- }
-
- if (!best)
- break;
-
- if (best == arrays) {
- arrays = best->next;
- } else {
- for (array = arrays; array; array = array->next) {
- if (array->next == best) {
- array->next = best->next;
- break;
- }
- }
- }
-
- counter -= best->elementCount;
- }
-
- if (!(array = arrays))
- return;
-
- while (array) {
- for (i = 0; i < array->elementCount; i++)
- array->elements[i] = used_virtual_registers[RegClass_VR]++;
- array = array->next;
- }
-
- if (arrays) {
- for (i = 0; i < number_of_ADDIs; i++)
- convert_array_to_register(arrays, i);
- }
- }
-}
-
-int vectorarraystoregs(void) {
- LocalVectorArray *arrays;
-
- converted_arrays = 0;
- if ((arrays = scanforlocalvectorarrays())) {
- scaninstructions(arrays);
- if (number_of_ADDIs > 0) {
- computeusedefchains(0);
- computeaddilist(arrays);
- allocatevectorpropinfo();
- computelocalvectorpropinfo(arrays);
- computedepthfirstordering();
- computeglobalvectorpropinfo();
- convert_arrays_to_registers(arrays);
- }
- }
-
- freeoheap();
- return converted_arrays;
-}