mirror of https://git.wuffs.org/MWCC
dump lots more code
This commit is contained in:
parent
bc1321735c
commit
fcfbafff31
|
@ -113,7 +113,7 @@ add_executable(mwcc
|
||||||
compiler_and_linker/unsorted/PCodeUtilities.c
|
compiler_and_linker/unsorted/PCodeUtilities.c
|
||||||
compiler_and_linker/unsorted/Operands.c
|
compiler_and_linker/unsorted/Operands.c
|
||||||
compiler_and_linker/unsorted/Exceptions.c
|
compiler_and_linker/unsorted/Exceptions.c
|
||||||
|
compiler_and_linker/unsorted/uDump.c
|
||||||
compiler_and_linker/unsorted/COptimizer.c
|
compiler_and_linker/unsorted/COptimizer.c
|
||||||
compiler_and_linker/unsorted/GlobalOptimizer.c
|
compiler_and_linker/unsorted/GlobalOptimizer.c
|
||||||
compiler_and_linker/unsorted/PCodeListing.c
|
compiler_and_linker/unsorted/PCodeListing.c
|
||||||
|
@ -131,7 +131,8 @@ add_executable(mwcc
|
||||||
compiler_and_linker/unsorted/FuncLevelAsmPPC.c
|
compiler_and_linker/unsorted/FuncLevelAsmPPC.c
|
||||||
compiler_and_linker/unsorted/CException.c
|
compiler_and_linker/unsorted/CException.c
|
||||||
compiler_and_linker/unsorted/CTemplateClass.c
|
compiler_and_linker/unsorted/CTemplateClass.c
|
||||||
|
compiler_and_linker/unsorted/ScanFloat.c
|
||||||
|
compiler_and_linker/unsorted/CExprConvMatch.c
|
||||||
compiler_and_linker/unsorted/CRTTI.c
|
compiler_and_linker/unsorted/CRTTI.c
|
||||||
compiler_and_linker/unsorted/CObjCModern.c
|
compiler_and_linker/unsorted/CObjCModern.c
|
||||||
compiler_and_linker/unsorted/InlineAsm.c
|
compiler_and_linker/unsorted/InlineAsm.c
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "compiler/CompilerTools.h"
|
#include "compiler/CompilerTools.h"
|
||||||
|
#include "compiler/CInt64.h"
|
||||||
#include "cos.h"
|
#include "cos.h"
|
||||||
|
|
||||||
extern Boolean systemHandles;
|
extern Boolean systemHandles;
|
||||||
|
@ -140,6 +141,7 @@ void AppendGListTargetEndianWord(GList *gl, SInt16 theword) {
|
||||||
|
|
||||||
ptr = *gl->data + gl->size;
|
ptr = *gl->data + gl->size;
|
||||||
gl->size += 2;
|
gl->size += 2;
|
||||||
|
theword = CTool_EndianConvertWord16(theword);
|
||||||
*(ptr++) = ((unsigned char *) &theword)[0];
|
*(ptr++) = ((unsigned char *) &theword)[0];
|
||||||
*(ptr++) = ((unsigned char *) &theword)[1];
|
*(ptr++) = ((unsigned char *) &theword)[1];
|
||||||
}
|
}
|
||||||
|
@ -170,6 +172,7 @@ void AppendGListTargetEndianLong(GList *gl, SInt32 theword) {
|
||||||
|
|
||||||
ptr = *gl->data + gl->size;
|
ptr = *gl->data + gl->size;
|
||||||
gl->size += 4;
|
gl->size += 4;
|
||||||
|
theword = CTool_EndianConvertWord32(theword);
|
||||||
*(ptr++) = ((unsigned char *) &theword)[0];
|
*(ptr++) = ((unsigned char *) &theword)[0];
|
||||||
*(ptr++) = ((unsigned char *) &theword)[1];
|
*(ptr++) = ((unsigned char *) &theword)[1];
|
||||||
*(ptr++) = ((unsigned char *) &theword)[2];
|
*(ptr++) = ((unsigned char *) &theword)[2];
|
||||||
|
@ -1157,26 +1160,56 @@ short getbit(SInt32 l) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENDIAN_CONVERSION
|
||||||
|
UInt16 CTool_EndianConvertWord16(UInt16 theword) {
|
||||||
|
UInt16 conv;
|
||||||
|
((UInt8 *) &conv)[0] = ((UInt8 *) &theword)[1];
|
||||||
|
((UInt8 *) &conv)[1] = ((UInt8 *) &theword)[0];
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 CTool_EndianConvertWord32(UInt32 theword) {
|
||||||
|
UInt32 conv;
|
||||||
|
((UInt8 *) &conv)[0] = ((UInt8 *) &theword)[3];
|
||||||
|
((UInt8 *) &conv)[1] = ((UInt8 *) &theword)[2];
|
||||||
|
((UInt8 *) &conv)[2] = ((UInt8 *) &theword)[1];
|
||||||
|
((UInt8 *) &conv)[3] = ((UInt8 *) &theword)[0];
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTool_EndianConvertMem(UInt8 *data, short len) {
|
||||||
|
UInt8 *a = data;
|
||||||
|
UInt8 *b = data + len;
|
||||||
|
while (--b > a) {
|
||||||
|
UInt8 val = *b;
|
||||||
|
*b = *a;
|
||||||
|
*a++ = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CTool_EndianConvertWord64(CInt64 ci, char *result) {
|
void CTool_EndianConvertWord64(CInt64 ci, char *result) {
|
||||||
UInt32 buf[2];
|
UInt32 buf[2];
|
||||||
buf[0] = ci.hi;
|
buf[0] = CTool_EndianConvertWord32(CTool_EndianReadWord32(&ci.hi));
|
||||||
buf[1] = ci.lo;
|
buf[1] = CTool_EndianConvertWord32(CInt64_GetULong(&ci));
|
||||||
memcpy(result, buf, 8);
|
memcpy(result, buf, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENDIAN_CONVERSION
|
||||||
|
UInt32 CTool_EndianReadWord32(void *ptr) {
|
||||||
|
return *((UInt32 *) ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x) {
|
UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x) {
|
||||||
unsigned short v;
|
UInt16 v;
|
||||||
v = *x;
|
*x = v = CTool_EndianConvertWord16(*x);
|
||||||
// this probably has a conversion on non-ppc
|
|
||||||
*x = v;
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x) {
|
UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x) {
|
||||||
unsigned long v;
|
UInt32 v;
|
||||||
v = *x;
|
*x = v = CTool_EndianConvertWord32(*x);
|
||||||
// this probably has a conversion on non-ppc
|
|
||||||
*x = v;
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,7 @@ static int addpropagatestouse(int candidateID, int useID) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 225
|
CError_FATAL(225);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,8 +199,7 @@ static void propagateandremoveadd(int id) {
|
||||||
useInstr->args[2] = instr->args[2];
|
useInstr->args[2] = instr->args[2];
|
||||||
useInstr->alias = instr->alias;
|
useInstr->alias = instr->alias;
|
||||||
} else if (useInstr->op == PC_ADDI) {
|
} else if (useInstr->op == PC_ADDI) {
|
||||||
#line 338
|
CError_ASSERT(338, useInstr->args[2].data.imm.value == 0);
|
||||||
CError_ASSERT(useInstr->args[2].data.imm.value == 0);
|
|
||||||
change_opcode(useInstr, PC_ADD);
|
change_opcode(useInstr, PC_ADD);
|
||||||
useInstr->args[1] = instr->args[1];
|
useInstr->args[1] = instr->args[1];
|
||||||
useInstr->args[2] = instr->args[2];
|
useInstr->args[2] = instr->args[2];
|
||||||
|
@ -214,8 +212,7 @@ static void propagateandremoveadd(int id) {
|
||||||
useInstr->args[2] = instr->args[2];
|
useInstr->args[2] = instr->args[2];
|
||||||
useInstr->alias = instr->alias;
|
useInstr->alias = instr->alias;
|
||||||
} else {
|
} else {
|
||||||
#line 352
|
CError_FATAL(352);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else if (useInstr->op == PC_MR) {
|
} else if (useInstr->op == PC_MR) {
|
||||||
change_opcode(useInstr, PC_ADDI);
|
change_opcode(useInstr, PC_ADDI);
|
||||||
|
@ -242,8 +239,7 @@ static void propagateandremoveadd(int id) {
|
||||||
useInstr->args[2].data.mem.offset,
|
useInstr->args[2].data.mem.offset,
|
||||||
nbytes_loaded_or_stored_by(useInstr));
|
nbytes_loaded_or_stored_by(useInstr));
|
||||||
} else {
|
} else {
|
||||||
#line 382
|
CError_FATAL(382);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,8 +164,7 @@ void add_alias_member(Alias *parent, Alias *child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Alias *make_alias_set_from_IR(void) {
|
Alias *make_alias_set_from_IR(void) {
|
||||||
#line 333
|
CError_FATAL(333);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +255,7 @@ static int addresspropagatestouse(int candidateID, int useID) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 478
|
CError_ASSERT(478, object->otype == OT_OBJECT);
|
||||||
CError_ASSERT(object->otype == OT_OBJECT);
|
|
||||||
|
|
||||||
if ((candidate_pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) && (candidate_pcode->flags & fPCodeFlag2000000)) {
|
if ((candidate_pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) && (candidate_pcode->flags & fPCodeFlag2000000)) {
|
||||||
reg = candidate_pcode->args[1].data.reg.reg;
|
reg = candidate_pcode->args[1].data.reg.reg;
|
||||||
|
@ -268,8 +266,7 @@ static int addresspropagatestouse(int candidateID, int useID) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
object = object->u.var.realObj;
|
object = object->u.var.realObj;
|
||||||
#line 495
|
CError_ASSERT(495, object->otype == OT_OBJECT);
|
||||||
CError_ASSERT(object->otype == OT_OBJECT);
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
} else if (candidate_pcode->op == PC_ADDI) {
|
} else if (candidate_pcode->op == PC_ADDI) {
|
||||||
if (!candidate_pcode->alias && object)
|
if (!candidate_pcode->alias && object)
|
||||||
|
@ -281,8 +278,7 @@ static int addresspropagatestouse(int candidateID, int useID) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
flag24 = 1;
|
flag24 = 1;
|
||||||
} else {
|
} else {
|
||||||
#line 509
|
CError_FATAL(509);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -309,8 +305,7 @@ static int addresspropagatestouse(int candidateID, int useID) {
|
||||||
if (use_pcode->argCount < 3)
|
if (use_pcode->argCount < 3)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#line 543
|
CError_ASSERT(543, use_pcode->args[1].kind == PCOp_REGISTER);
|
||||||
CError_ASSERT(use_pcode->args[1].kind == PCOp_REGISTER);
|
|
||||||
|
|
||||||
if (candidate_pcode->block == use_pcode->block && precedes(candidate_pcode, use_pcode)) {
|
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 (scan = candidate_pcode->nextPCode; scan && scan != use_pcode; scan = scan->nextPCode) {
|
||||||
|
@ -361,8 +356,7 @@ static int addresspropagatestouse(int candidateID, int useID) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 598
|
CError_ASSERT(598, object != NULL);
|
||||||
CError_ASSERT(object != NULL);
|
|
||||||
|
|
||||||
if (use_pcode->op == PC_ADDI || use_pcode->op == PC_ADD || use_pcode->op == PC_ADDIS) {
|
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))
|
if (use_pcode->args[0].data.reg.reg < n_real_registers[RegClass_GPR] && !is_safe_const(object))
|
||||||
|
@ -653,8 +647,7 @@ static Boolean may_alias_alias(Alias *a, Alias *b) {
|
||||||
case (AliasType2 * 3) + AliasType2:
|
case (AliasType2 * 3) + AliasType2:
|
||||||
return (a == b) || !bitvectorintersectionisempty(a->vec24, b->vec24, n_aliases);
|
return (a == b) || !bitvectorintersectionisempty(a->vec24, b->vec24, n_aliases);
|
||||||
default:
|
default:
|
||||||
#line 1054
|
CError_FATAL(1054);
|
||||||
CError_FATAL();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,18 +698,15 @@ void update_alias_value(Alias *alias, PCode *pcode) {
|
||||||
case AliasType0:
|
case AliasType0:
|
||||||
killmemory(alias, pcode);
|
killmemory(alias, pcode);
|
||||||
for (member = alias->children; member; member = member->nextChild) {
|
for (member = alias->children; member; member = member->nextChild) {
|
||||||
#line 1152
|
CError_ASSERT(1152, member->parent->type == AliasType2);
|
||||||
CError_ASSERT(member->parent->type == AliasType2);
|
|
||||||
killmemory(member->parent, NULL);
|
killmemory(member->parent, NULL);
|
||||||
}
|
}
|
||||||
for (member = alias->parents; member; member = member->nextParent) {
|
for (member = alias->parents; member; member = member->nextParent) {
|
||||||
#line 1157
|
CError_ASSERT(1157, member->child->type == AliasType1);
|
||||||
CError_ASSERT(member->child->type == AliasType1);
|
|
||||||
killmemory(member->child, NULL);
|
killmemory(member->child, NULL);
|
||||||
for (member2 = member->child->children; member2; member2 = member2->nextChild) {
|
for (member2 = member->child->children; member2; member2 = member2->nextChild) {
|
||||||
if (member2->parent != alias) {
|
if (member2->parent != alias) {
|
||||||
#line 1163
|
CError_ASSERT(1163, member2->parent->type == AliasType2);
|
||||||
CError_ASSERT(member2->parent->type == AliasType2);
|
|
||||||
killmemory(member2->parent, NULL);
|
killmemory(member2->parent, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void CABI_GetBaseVTableSize() {}
|
||||||
static void CABI_ApplyClassFlags() {}
|
static void CABI_ApplyClassFlags() {}
|
||||||
static void CABI_AllocateVTable() {}
|
static void CABI_AllocateVTable() {}
|
||||||
void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) {}
|
void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) {}
|
||||||
void CABI_MakeDefaultArgConstructor(Object *obj, TypeClass *tclass) {}
|
void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *obj) {}
|
||||||
static void CABI_ThisArg() {}
|
static void CABI_ThisArg() {}
|
||||||
ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {}
|
ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {}
|
||||||
static void CABI_VArg() {}
|
static void CABI_VArg() {}
|
||||||
|
|
|
@ -0,0 +1,737 @@
|
||||||
|
#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(CParams *params) {
|
||||||
|
BrowseHeader hdr;
|
||||||
|
|
||||||
|
CError_ASSERT(123, params != NULL);
|
||||||
|
|
||||||
|
params->objectdata.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(CParams *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->objectdata.browsedata = hnd;
|
||||||
|
gBrowseData.data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBrowse_Cleanup(CParams *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->x60 <= 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->x60 - 1);
|
||||||
|
CError_ASSERT(270, gClassData.size == 9);
|
||||||
|
AppendGListLong(&gClassData, di->x60 - 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_FLAGS_800) && !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;
|
||||||
|
TypeMethod *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_FLAGS_100)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (object->datatype == DVFUNC)
|
||||||
|
flags |= kVirtual;
|
||||||
|
if (tfunc->flags & FUNC_FLAGS_8)
|
||||||
|
flags |= kAbstract;
|
||||||
|
if (tfunc->x26)
|
||||||
|
flags |= kStatic;
|
||||||
|
if (tfunc->flags & FUNC_FLAGS_1000)
|
||||||
|
flags |= kCtor;
|
||||||
|
if (tfunc->flags & FUNC_FLAGS_2000)
|
||||||
|
flags |= kDtor;
|
||||||
|
|
||||||
|
AppendGListByte(&gClassData, memberFunction);
|
||||||
|
AppendGListByte(&gClassData, gFromAccessType[object->access]);
|
||||||
|
AppendGListLong(&gClassData, flags);
|
||||||
|
|
||||||
|
id = tfunc->x22;
|
||||||
|
if (id <= 0) {
|
||||||
|
// TODO: this is not 64-bit safe
|
||||||
|
if (!(tfunc->flags & FUNC_FLAGS_2) || id == -1)
|
||||||
|
AppendGListLong(&gMemberFuncList, (SInt32) object);
|
||||||
|
tfunc->x22 = 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->x60 <= 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->x60 - 1);
|
||||||
|
CError_ASSERT(521, gClassData.size == 9);
|
||||||
|
AppendGListLong(&gClassData, di->x60 - 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_FLAGS_100 | FUNC_FLAGS_200)) && (!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_FLAGS_1000 | FUNC_FLAGS_2000)) {
|
||||||
|
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_FLAGS_2000) {
|
||||||
|
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_FLAGS_METHOD)
|
||||||
|
flags |= kMember;
|
||||||
|
AppendGListLong(&gBrowseData, flags);
|
||||||
|
|
||||||
|
funcid = 0;
|
||||||
|
if (tfunc->flags & FUNC_FLAGS_METHOD) {
|
||||||
|
funcid = TYPE_METHOD(tfunc)->x22;
|
||||||
|
if (funcid <= 0) {
|
||||||
|
TYPE_METHOD(tfunc)->x22 = 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_FLAGS_2))
|
||||||
|
RecordFunction(*array, 0, 0, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
COS_UnlockHandle(gMemberFuncList.data);
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ extern void CTemplClass_RegisterBaseClass(TemplClass *tmclass, Type *baseclass,
|
||||||
extern void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *obj);
|
extern void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *obj);
|
||||||
extern void CTemplClass_RegisterObjectInit(TemplClass *tmclass, ObjBase *obj, ENode *expr);
|
extern void CTemplClass_RegisterObjectInit(TemplClass *tmclass, ObjBase *obj, ENode *expr);
|
||||||
extern void CTemplClass_DefineMember(TemplClass *tmclass, Object *obj, FileOffsetInfo *fileoffset, TStream *stream);
|
extern void CTemplClass_DefineMember(TemplClass *tmclass, Object *obj, FileOffsetInfo *fileoffset, TStream *stream);
|
||||||
extern void CTemplClass_CompleteClass(TemplClass *tmclass, DeclE *decle);
|
extern void CTemplClass_CompleteClass(TemplClass *templ, DeclE *decle);
|
||||||
extern void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *tenum);
|
extern void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *tenum);
|
||||||
extern void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *oec, ENode *expr);
|
extern void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *oec, ENode *expr);
|
||||||
extern TypeClass *CTemplClass_DefineNestedClass(TemplClass *tmclass, HashNameNode *name, short mode);
|
extern TypeClass *CTemplClass_DefineNestedClass(TemplClass *tmclass, HashNameNode *name, short mode);
|
||||||
|
@ -4647,7 +4647,7 @@ void CDecl_CompleteClass(DeclE *decle, TypeClass *tclass) {
|
||||||
if (tclass->sominfo)
|
if (tclass->sominfo)
|
||||||
CSOM_ClassComplete(tclass);
|
CSOM_ClassComplete(tclass);
|
||||||
|
|
||||||
if ((tclass->flags & CLASS_FLAGS_800) && !TEMPL_CLASS_INST(tclass)->x47)
|
if ((tclass->flags & CLASS_FLAGS_800) && !TEMPL_CLASS_INST(tclass)->is_specialized)
|
||||||
tclass->action = CLASS_ACTION_0;
|
tclass->action = CLASS_ACTION_0;
|
||||||
|
|
||||||
if (!tclass->action)
|
if (!tclass->action)
|
||||||
|
@ -4860,9 +4860,9 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class
|
||||||
|
|
||||||
is_templ = (tclass->flags & CLASS_FLAGS_100) ? 1 : 0;
|
is_templ = (tclass->flags & CLASS_FLAGS_100) ? 1 : 0;
|
||||||
if (tclass->flags & CLASS_FLAGS_800) {
|
if (tclass->flags & CLASS_FLAGS_800) {
|
||||||
TEMPL_CLASS_INST(tclass)->x46 = 1;
|
TEMPL_CLASS_INST(tclass)->is_instantiated = 1;
|
||||||
if (!declinfo->x28)
|
if (!declinfo->x28)
|
||||||
TEMPL_CLASS_INST(tclass)->x47 = 1;
|
TEMPL_CLASS_INST(tclass)->is_specialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 6853
|
#line 6853
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
#include "cos.h"
|
#include "cos.h"
|
||||||
|
#include "compiler/CClass.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CFunc.h"
|
||||||
#include "compiler/CInt64.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/CompilerTools.h"
|
||||||
|
#include "compiler/InlineAsm.h"
|
||||||
|
#include "compiler/Unmangle.h"
|
||||||
#include "compiler/enode.h"
|
#include "compiler/enode.h"
|
||||||
#include "compiler/objc.h"
|
#include "compiler/objc.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler/scopes.h"
|
#include "compiler/scopes.h"
|
||||||
#include "compiler/templates.h"
|
#include "compiler/templates.h"
|
||||||
#include "compiler/tokens.h"
|
#include "compiler/tokens.h"
|
||||||
#include "compiler.h"
|
|
||||||
|
|
||||||
TStreamElement *cerror_locktoken;
|
TStreamElement *cerror_locktoken;
|
||||||
static TStreamElement *cerror_token;
|
static TStreamElement *cerror_token;
|
||||||
|
@ -49,8 +57,7 @@ void CError_ResetErrorSkip() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CError_GetErrorString(char *buf, short code) {
|
void CError_GetErrorString(char *buf, short code) {
|
||||||
#line 142
|
CError_ASSERT(142, code >= CErrorStr100 && code < CErrorStrMAX);
|
||||||
CError_ASSERT(code >= CErrorStr100 && code < CErrorStrMAX);
|
|
||||||
COS_GetString(buf, 10000, code - 99);
|
COS_GetString(buf, 10000, code - 99);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,8 +150,7 @@ void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) {
|
||||||
CError_BufferAppendType(eb, targ->data.ttargtype, 0);
|
CError_BufferAppendType(eb, targ->data.ttargtype, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 300
|
CError_FATAL(300);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,8 +244,7 @@ void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) {
|
||||||
CError_BufferAppendChar(eb, ']');
|
CError_BufferAppendChar(eb, ']');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 463
|
CError_FATAL(463);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,8 +355,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) {
|
||||||
CError_BufferAppendString(eb, "long double");
|
CError_BufferAppendString(eb, "long double");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 584
|
CError_FATAL(584);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPEENUM:
|
case TYPEENUM:
|
||||||
|
@ -384,8 +388,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) {
|
||||||
case STRUCT_TYPE_E:
|
case STRUCT_TYPE_E:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 618
|
CError_FATAL(618);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
if (TYPE_STRUCT(ty)->name)
|
if (TYPE_STRUCT(ty)->name)
|
||||||
CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name);
|
CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name);
|
||||||
|
@ -482,8 +485,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) {
|
||||||
CError_BufferAppendString(eb, buf);
|
CError_BufferAppendString(eb, buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 752
|
CError_FATAL(752);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,8 +627,7 @@ char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *opStr;
|
char *opStr;
|
||||||
|
|
||||||
#line 973
|
CError_ASSERT(973, operatorName);
|
||||||
CError_ASSERT(operatorName);
|
|
||||||
|
|
||||||
opStr = CMangler_GetOperator(operatorName);
|
opStr = CMangler_GetOperator(operatorName);
|
||||||
if (!opStr)
|
if (!opStr)
|
||||||
|
@ -784,8 +785,7 @@ void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean f
|
||||||
format += 2;
|
format += 2;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
#line 1174
|
CError_FATAL(1174);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -855,8 +855,7 @@ void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argN
|
||||||
|
|
||||||
while (args && args->object->otype != OT_OBJECT)
|
while (args && args->object->otype != OT_OBJECT)
|
||||||
args = args->next;
|
args = args->next;
|
||||||
#line 1268
|
CError_ASSERT(1268, args);
|
||||||
CError_ASSERT(args);
|
|
||||||
|
|
||||||
p = string;
|
p = string;
|
||||||
do {
|
do {
|
||||||
|
@ -956,7 +955,7 @@ void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CError_AbstractClassError(TypeClass *tclass) {
|
void CError_AbstractClassError(TypeClass *tclass) {
|
||||||
int result = CClass_CheckPures(tclass);
|
Object *result = CClass_CheckPures(tclass);
|
||||||
if (!result)
|
if (!result)
|
||||||
CError_Error(372, tclass, 0);
|
CError_Error(372, tclass, 0);
|
||||||
else
|
else
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1053,7 +1053,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool
|
||||||
switch (pr->obj_10->otype) {
|
switch (pr->obj_10->otype) {
|
||||||
case OT_OBJECT:
|
case OT_OBJECT:
|
||||||
if (OBJECT(pr->obj_10)->nspace && OBJECT(pr->obj_10)->nspace->theclass && (OBJECT(pr->obj_10)->nspace->theclass->flags & CLASS_FLAGS_100)) {
|
if (OBJECT(pr->obj_10)->nspace && OBJECT(pr->obj_10)->nspace->theclass && (OBJECT(pr->obj_10)->nspace->theclass->flags & CLASS_FLAGS_100)) {
|
||||||
result = CExpr_NewTemplDepENode(TDE_QUALTEMPL); // not sure this is right tbh
|
result = CExpr_NewTemplDepENode(TDE_OBJ);
|
||||||
result->data.templdep.u.obj = OBJECT(pr->obj_10);
|
result->data.templdep.u.obj = OBJECT(pr->obj_10);
|
||||||
tk = lex();
|
tk = lex();
|
||||||
return result;
|
return result;
|
||||||
|
@ -2143,8 +2143,8 @@ static ENode *CExpr_ParseSizeof(void) {
|
||||||
CError_Error(286);
|
CError_Error(286);
|
||||||
|
|
||||||
if (CTemplTool_IsTemplateArgumentDependentType(type)) {
|
if (CTemplTool_IsTemplateArgumentDependentType(type)) {
|
||||||
expr = CExpr_NewTemplDepENode(TDE_TYPEEXPR);
|
expr = CExpr_NewTemplDepENode(TDE_SIZEOF);
|
||||||
expr->data.templdep.u.typeexpr.u.type = type;
|
expr->data.templdep.u.typeexpr.type = type;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2183,8 +2183,8 @@ static ENode *CExpr_ParseAlignof(void) {
|
||||||
CError_Error(364);
|
CError_Error(364);
|
||||||
|
|
||||||
if (CTemplTool_IsTemplateArgumentDependentType(type)) {
|
if (CTemplTool_IsTemplateArgumentDependentType(type)) {
|
||||||
expr = CExpr_NewTemplDepENode(TDE_unk2);
|
expr = CExpr_NewTemplDepENode(TDE_ALIGNOF);
|
||||||
expr->data.templdep.u.typeexpr.u.type = type;
|
expr->data.templdep.u.typeexpr.type = type;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2629,7 +2629,7 @@ ENode *unary_expression(void) {
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
if (IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
|
if (IS_TYPE_TEMPLDEPEXPR(expr->rtype)) {
|
||||||
tmp = CExpr_NewTemplDepENode(TDE_MONAND);
|
tmp = CExpr_NewTemplDepENode(TDE_ADDRESS_OF);
|
||||||
tmp->data.templdep.u.monadic = expr;
|
tmp->data.templdep.u.monadic = expr;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -4861,7 +4861,7 @@ static Boolean CExpr_HasSideEffect(ENode *expr) {
|
||||||
case ELABEL:
|
case ELABEL:
|
||||||
case ENEWEXCEPTION:
|
case ENEWEXCEPTION:
|
||||||
case ENEWEXCEPTIONARRAY:
|
case ENEWEXCEPTIONARRAY:
|
||||||
case EMYSTERY67:
|
case EINITTRYCATCH:
|
||||||
case EINSTRUCTION:
|
case EINSTRUCTION:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -161,7 +161,7 @@ restart:
|
||||||
CExpr_RecSearchExprTree(expr->data.newexception.initexpr);
|
CExpr_RecSearchExprTree(expr->data.newexception.initexpr);
|
||||||
expr = expr->data.newexception.tryexpr;
|
expr = expr->data.newexception.tryexpr;
|
||||||
goto restart;
|
goto restart;
|
||||||
case EMYSTERY67:
|
case EINITTRYCATCH:
|
||||||
if (expr->data.itc.initexpr)
|
if (expr->data.itc.initexpr)
|
||||||
CExpr_RecSearchExprTree(expr->data.itc.initexpr);
|
CExpr_RecSearchExprTree(expr->data.itc.initexpr);
|
||||||
if (expr->data.itc.tryexpr)
|
if (expr->data.itc.tryexpr)
|
||||||
|
@ -3745,7 +3745,7 @@ static ENode *CExpr_NewExceptionSafeAlloc(Type *type, ENode *node, ENodeList *ar
|
||||||
} else {
|
} else {
|
||||||
if (!catchexpr)
|
if (!catchexpr)
|
||||||
catchexpr = CExpr_DeleteFuncCall(deletefunc, create_objectnode(obj), type, include_size);
|
catchexpr = CExpr_DeleteFuncCall(deletefunc, create_objectnode(obj), type, include_size);
|
||||||
result->type = EMYSTERY67;
|
result->type = EINITTRYCATCH;
|
||||||
result->data.itc.initexpr = node;
|
result->data.itc.initexpr = node;
|
||||||
result->data.itc.tryexpr = NULL;
|
result->data.itc.tryexpr = NULL;
|
||||||
result->data.itc.result = create_objectnode(obj);
|
result->data.itc.result = create_objectnode(obj);
|
||||||
|
@ -3760,7 +3760,7 @@ static ENode *CExpr_NewExceptionSafeInit(ENode *expr, ENode *tryexpr) {
|
||||||
case ENEWEXCEPTION:
|
case ENEWEXCEPTION:
|
||||||
expr->data.newexception.tryexpr = tryexpr;
|
expr->data.newexception.tryexpr = tryexpr;
|
||||||
break;
|
break;
|
||||||
case EMYSTERY67:
|
case EINITTRYCATCH:
|
||||||
expr->data.itc.tryexpr = tryexpr;
|
expr->data.itc.tryexpr = tryexpr;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "compiler/CExpr.h"
|
|
@ -89,7 +89,7 @@ static void CFunc_AdjustOldStyleArgs(void) {}
|
||||||
void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args) {}
|
void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args) {}
|
||||||
static ObjectList *CFunc_CopyObjectList(ObjectList *list) {}
|
static ObjectList *CFunc_CopyObjectList(ObjectList *list) {}
|
||||||
static void SetupFunctionArguments(Object *obj, DeclInfo *declinfo) {}
|
static void SetupFunctionArguments(Object *obj, DeclInfo *declinfo) {}
|
||||||
NameSpace *CFunc_FuncGenSetup(Statement *stmt) {}
|
NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func) {}
|
||||||
void CFunc_GetGlobalCompilerState(CFuncSave *state) {}
|
void CFunc_GetGlobalCompilerState(CFuncSave *state) {}
|
||||||
void CFunc_SetGlobalCompilerState(CFuncSave *state) {}
|
void CFunc_SetGlobalCompilerState(CFuncSave *state) {}
|
||||||
void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk) {}
|
void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk) {}
|
||||||
|
|
|
@ -0,0 +1,534 @@
|
||||||
|
#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_FLAGS_10;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -322,8 +322,7 @@ static Stage CInit_ParseNextInit(CInit_Stuff2 *s) {
|
||||||
s->stage = Stage3;
|
s->stage = Stage3;
|
||||||
return Stage3;
|
return Stage3;
|
||||||
default:
|
default:
|
||||||
#line 389
|
CError_FATAL(389);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tk) {
|
switch (tk) {
|
||||||
|
@ -417,8 +416,7 @@ static Boolean CInit_IsSimpleInit(Type *type) {
|
||||||
|
|
||||||
static Object *CInit_GetInitObject(Object *obj) {
|
static Object *CInit_GetInitObject(Object *obj) {
|
||||||
if (obj->datatype == DALIAS) {
|
if (obj->datatype == DALIAS) {
|
||||||
#line 521
|
CError_ASSERT(521, !obj->u.alias.offset);
|
||||||
CError_ASSERT(!obj->u.alias.offset);
|
|
||||||
obj = obj->u.alias.object;
|
obj = obj->u.alias.object;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -870,10 +868,8 @@ static void CInit_InitTypeStruct(CInit_Stuff *s, CInit_Stuff2 *s2, TypeStruct *t
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if (IS_TYPESTRUCT_VECTOR(tstruct) && s2->expr) {
|
if (IS_TYPESTRUCT_VECTOR(tstruct) && s2->expr)
|
||||||
#line 1218
|
CError_ASSERT(1218, !ENODE_IS(s2->expr, EVECTOR128CONST));
|
||||||
CError_ASSERT(!ENODE_IS(s2->expr, EVECTOR128CONST));
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
member = member->next;
|
member = member->next;
|
||||||
|
@ -1130,8 +1126,7 @@ static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32
|
||||||
CInit_InitTypeBitfield(s, s2->expr, TYPE_BITFIELD(type), qual);
|
CInit_InitTypeBitfield(s, s2->expr, TYPE_BITFIELD(type), qual);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1542
|
CError_FATAL(1542);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
|
@ -1157,8 +1152,7 @@ static void CInit_InitType(CInit_Stuff *s, CInit_Stuff2 *s2, Type *type, UInt32
|
||||||
CInit_InitTypeClass(s, s2, TYPE_CLASS(type), qual, errorflag);
|
CInit_InitTypeClass(s, s2, TYPE_CLASS(type), qual, errorflag);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1573
|
CError_FATAL(1573);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1203,8 +1197,7 @@ static void CInit_InitData(CInit_Stuff *s, Type *type, UInt32 qual, Boolean flag
|
||||||
if (s->x0) {
|
if (s->x0) {
|
||||||
buffer = lalloc(size);
|
buffer = lalloc(size);
|
||||||
for (tmp = s; tmp; tmp = tmp->x0) {
|
for (tmp = s; tmp; tmp = tmp->x0) {
|
||||||
#line 1647
|
CError_ASSERT(1647, (tmp->xC + tmp->size) <= size);
|
||||||
CError_ASSERT((tmp->xC + tmp->size) <= size);
|
|
||||||
memcpy(buffer + tmp->xC, tmp->buffer, tmp->size);
|
memcpy(buffer + tmp->xC, tmp->buffer, tmp->size);
|
||||||
}
|
}
|
||||||
s->buffer = buffer;
|
s->buffer = buffer;
|
||||||
|
@ -1522,8 +1515,7 @@ static void CInit_TypeExpr(Type *type, ENode *expr) {
|
||||||
CError_Error(174);
|
CError_Error(174);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2082
|
CError_FATAL(2082);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1883,8 +1875,7 @@ static void CInit_Type(Type *type, UInt32 qual, Boolean flag) {
|
||||||
CInit_Class(TYPE_CLASS(type), flag);
|
CInit_Class(TYPE_CLASS(type), flag);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2482
|
CError_FATAL(2482);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2020,8 +2011,7 @@ static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB exp
|
||||||
}
|
}
|
||||||
CInit_SetupInitInfoBuffer(type);
|
CInit_SetupInitInfoBuffer(type);
|
||||||
CInit_Type(type, obj->qual, 1);
|
CInit_Type(type, obj->qual, 1);
|
||||||
#line 2639
|
CError_ASSERT(2639, obj->type->size == (size = cinit_initinfo->size));
|
||||||
CError_ASSERT(obj->type->size == (size = cinit_initinfo->size));
|
|
||||||
if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, size)) {
|
if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, size)) {
|
||||||
CInit_AdjustObjectDataSize(obj);
|
CInit_AdjustObjectDataSize(obj);
|
||||||
CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
|
CInit_DeclareData(obj, cinit_initinfo->buffer, cinit_initinfo->list, obj->type->size);
|
||||||
|
@ -2098,8 +2088,7 @@ static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB exp
|
||||||
if (!obj || (flag && copts.cplusplus)) {
|
if (!obj || (flag && copts.cplusplus)) {
|
||||||
if (obj) {
|
if (obj) {
|
||||||
IsCompleteType(obj->type);
|
IsCompleteType(obj->type);
|
||||||
#line 2747
|
CError_ASSERT(2747, obj->type->size == type->size);
|
||||||
CError_ASSERT(obj->type->size == type->size);
|
|
||||||
CInit_DeclareData(obj, NULL, NULL, obj->type->size);
|
CInit_DeclareData(obj, NULL, NULL, obj->type->size);
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -2107,8 +2096,7 @@ static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB exp
|
||||||
|
|
||||||
CInit_SetupInitInfoBuffer(type);
|
CInit_SetupInitInfoBuffer(type);
|
||||||
CInit_TypeExpr(type, expr);
|
CInit_TypeExpr(type, expr);
|
||||||
#line 2756
|
CError_ASSERT(2756, obj->type->size == cinit_initinfo->size);
|
||||||
CError_ASSERT(obj->type->size == cinit_initinfo->size);
|
|
||||||
|
|
||||||
IsCompleteType(obj->type);
|
IsCompleteType(obj->type);
|
||||||
CInit_AdjustObjectDataSize(obj);
|
CInit_AdjustObjectDataSize(obj);
|
||||||
|
@ -2127,8 +2115,7 @@ static ENode *CInit_GenericData(Object *obj, Type *type, UInt32 qual, ExprCB exp
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 2776
|
CError_FATAL(2776);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2154,8 +2141,7 @@ void CInit_ExportConst(Object *obj) {
|
||||||
CMach_InitFloatMem(obj->type, *obj->u.data.u.floatconst, buffer);
|
CMach_InitFloatMem(obj->type, *obj->u.data.u.floatconst, buffer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2807
|
CError_FATAL(2807);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_const_object(obj))
|
if (is_const_object(obj))
|
||||||
|
@ -2414,16 +2400,14 @@ static void CInit_FindDtorTemp(ENode *expr) {
|
||||||
static void CInit_RefTempTransform(Type *type, ENode *expr) {
|
static void CInit_RefTempTransform(Type *type, ENode *expr) {
|
||||||
Object *obj;
|
Object *obj;
|
||||||
|
|
||||||
#line 3164
|
CError_ASSERT(3164, IS_TYPE_POINTER_ONLY(type));
|
||||||
CError_ASSERT(IS_TYPE_POINTER_ONLY(type));
|
|
||||||
|
|
||||||
if (IS_TYPE_CLASS(TYPE_POINTER(type)->target)) {
|
if (IS_TYPE_CLASS(TYPE_POINTER(type)->target)) {
|
||||||
cinit_fdtnode = NULL;
|
cinit_fdtnode = NULL;
|
||||||
cinit_fdtambig = 0;
|
cinit_fdtambig = 0;
|
||||||
CInit_FindDtorTemp(expr);
|
CInit_FindDtorTemp(expr);
|
||||||
if (cinit_fdtnode) {
|
if (cinit_fdtnode) {
|
||||||
#line 3172
|
CError_ASSERT(3172, !cinit_fdtambig);
|
||||||
CError_ASSERT(!cinit_fdtambig);
|
|
||||||
obj = create_temp_object(cinit_fdtnode->node->data.temp.type);
|
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_initinfo->register_object_cb(cinit_fdtnode->node->data.temp.type, obj, 0, 0);
|
||||||
cinit_fdtnode->node = create_objectrefnode(obj);
|
cinit_fdtnode->node = create_objectrefnode(obj);
|
||||||
|
@ -2448,8 +2432,7 @@ static Boolean CInit_InitReference(Object *obj, Boolean flag) {
|
||||||
cinit_initinfo->expr_cb = CInit_RefInit;
|
cinit_initinfo->expr_cb = CInit_RefInit;
|
||||||
CInit_SetupInitInfoBuffer(obj->type);
|
CInit_SetupInitInfoBuffer(obj->type);
|
||||||
CInit_ExprPointer(TYPE_POINTER(obj->type), expr);
|
CInit_ExprPointer(TYPE_POINTER(obj->type), expr);
|
||||||
#line 3213
|
CError_ASSERT(3213, obj->type->size == cinit_initinfo->size);
|
||||||
CError_ASSERT(obj->type->size == cinit_initinfo->size);
|
|
||||||
|
|
||||||
if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) {
|
if (cinit_initinfo->list || !CInit_IsAllZero(cinit_initinfo->buffer, obj->type->size)) {
|
||||||
IsCompleteType(obj->type);
|
IsCompleteType(obj->type);
|
||||||
|
@ -3000,8 +2983,7 @@ void CInit_RewriteString(ENode *expr, Boolean flag) {
|
||||||
if (cparamblkptr->isPrecompiling == 1)
|
if (cparamblkptr->isPrecompiling == 1)
|
||||||
CError_Error(180);
|
CError_Error(180);
|
||||||
|
|
||||||
#line 4220
|
CError_ASSERT(4220, expr->rtype->type == TYPEPOINTER);
|
||||||
CError_ASSERT(expr->rtype->type == TYPEPOINTER);
|
|
||||||
|
|
||||||
is_wide = TYPE_POINTER(expr->rtype)->target->size != 1;
|
is_wide = TYPE_POINTER(expr->rtype)->target->size != 1;
|
||||||
if (copts.pool_strings) {
|
if (copts.pool_strings) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,11 @@
|
||||||
#include "compiler.h"
|
#include "compiler/CMachine.h"
|
||||||
|
#include "compiler/CClass.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/CError.h"
|
||||||
#include "compiler/CInt64.h"
|
#include "compiler/CInt64.h"
|
||||||
|
#include "compiler/CParser.h"
|
||||||
|
#include "compiler/CPrep.h"
|
||||||
|
#include "compiler/CPrepTokenizer.h"
|
||||||
|
#include "compiler/CompilerTools.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler/types.h"
|
#include "compiler/types.h"
|
||||||
|
|
||||||
|
@ -157,10 +162,8 @@ SInt32 CMach_GetQUALalign(UInt32 qual) {
|
||||||
result = 4096;
|
result = 4096;
|
||||||
else if (chk == Q_ALIGNED_8192)
|
else if (chk == Q_ALIGNED_8192)
|
||||||
result = 8192;
|
result = 8192;
|
||||||
else {
|
else
|
||||||
#line 226
|
CError_FATAL(226);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -240,8 +243,7 @@ CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right) {
|
||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 327
|
CError_FATAL(327);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -339,8 +341,7 @@ CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right) {
|
||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 389
|
CError_FATAL(389);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -441,8 +442,7 @@ CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val) {
|
||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 448
|
CError_FATAL(448);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -486,8 +486,7 @@ CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val) {
|
||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 478
|
CError_FATAL(478);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -549,28 +548,26 @@ void CMach_InitIntMem(Type *type, CInt64 val, void *mem) {
|
||||||
case TYPEINT:
|
case TYPEINT:
|
||||||
switch (type->size) {
|
switch (type->size) {
|
||||||
case 1:
|
case 1:
|
||||||
ch = (UInt8) val.lo;
|
ch = (UInt8) CInt64_GetULong(&val);
|
||||||
memcpy(mem, &ch, 1);
|
memcpy(mem, &ch, 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sh = (UInt16) val.lo;
|
sh = (UInt16) CTool_EndianConvertWord16(CInt64_GetULong(&val));
|
||||||
memcpy(mem, &sh, 2);
|
memcpy(mem, &sh, 2);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
lg = (UInt32) val.lo;
|
lg = (UInt32) CTool_EndianConvertWord32(CInt64_GetULong(&val));
|
||||||
memcpy(mem, &lg, 4);
|
memcpy(mem, &lg, 4);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
CTool_EndianConvertWord64(val, mem);
|
CTool_EndianConvertWord64(val, mem);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 566
|
CError_FATAL(566);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 570
|
CError_FATAL(570);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,13 +609,11 @@ void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem, Boolean flag) {
|
||||||
memcpy(mem, f, 16);
|
memcpy(mem, f, 16);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 655
|
CError_FATAL(655);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 659
|
CError_FATAL(659);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,8 +632,7 @@ Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right) {
|
||||||
left.value /= right.value;
|
left.value /= right.value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 679
|
CError_FATAL(679);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMach_CalcFloatConvert(type, left);
|
return CMach_CalcFloatConvert(type, left);
|
||||||
|
@ -646,8 +640,7 @@ Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right) {
|
||||||
|
|
||||||
Float CMach_CalcFloatMonadic(Type *type, short op, Float fval) {
|
Float CMach_CalcFloatMonadic(Type *type, short op, Float fval) {
|
||||||
if (op != '-')
|
if (op != '-')
|
||||||
#line 692
|
CError_FATAL(692);
|
||||||
CError_FATAL();
|
|
||||||
|
|
||||||
fval.value = -fval.value;
|
fval.value = -fval.value;
|
||||||
return CMach_CalcFloatConvert(type, fval);
|
return CMach_CalcFloatConvert(type, fval);
|
||||||
|
@ -668,8 +661,7 @@ Boolean CMach_CalcFloatDiadicBool(Type *type, Float left, short op, Float right)
|
||||||
case '<':
|
case '<':
|
||||||
return left.value < right.value;
|
return left.value < right.value;
|
||||||
default:
|
default:
|
||||||
#line 714
|
CError_FATAL(714);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,8 +673,7 @@ Boolean CMach_CalcVectorDiadicBool(Type *type, MWVector128 *left, short op, MWVe
|
||||||
case TK_LOGICAL_NE:
|
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]);
|
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:
|
default:
|
||||||
#line 740
|
CError_FATAL(740);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,8 +723,7 @@ Float CMach_CalcFloatConvert(Type *type, Float fval) {
|
||||||
case 12:
|
case 12:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 801
|
CError_FATAL(801);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
return fval;
|
return fval;
|
||||||
}
|
}
|
||||||
|
@ -759,16 +749,17 @@ void CMach_InitFloatMem(Type *type, Float val, void *mem) {
|
||||||
case 4:
|
case 4:
|
||||||
f = val.value;
|
f = val.value;
|
||||||
memcpy(mem, &f, 4);
|
memcpy(mem, &f, 4);
|
||||||
|
CTool_EndianConvertMem(mem, 4);
|
||||||
return;
|
return;
|
||||||
case 8:
|
case 8:
|
||||||
d = val.value;
|
d = val.value;
|
||||||
memcpy(mem, &d, 8);
|
memcpy(mem, &d, 8);
|
||||||
|
CTool_EndianConvertMem(mem, 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 866
|
CError_FATAL(866);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMach_PrintFloat(char *buf, Float val) {
|
void CMach_PrintFloat(char *buf, Float val) {
|
||||||
|
@ -870,8 +861,7 @@ static SInt16 CMach_GetQualifiedStructAlign(TypeStruct *tstruct, Boolean flag) {
|
||||||
best = 1;
|
best = 1;
|
||||||
switch (copts.align_mode) {
|
switch (copts.align_mode) {
|
||||||
default:
|
default:
|
||||||
#line 1026
|
CError_FATAL(1026);
|
||||||
CError_FATAL();
|
|
||||||
case AlignMode4_2Byte:
|
case AlignMode4_2Byte:
|
||||||
case AlignMode5_4Byte:
|
case AlignMode5_4Byte:
|
||||||
case AlignMode6_8Byte:
|
case AlignMode6_8Byte:
|
||||||
|
@ -954,8 +944,7 @@ static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) {
|
||||||
best = 1;
|
best = 1;
|
||||||
switch (copts.align_mode) {
|
switch (copts.align_mode) {
|
||||||
default:
|
default:
|
||||||
#line 1149
|
CError_FATAL(1149);
|
||||||
CError_FATAL();
|
|
||||||
case AlignMode4_2Byte:
|
case AlignMode4_2Byte:
|
||||||
case AlignMode5_4Byte:
|
case AlignMode5_4Byte:
|
||||||
case AlignMode6_8Byte:
|
case AlignMode6_8Byte:
|
||||||
|
@ -1092,8 +1081,7 @@ restart:
|
||||||
return 8;
|
return 8;
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
default:
|
||||||
#line 1346
|
CError_FATAL(1346);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
case TYPEMEMBERPOINTER:
|
case TYPEMEMBERPOINTER:
|
||||||
case TYPEPOINTER:
|
case TYPEPOINTER:
|
||||||
|
@ -1146,8 +1134,7 @@ restart:
|
||||||
case TYPETEMPLATE:
|
case TYPETEMPLATE:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
#line 1392
|
CError_FATAL(1392);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1261,8 +1248,7 @@ SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) {
|
||||||
basesize_bits = 32;
|
basesize_bits = 32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1620
|
CError_FATAL(1620);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (copts.align_mode) {
|
switch (copts.align_mode) {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "compiler.h"
|
#include "compiler/CMangler.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/CError.h"
|
||||||
#include "compiler/CInt64.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/enode.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler/scopes.h"
|
#include "compiler/scopes.h"
|
||||||
|
@ -197,8 +201,7 @@ static void CMangler_CheckTemplateArguments(TemplArg *arg) {
|
||||||
while (arg) {
|
while (arg) {
|
||||||
if (arg->pid.type == TPT_NONTYPE) {
|
if (arg->pid.type == TPT_NONTYPE) {
|
||||||
expr = arg->data.paramdecl.expr;
|
expr = arg->data.paramdecl.expr;
|
||||||
#line 360
|
CError_ASSERT(360, expr);
|
||||||
CError_ASSERT(expr);
|
|
||||||
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
||||||
switch (expr->type) {
|
switch (expr->type) {
|
||||||
case EINTCONST:
|
case EINTCONST:
|
||||||
|
@ -207,8 +210,7 @@ static void CMangler_CheckTemplateArguments(TemplArg *arg) {
|
||||||
CMangler_GetLinkName(expr->data.objref);
|
CMangler_GetLinkName(expr->data.objref);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 383
|
CError_FATAL(383);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,8 +227,7 @@ static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
|
||||||
while (arg) {
|
while (arg) {
|
||||||
if (arg->pid.type == TPT_NONTYPE) {
|
if (arg->pid.type == TPT_NONTYPE) {
|
||||||
expr = arg->data.paramdecl.expr;
|
expr = arg->data.paramdecl.expr;
|
||||||
#line 409
|
CError_ASSERT(409, expr);
|
||||||
CError_ASSERT(expr);
|
|
||||||
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
||||||
switch (expr->type) {
|
switch (expr->type) {
|
||||||
case EINTCONST:
|
case EINTCONST:
|
||||||
|
@ -238,8 +239,7 @@ static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
|
||||||
AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
|
AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 452
|
CError_FATAL(452);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AppendGListByte(&name_mangle_list, 'T');
|
AppendGListByte(&name_mangle_list, 'T');
|
||||||
|
@ -247,8 +247,7 @@ static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
|
||||||
} else if (arg->pid.type == TPT_TYPE) {
|
} else if (arg->pid.type == TPT_TYPE) {
|
||||||
CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
|
CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
|
||||||
} else {
|
} else {
|
||||||
#line 467
|
CError_ASSERT(467, arg->pid.type == TPT_TEMPLATE);
|
||||||
CError_ASSERT(arg->pid.type == TPT_TEMPLATE);
|
|
||||||
CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
|
CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,8 +384,7 @@ static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
|
||||||
AppendGListByte(&name_mangle_list, 'r');
|
AppendGListByte(&name_mangle_list, 'r');
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
#line 619
|
CError_FATAL(619);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
case TYPEENUM:
|
case TYPEENUM:
|
||||||
CMangler_MangleQualifier(qual);
|
CMangler_MangleQualifier(qual);
|
||||||
|
@ -485,8 +483,7 @@ static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
|
||||||
AppendGListName(&name_mangle_list, "class");
|
AppendGListName(&name_mangle_list, "class");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 701
|
CError_FATAL(701);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -500,8 +497,7 @@ static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 716
|
CError_FATAL(716);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,8 +708,7 @@ HashNameNode *CMangler_GetLinkName(Object *obj) {
|
||||||
obj->u.toc.linkname = CMangler_DataLinkName(obj);
|
obj->u.toc.linkname = CMangler_DataLinkName(obj);
|
||||||
return obj->u.toc.linkname;
|
return obj->u.toc.linkname;
|
||||||
default:
|
default:
|
||||||
#line 1110
|
CError_FATAL(1110);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,181 @@
|
||||||
|
#include "compiler/CObjCModern.h"
|
||||||
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CExpr.h"
|
||||||
|
#include "compiler/CObjC.h"
|
||||||
|
#include "compiler/CPrep.h"
|
||||||
|
#include "compiler/CPrepTokenizer.h"
|
||||||
|
#include "compiler/CompilerTools.h"
|
||||||
|
#include "compiler/objc.h"
|
||||||
|
#include "compiler/objects.h"
|
||||||
|
#include "compiler/scopes.h"
|
||||||
|
|
||||||
|
static ObjCNamedArg *CObjC_GetKeywordArgList(HashNameNode *name, Boolean *isSingleArg) {
|
||||||
|
ObjCNamedArg *first;
|
||||||
|
ObjCNamedArg *arg;
|
||||||
|
char *start;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
start = name->name;
|
||||||
|
first = NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
for (p = start; *p != '_'; p++) {
|
||||||
|
if (*p == 0) {
|
||||||
|
if (!first) {
|
||||||
|
first = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
memclrw(first, sizeof(ObjCNamedArg));
|
||||||
|
|
||||||
|
first->name = name;
|
||||||
|
|
||||||
|
*isSingleArg = 1;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg->next = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
arg = arg->next;
|
||||||
|
|
||||||
|
arg->next = NULL;
|
||||||
|
arg->name = GetHashNameNode(start);
|
||||||
|
arg->expr = NULL;
|
||||||
|
|
||||||
|
*isSingleArg = 0;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
arg->next = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
arg = arg->next;
|
||||||
|
} else {
|
||||||
|
arg = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
first = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
arg->next = NULL;
|
||||||
|
arg->name = GetHashNameNode(start);
|
||||||
|
arg->expr = NULL;
|
||||||
|
*p = '_';
|
||||||
|
|
||||||
|
if (*(++p) == 0) {
|
||||||
|
*isSingleArg = 0;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ENode *CObjC_ModernSendMessage(TypeClass *tclass, ENode *expr, HashNameNode *name, Boolean isSuper) {
|
||||||
|
ENode *callexpr;
|
||||||
|
ObjCNamedArg *args;
|
||||||
|
ObjCNamedArg *arg;
|
||||||
|
ENodeList *unnamedArgs;
|
||||||
|
Boolean isSingleArg;
|
||||||
|
|
||||||
|
CError_ASSERT(92, ENODE_IS(expr, EINDIRECT));
|
||||||
|
expr = expr->data.monadic;
|
||||||
|
|
||||||
|
args = CObjC_GetKeywordArgList(name, &isSingleArg);
|
||||||
|
|
||||||
|
if ((tk = lex()) == ')') {
|
||||||
|
if (!isSingleArg) {
|
||||||
|
CError_Error(CErrorStr162);
|
||||||
|
return nullnode();
|
||||||
|
}
|
||||||
|
|
||||||
|
callexpr = CObjC_MakeSendMsgExpr(expr, tclass, args, NULL, 1, isSuper);
|
||||||
|
tk = lex();
|
||||||
|
return callexpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSingleArg) {
|
||||||
|
CError_Error(CErrorStr162);
|
||||||
|
return nullnode();
|
||||||
|
}
|
||||||
|
|
||||||
|
unnamedArgs = NULL;
|
||||||
|
arg = args;
|
||||||
|
while (1) {
|
||||||
|
arg->expr = assignment_expression();
|
||||||
|
|
||||||
|
if (tk == ')') {
|
||||||
|
if (arg->next) {
|
||||||
|
CError_Error(CErrorStr162);
|
||||||
|
return nullnode();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tk != ',') {
|
||||||
|
CError_Error(CErrorStr141);
|
||||||
|
return nullnode();
|
||||||
|
}
|
||||||
|
|
||||||
|
tk = lex();
|
||||||
|
arg = arg->next;
|
||||||
|
|
||||||
|
if (!arg) {
|
||||||
|
unnamedArgs = CExpr_ScanExpressionList(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callexpr = CObjC_MakeSendMsgExpr(expr, tclass, args, unnamedArgs, 1, isSuper);
|
||||||
|
tk = lex();
|
||||||
|
return callexpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENode *CObjC_CheckModernSendMessage(TypeClass *tclass, ENode *expr) {
|
||||||
|
HashNameNode *name;
|
||||||
|
SInt32 state;
|
||||||
|
|
||||||
|
CPrep_TokenStreamGetState(&state);
|
||||||
|
|
||||||
|
tk = lex();
|
||||||
|
CObjC_TranslateSelectorToken();
|
||||||
|
if (tk == TK_IDENTIFIER) {
|
||||||
|
if (!strcmp(tkidentifier->name, "super")) {
|
||||||
|
if (lex() == TK_COLON_COLON) {
|
||||||
|
tk = lex();
|
||||||
|
CObjC_TranslateSelectorToken();
|
||||||
|
|
||||||
|
name = tkidentifier;
|
||||||
|
if (tk == TK_IDENTIFIER && lex() == '(')
|
||||||
|
return CObjC_ModernSendMessage(tclass, expr, name, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = tkidentifier;
|
||||||
|
if (lex() == '(')
|
||||||
|
return CObjC_ModernSendMessage(tclass, expr, name, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPrep_TokenStreamSetState(&state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENode *CObjC_New(TypeClass *tclass) {
|
||||||
|
ObjCNamedArg *arg;
|
||||||
|
ENode *objexpr;
|
||||||
|
|
||||||
|
arg = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
memclrw(arg, sizeof(ObjCNamedArg));
|
||||||
|
|
||||||
|
arg->name = GetHashNameNode("alloc");
|
||||||
|
|
||||||
|
objexpr = create_objectrefnode(tclass->objcinfo->classobject);
|
||||||
|
|
||||||
|
return CObjC_MakeSendMsgExpr(objexpr, tclass, arg, NULL, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENode *CObjC_Delete(TypeClass *tclass, ENode *objexpr) {
|
||||||
|
ObjCNamedArg *arg;
|
||||||
|
|
||||||
|
arg = lalloc(sizeof(ObjCNamedArg));
|
||||||
|
memclrw(arg, sizeof(ObjCNamedArg));
|
||||||
|
|
||||||
|
arg->name = GetHashNameNode("dealloc");
|
||||||
|
|
||||||
|
return CObjC_MakeSendMsgExpr(objexpr, tclass, arg, NULL, 0, 0);
|
||||||
|
}
|
|
@ -190,12 +190,7 @@ static short cse_cost(COptCSE *cse) {
|
||||||
if (ENODE_IS3(cse->expr, EMUL, EDIV, EMODULO))
|
if (ENODE_IS3(cse->expr, EMUL, EDIV, EMODULO))
|
||||||
cost = 2;
|
cost = 2;
|
||||||
}
|
}
|
||||||
//cost = (!copts.optimize_for_size && ENODE_IS3(cse->expr, EMUL, EDIV, EMODULO)) ? 2 : 1;
|
|
||||||
return cse_cost(cse->left) + cse_cost(cse->right) + cost;
|
return cse_cost(cse->left) + cse_cost(cse->right) + cost;
|
||||||
//return
|
|
||||||
// ((!copts.optimize_for_size && ENODE_IS3(cse->expr, EMUL, EDIV, EMODULO)) ? 2 : 1) +
|
|
||||||
// cse_cost(cse->left) +
|
|
||||||
// cse_cost(cse->right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -237,8 +232,7 @@ static void cse_remove(void) {
|
||||||
if (cse->replaced) {
|
if (cse->replaced) {
|
||||||
replaces = 0;
|
replaces = 0;
|
||||||
cse_replace(cse->replaced, cse);
|
cse_replace(cse->replaced, cse);
|
||||||
#line 348
|
CError_ASSERT(348, replaces >= 1);
|
||||||
CError_ASSERT(replaces >= 1);
|
|
||||||
cse_found = 1;
|
cse_found = 1;
|
||||||
did_replacement = 1;
|
did_replacement = 1;
|
||||||
cse_update_usages(cse, cse->x1C);
|
cse_update_usages(cse, cse->x1C);
|
||||||
|
@ -304,12 +298,10 @@ static void cse_remove(void) {
|
||||||
cse_replace(expr2, cse);
|
cse_replace(expr2, cse);
|
||||||
cse->replaced = expr2;
|
cse->replaced = expr2;
|
||||||
|
|
||||||
if (replaces < 2) {
|
if (replaces < 2)
|
||||||
#line 390
|
CError_FATAL(390);
|
||||||
CError_FATAL();
|
else
|
||||||
} else {
|
|
||||||
cse_found = 1;
|
cse_found = 1;
|
||||||
}
|
|
||||||
|
|
||||||
expr4 = lalloc(sizeof(ENode));
|
expr4 = lalloc(sizeof(ENode));
|
||||||
*expr4 = *cse->mexpr;
|
*expr4 = *cse->mexpr;
|
||||||
|
@ -408,8 +400,7 @@ static COptCSE *cse_add_monadic_node(ENode *outer, COptCSE *innercse) {
|
||||||
|
|
||||||
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
||||||
if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
|
if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
|
||||||
#line 524
|
CError_ASSERT(524, cse->expr != outer);
|
||||||
CError_ASSERT(cse->expr != outer);
|
|
||||||
cse->x1C++;
|
cse->x1C++;
|
||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
@ -430,8 +421,7 @@ static COptCSE *cse_add_typecon_node(ENode *outer, COptCSE *innercse) {
|
||||||
|
|
||||||
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
||||||
if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
|
if (cse->left == innercse && cse->expr->rtype == outer->rtype) {
|
||||||
#line 552
|
CError_ASSERT(552, cse->expr != outer);
|
||||||
CError_ASSERT(cse->expr != outer);
|
|
||||||
cse->x1C++;
|
cse->x1C++;
|
||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
@ -452,8 +442,7 @@ static COptCSE *cse_add_diadic_node(ENode *outer, COptCSE *leftcse, COptCSE *rig
|
||||||
|
|
||||||
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
||||||
if (cse->left == leftcse && cse->right == rightcse) {
|
if (cse->left == leftcse && cse->right == rightcse) {
|
||||||
#line 581
|
CError_ASSERT(581, cse->expr != outer);
|
||||||
CError_ASSERT(cse->expr != outer);
|
|
||||||
cse->x1C++;
|
cse->x1C++;
|
||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
@ -475,8 +464,7 @@ static COptCSE *cse_add_commdiadic_node(ENode *outer, COptCSE *leftcse, COptCSE
|
||||||
|
|
||||||
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
for (cse = csenodes[outer->type]; cse; cse = cse->next) {
|
||||||
if ((cse->left == leftcse && cse->right == rightcse) || (cse->left == rightcse && cse->right == leftcse)) {
|
if ((cse->left == leftcse && cse->right == rightcse) || (cse->left == rightcse && cse->right == leftcse)) {
|
||||||
#line 612
|
CError_ASSERT(612, cse->expr != outer);
|
||||||
CError_ASSERT(cse->expr != outer);
|
|
||||||
cse->x1C++;
|
cse->x1C++;
|
||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
@ -527,8 +515,7 @@ static void cse_mem_modify(void) {
|
||||||
for (cse = csenodes[EINDIRECT]; cse; cse = cse->next) {
|
for (cse = csenodes[EINDIRECT]; cse; cse = cse->next) {
|
||||||
if (ENODE_IS(cse->expr->data.monadic, EOBJREF)) {
|
if (ENODE_IS(cse->expr->data.monadic, EOBJREF)) {
|
||||||
Object *obj = cse->expr->data.monadic->data.objref;
|
Object *obj = cse->expr->data.monadic->data.objref;
|
||||||
#line 672
|
CError_ASSERT(672, obj->datatype != DALIAS);
|
||||||
CError_ASSERT(obj->datatype != DALIAS);
|
|
||||||
if (obj->datatype == DLOCAL && !obj->u.var.info->noregister)
|
if (obj->datatype == DLOCAL && !obj->u.var.info->noregister)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -633,8 +620,7 @@ static COptCSE *cse_expression(ENode *expr) {
|
||||||
case EPREDEC:
|
case EPREDEC:
|
||||||
save = mexpr;
|
save = mexpr;
|
||||||
mexpr = expr;
|
mexpr = expr;
|
||||||
#line 816
|
CError_ASSERT(816, ENODE_IS(expr->data.monadic, EINDIRECT));
|
||||||
CError_ASSERT(ENODE_IS(expr->data.monadic, EINDIRECT));
|
|
||||||
|
|
||||||
cse_expression(expr->data.monadic->data.monadic);
|
cse_expression(expr->data.monadic->data.monadic);
|
||||||
cse_modify_expression(expr->data.monadic);
|
cse_modify_expression(expr->data.monadic);
|
||||||
|
@ -697,8 +683,7 @@ static COptCSE *cse_expression(ENode *expr) {
|
||||||
case EANDASS:
|
case EANDASS:
|
||||||
case EXORASS:
|
case EXORASS:
|
||||||
case EORASS:
|
case EORASS:
|
||||||
#line 887
|
CError_ASSERT(887, ENODE_IS(expr->data.diadic.left, EINDIRECT));
|
||||||
CError_ASSERT(ENODE_IS(expr->data.diadic.left, EINDIRECT));
|
|
||||||
save = mexpr;
|
save = mexpr;
|
||||||
mexpr = expr;
|
mexpr = expr;
|
||||||
cse_expression(expr->data.diadic.right);
|
cse_expression(expr->data.diadic.right);
|
||||||
|
@ -754,12 +739,10 @@ static COptCSE *cse_expression(ENode *expr) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case EPRECOMP:
|
case EPRECOMP:
|
||||||
#line 948
|
CError_FATAL(948);
|
||||||
CError_FATAL();
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 951
|
CError_FATAL(951);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1085,8 +1068,7 @@ static void CheckExpr(ENode *expr) {
|
||||||
case EVECTOR128CONST:
|
case EVECTOR128CONST:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
#line 1332
|
CError_FATAL(1332);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1347,8 +1329,7 @@ static void BasicBlockAnalyze(Statement *stmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1602
|
CError_ASSERT(1602, iblock);
|
||||||
CError_ASSERT(iblock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1480,8 +1461,7 @@ static void optimizeswitch(Statement *stmt) {
|
||||||
SwitchCase *swcase;
|
SwitchCase *swcase;
|
||||||
|
|
||||||
info = (SwitchInfo *) stmt->label;
|
info = (SwitchInfo *) stmt->label;
|
||||||
#line 1746
|
CError_ASSERT(1746, info && info->cases && info->defaultlabel);
|
||||||
CError_ASSERT(info && info->cases && info->defaultlabel);
|
|
||||||
|
|
||||||
info->defaultlabel = finallabel(info->defaultlabel, stmt);
|
info->defaultlabel = finallabel(info->defaultlabel, stmt);
|
||||||
for (swcase = info->cases; swcase; swcase = swcase->next)
|
for (swcase = info->cases; swcase; swcase = swcase->next)
|
||||||
|
@ -1576,8 +1556,7 @@ static void optimizebranches(Statement *stmt) {
|
||||||
|
|
||||||
void SetVarUsage(Object *obj, Boolean noregister) {
|
void SetVarUsage(Object *obj, Boolean noregister) {
|
||||||
VarInfo *vi;
|
VarInfo *vi;
|
||||||
#line 1875
|
CError_ASSERT(1875, obj->datatype != DALIAS);
|
||||||
CError_ASSERT(obj->datatype != DALIAS);
|
|
||||||
|
|
||||||
if (obj->datatype == DLOCAL || obj->datatype == DNONLAZYPTR) {
|
if (obj->datatype == DLOCAL || obj->datatype == DNONLAZYPTR) {
|
||||||
vi = obj->u.var.info;
|
vi = obj->u.var.info;
|
||||||
|
@ -1689,8 +1668,7 @@ static void checkexpression(ENode *expr) {
|
||||||
case ESTRINGCONST:
|
case ESTRINGCONST:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
#line 1998
|
CError_FATAL(1998);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,8 +1734,7 @@ static void colorcode(Statement *stmt) {
|
||||||
case ST_BEGINLOOP:
|
case ST_BEGINLOOP:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2096
|
CError_FATAL(2096);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
stmt = stmt->next;
|
stmt = stmt->next;
|
||||||
}
|
}
|
||||||
|
@ -1820,8 +1797,7 @@ static void COpt_Optimize(Object *obj, Statement *stmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void COpt_ELABELCallBack(ENode *expr) {
|
static void COpt_ELABELCallBack(ENode *expr) {
|
||||||
#line 2195
|
CError_ASSERT(2195, expr->data.label->stmt && expr->data.label->stmt->type == ST_LABEL);
|
||||||
CError_ASSERT(expr->data.label->stmt && expr->data.label->stmt->type == ST_LABEL);
|
|
||||||
expr->data.label->stmt->flags |= StmtFlag_1;
|
expr->data.label->stmt->flags |= StmtFlag_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1437,10 +1437,10 @@ static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) {
|
||||||
CPrec_AppendData(tclass, sizeof(TemplClass));
|
CPrec_AppendData(tclass, sizeof(TemplClass));
|
||||||
if (TEMPL_CLASS(tclass)->next)
|
if (TEMPL_CLASS(tclass)->next)
|
||||||
hasNextTempl = 1;
|
hasNextTempl = 1;
|
||||||
if (TEMPL_CLASS(tclass)->templ__parent)
|
if (TEMPL_CLASS(tclass)->templ_parent)
|
||||||
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ__parent));
|
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ_parent));
|
||||||
if (TEMPL_CLASS(tclass)->x3A_maybe_parentinst)
|
if (TEMPL_CLASS(tclass)->inst_parent)
|
||||||
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->x3A_maybe_parentinst, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->x3A_maybe_parentinst));
|
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->inst_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->inst_parent));
|
||||||
if (TEMPL_CLASS(tclass)->templ__params)
|
if (TEMPL_CLASS(tclass)->templ__params)
|
||||||
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params));
|
CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params));
|
||||||
if (TEMPL_CLASS(tclass)->members)
|
if (TEMPL_CLASS(tclass)->members)
|
||||||
|
@ -1458,8 +1458,8 @@ static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) {
|
||||||
CPrec_AppendData(tclass, sizeof(TemplClassInst));
|
CPrec_AppendData(tclass, sizeof(TemplClassInst));
|
||||||
if (TEMPL_CLASS_INST(tclass)->next)
|
if (TEMPL_CLASS_INST(tclass)->next)
|
||||||
hasNextTemplInst = 1;
|
hasNextTemplInst = 1;
|
||||||
if (TEMPL_CLASS_INST(tclass)->x36)
|
if (TEMPL_CLASS_INST(tclass)->parent)
|
||||||
CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->x36, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->x36));
|
CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->parent));
|
||||||
if (TEMPL_CLASS_INST(tclass)->templ)
|
if (TEMPL_CLASS_INST(tclass)->templ)
|
||||||
CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) 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)
|
if (TEMPL_CLASS_INST(tclass)->inst_args)
|
||||||
|
|
|
@ -0,0 +1,676 @@
|
||||||
|
#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 %ld\t\"", linenumber);
|
||||||
|
else
|
||||||
|
size = sprintf(linebuf, "/* #line %ld\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 %ld */", 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);
|
||||||
|
}
|
|
@ -0,0 +1,940 @@
|
||||||
|
#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_FLAGS_2))
|
||||||
|
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.useRTTI)
|
||||||
|
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_FLAGS_2))
|
||||||
|
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.ANSI_strict))
|
||||||
|
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.useRTTI)
|
||||||
|
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_FLAGS_2)) {
|
||||||
|
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_FLAGS_2)) {
|
||||||
|
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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -258,11 +258,9 @@ static void allocate_local_vregs(void) {
|
||||||
vi->reg = 0;
|
vi->reg = 0;
|
||||||
assign_register_by_type(&pic_base);
|
assign_register_by_type(&pic_base);
|
||||||
pic_base_reg = vi->reg;
|
pic_base_reg = vi->reg;
|
||||||
#line 497
|
CError_ASSERT(497, pic_base_reg);
|
||||||
CError_ASSERT(pic_base_reg);
|
|
||||||
} else {
|
} else {
|
||||||
#line 500
|
CError_FATAL(500);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pic_base_reg = 0;
|
pic_base_reg = 0;
|
||||||
|
@ -338,8 +336,7 @@ static void allocate_local_GPRs(void) {
|
||||||
vi->reg = 0;
|
vi->reg = 0;
|
||||||
assign_register_by_type(&pic_base);
|
assign_register_by_type(&pic_base);
|
||||||
pic_base_reg = vi->reg;
|
pic_base_reg = vi->reg;
|
||||||
#line 605
|
CError_ASSERT(605, pic_base_reg);
|
||||||
CError_ASSERT(pic_base_reg);
|
|
||||||
} else {
|
} else {
|
||||||
pic_base_reg = 0;
|
pic_base_reg = 0;
|
||||||
}
|
}
|
||||||
|
@ -398,8 +395,7 @@ static void allocate_local_GPRs(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
assign_register_by_type(winning_obj);
|
assign_register_by_type(winning_obj);
|
||||||
#line 698
|
CError_ASSERT(698, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,8 +448,7 @@ static void allocate_local_FPRs(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
assign_register_by_type(winning_obj);
|
assign_register_by_type(winning_obj);
|
||||||
#line 782
|
CError_ASSERT(782, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,8 +499,7 @@ static void allocate_local_VRs(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
assign_register_by_type(winning_obj);
|
assign_register_by_type(winning_obj);
|
||||||
#line 846
|
CError_ASSERT(846, Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,8 +528,7 @@ void move_assigned_argument(Object *obj, short reg) {
|
||||||
|
|
||||||
vi = Registers_GetVarInfo(obj);
|
vi = Registers_GetVarInfo(obj);
|
||||||
type = obj->type;
|
type = obj->type;
|
||||||
#line 901
|
CError_ASSERT(901, obj->datatype == DLOCAL);
|
||||||
CError_ASSERT(obj->datatype == DLOCAL);
|
|
||||||
|
|
||||||
if (!vi->used)
|
if (!vi->used)
|
||||||
return;
|
return;
|
||||||
|
@ -547,8 +540,7 @@ void move_assigned_argument(Object *obj, short reg) {
|
||||||
if (vi->reg != reg)
|
if (vi->reg != reg)
|
||||||
emitpcode(PC_MR, vi->reg, reg);
|
emitpcode(PC_MR, vi->reg, reg);
|
||||||
if (reg < GPRLimit) {
|
if (reg < GPRLimit) {
|
||||||
#line 916
|
CError_FAIL(916, (vi->regHi == reg) || (vi->reg == (reg + 1)));
|
||||||
CError_FAIL((vi->regHi == reg) || (vi->reg == (reg + 1)));
|
|
||||||
if (vi->regHi != (reg + 1))
|
if (vi->regHi != (reg + 1))
|
||||||
emitpcode(PC_MR, vi->regHi, reg + 1);
|
emitpcode(PC_MR, vi->regHi, reg + 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -558,8 +550,7 @@ void move_assigned_argument(Object *obj, short reg) {
|
||||||
if (vi->regHi != reg)
|
if (vi->regHi != reg)
|
||||||
emitpcode(PC_MR, vi->regHi, reg);
|
emitpcode(PC_MR, vi->regHi, reg);
|
||||||
if (reg < GPRLimit) {
|
if (reg < GPRLimit) {
|
||||||
#line 931
|
CError_FAIL(931, (vi->reg == reg) || (vi->regHi == (reg + 1)));
|
||||||
CError_FAIL((vi->reg == reg) || (vi->regHi == (reg + 1)));
|
|
||||||
if (vi->reg != (reg + 1))
|
if (vi->reg != (reg + 1))
|
||||||
emitpcode(PC_MR, vi->reg, reg + 1);
|
emitpcode(PC_MR, vi->reg, reg + 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -595,8 +586,7 @@ void move_assigned_argument(Object *obj, short reg) {
|
||||||
load_store_register(PC_STW, reg + 1, local_base_register(obj), obj, 4);
|
load_store_register(PC_STW, reg + 1, local_base_register(obj), obj, 4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 993
|
CError_FATAL(993);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else if (IS_TYPE_FLOAT(type)) {
|
} else if (IS_TYPE_FLOAT(type)) {
|
||||||
load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, local_base_register(obj), obj, 0);
|
load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, local_base_register(obj), obj, 0);
|
||||||
|
@ -639,8 +629,7 @@ void move_assigned_argument(Object *obj, short reg) {
|
||||||
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
|
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1095
|
CError_FATAL(1095);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!optimizing) {
|
} else if (!optimizing) {
|
||||||
|
@ -682,8 +671,7 @@ static void load_TOC_pointers(void) {
|
||||||
emitpcode(PC_MR, vi->reg, opnd.reg);
|
emitpcode(PC_MR, vi->reg, opnd.reg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1206
|
CError_FATAL(1206);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -782,8 +770,7 @@ static void gotoexpression(ENode *expr) {
|
||||||
|
|
||||||
if (opnd.optype != OpndType_GPR)
|
if (opnd.optype != OpndType_GPR)
|
||||||
Coerce_to_register(&opnd, TYPE(&void_ptr), 0);
|
Coerce_to_register(&opnd, TYPE(&void_ptr), 0);
|
||||||
#line 1397
|
CError_ASSERT(1397, opnd.optype == OpndType_GPR);
|
||||||
CError_ASSERT(opnd.optype == OpndType_GPR);
|
|
||||||
|
|
||||||
for (list = codelabellist; list; list = list->next)
|
for (list = codelabellist; list; list = list->next)
|
||||||
pcbranch(pclastblock, list->label->pclabel);
|
pcbranch(pclastblock, list->label->pclabel);
|
||||||
|
@ -854,8 +841,7 @@ static void returnstatement(ENode *expr, Boolean dont_branch) {
|
||||||
|
|
||||||
static void capturestackpointer(Object *obj) {
|
static void capturestackpointer(Object *obj) {
|
||||||
branch_label(makepclabel());
|
branch_label(makepclabel());
|
||||||
#line 1568
|
CError_ASSERT(1568, obj->datatype == DLOCAL);
|
||||||
CError_ASSERT(obj->datatype == DLOCAL);
|
|
||||||
|
|
||||||
load_store_register(PC_STW, 1, local_base_register(obj), obj, 20);
|
load_store_register(PC_STW, 1, local_base_register(obj), obj, 20);
|
||||||
branch_label(makepclabel());
|
branch_label(makepclabel());
|
||||||
|
@ -864,8 +850,7 @@ static void capturestackpointer(Object *obj) {
|
||||||
static void resetstackpointer(Object *obj) {
|
static void resetstackpointer(Object *obj) {
|
||||||
PCode *pc;
|
PCode *pc;
|
||||||
|
|
||||||
#line 1595
|
CError_ASSERT(1595, obj->datatype == DLOCAL);
|
||||||
CError_ASSERT(obj->datatype == DLOCAL);
|
|
||||||
|
|
||||||
branch_label(makepclabel());
|
branch_label(makepclabel());
|
||||||
|
|
||||||
|
@ -1012,8 +997,7 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag,
|
||||||
capturestackpointer(stmt->expr->data.objref);
|
capturestackpointer(stmt->expr->data.objref);
|
||||||
break;
|
break;
|
||||||
case ST_ENDCATCHDTOR:
|
case ST_ENDCATCHDTOR:
|
||||||
#line 2056
|
CError_ASSERT(2056, stmt->expr->data.objref->datatype == DLOCAL);
|
||||||
CError_ASSERT(stmt->expr->data.objref->datatype == DLOCAL);
|
|
||||||
obj = stmt->expr->data.objref;
|
obj = stmt->expr->data.objref;
|
||||||
add_immediate(3, local_base_register(obj), obj, 0);
|
add_immediate(3, local_base_register(obj), obj, 0);
|
||||||
{
|
{
|
||||||
|
@ -1028,8 +1012,7 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag,
|
||||||
if (stmt->expr) {
|
if (stmt->expr) {
|
||||||
// ... will need to understand inline ASM properly for this ...
|
// ... will need to understand inline ASM properly for this ...
|
||||||
if (((WeirdInlineAsmThing *) stmt->expr)->x2 & 1) {
|
if (((WeirdInlineAsmThing *) stmt->expr)->x2 & 1) {
|
||||||
#line 2076
|
CError_FATAL(2076);
|
||||||
CError_FATAL();
|
|
||||||
} else {
|
} else {
|
||||||
branch_label(makepclabel());
|
branch_label(makepclabel());
|
||||||
InlineAsm_TranslateIRtoPCode(stmt);
|
InlineAsm_TranslateIRtoPCode(stmt);
|
||||||
|
@ -1037,16 +1020,13 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_BEGINLOOP:
|
case ST_BEGINLOOP:
|
||||||
#line 2086
|
CError_FATAL(2086);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
case ST_ENDLOOP:
|
case ST_ENDLOOP:
|
||||||
#line 2090
|
CError_FATAL(2090);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2094
|
CError_FATAL(2094);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
check_temp_registers();
|
check_temp_registers();
|
||||||
}
|
}
|
||||||
|
@ -1168,8 +1148,7 @@ void CodeGen_GenVDispatchThunk(Object *thunkobj, Object *obj, SInt32 a, SInt32 b
|
||||||
save_traceback = copts.traceback;
|
save_traceback = copts.traceback;
|
||||||
|
|
||||||
CodeGen_InitialSanityCheck();
|
CodeGen_InitialSanityCheck();
|
||||||
#line 2270
|
CError_ASSERT(2270, b == 0);
|
||||||
CError_ASSERT(b == 0);
|
|
||||||
|
|
||||||
initpcode();
|
initpcode();
|
||||||
makepcblock();
|
makepcblock();
|
||||||
|
@ -1276,8 +1255,7 @@ void CodeGen_SOMStub(Object *a, Object *b, Object *c, SInt32 offset) {
|
||||||
|
|
||||||
CodeGen_InitialSanityCheck();
|
CodeGen_InitialSanityCheck();
|
||||||
memclrw(&opnd, sizeof(Operand));
|
memclrw(&opnd, sizeof(Operand));
|
||||||
#line 2528
|
CError_ASSERT(2528, offset <= 0x7FFF);
|
||||||
CError_ASSERT(offset <= 0x7FFF);
|
|
||||||
|
|
||||||
initpcode();
|
initpcode();
|
||||||
makepcblock();
|
makepcblock();
|
||||||
|
@ -1296,8 +1274,7 @@ void CodeGen_SOMStub(Object *a, Object *b, Object *c, SInt32 offset) {
|
||||||
Coerce_to_register(&opnd, TYPE(&void_ptr), 12);
|
Coerce_to_register(&opnd, TYPE(&void_ptr), 12);
|
||||||
|
|
||||||
if (opnd.optype != OpndType_GPR) {
|
if (opnd.optype != OpndType_GPR) {
|
||||||
#line 2562
|
CError_FATAL(2562);
|
||||||
CError_FATAL();
|
|
||||||
} else if (opnd.reg != 12) {
|
} else if (opnd.reg != 12) {
|
||||||
emitpcode(PC_MR, 12, opnd.reg);
|
emitpcode(PC_MR, 12, opnd.reg);
|
||||||
}
|
}
|
||||||
|
@ -1933,19 +1910,19 @@ void CodeGen_UpdateBackEndOptions(void) {
|
||||||
copts.global_optimizer = 1;
|
copts.global_optimizer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen_objc_method_self_offset() {
|
SInt32 CodeGen_objc_method_self_offset(ObjCMethod *meth) {
|
||||||
// TODO objc
|
// TODO objc
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen_objc_method_sel_offset() {
|
SInt32 CodeGen_objc_method_sel_offset(ObjCMethod *meth) {
|
||||||
// TODO objc
|
// TODO objc
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen_objc_method_arg_offset() {
|
SInt32 CodeGen_objc_method_arg_offset(ObjCMethod *meth, ObjCMethodArg *arg) {
|
||||||
// TODO objc
|
// TODO objc
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen_objc_method_args_size() {
|
SInt32 CodeGen_objc_method_args_size(ObjCMethod *meth) {
|
||||||
// TODO objc
|
// TODO objc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2386,8 +2363,7 @@ char *CodeGen_ExpandSpecialMacro(Macro *macro) {
|
||||||
if (!copts.ANSI_strict && macro == &ppcM) return "1";
|
if (!copts.ANSI_strict && macro == &ppcM) return "1";
|
||||||
if (macro == &_ppc_M) return "1";
|
if (macro == &_ppc_M) return "1";
|
||||||
|
|
||||||
#line 4801
|
CError_FATAL(4801);
|
||||||
CError_FATAL();
|
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,8 +155,7 @@ static int isuniquedefinition(PCode *pcode, Loop *loop) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 292
|
CError_FATAL(292);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -227,8 +226,7 @@ static int uniquelyreachesalluses(int defID, Loop *loop) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 382
|
CError_FATAL(382);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -331,8 +329,7 @@ static void moveinvariantcomputation(PCode *pcode, Loop *loop) {
|
||||||
bitvectorsetbit(defID, usedefinfo[blocklist->block->blockIndex].defvec8);
|
bitvectorsetbit(defID, usedefinfo[blocklist->block->blockIndex].defvec8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 545
|
CError_FATAL(545);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,8 +360,7 @@ static int srawi_addze_maymove(PCode *pcode, Loop *loop) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 582
|
CError_FATAL(582);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uniquelyreachesalluses(pcode->defID, loop))
|
if (!uniquelyreachesalluses(pcode->defID, loop))
|
||||||
|
@ -486,8 +482,7 @@ static void movecmptopreheader(Loop *loop, PCodeBlock *block, PCode *pc1, PCode
|
||||||
insertpreheaderblock(loop);
|
insertpreheaderblock(loop);
|
||||||
|
|
||||||
pc3 = preheader->lastPCode;
|
pc3 = preheader->lastPCode;
|
||||||
#line 775
|
CError_ASSERT(775, pc3->op == PC_B);
|
||||||
CError_ASSERT(pc3->op == PC_B);
|
|
||||||
deletepcode(pc3);
|
deletepcode(pc3);
|
||||||
deletepcode(pc2);
|
deletepcode(pc2);
|
||||||
appendpcode(preheader, pc2);
|
appendpcode(preheader, pc2);
|
||||||
|
@ -715,8 +710,7 @@ static void simpleunswitchloop(Loop *loop) {
|
||||||
bestpath2 = pathiter1;
|
bestpath2 = pathiter1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1192
|
CError_ASSERT(1192, bestpath2->block);
|
||||||
CError_ASSERT(bestpath2->block);
|
|
||||||
|
|
||||||
if (bestpath2->block->lastPCode && bestpath2->block->lastPCode->op == PC_B)
|
if (bestpath2->block->lastPCode && bestpath2->block->lastPCode->op == PC_B)
|
||||||
deletepcode(bestpath2->block->lastPCode);
|
deletepcode(bestpath2->block->lastPCode);
|
||||||
|
@ -753,8 +747,7 @@ static void simpleunswitchloop(Loop *loop) {
|
||||||
op23 = &loop->body->lastPCode->args[i];
|
op23 = &loop->body->lastPCode->args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1250
|
CError_ASSERT(1250, op23 != NULL);
|
||||||
CError_ASSERT(op23 != NULL);
|
|
||||||
|
|
||||||
changesuccessor(loop->body, op23->data.label.label->block, path2_24->block);
|
changesuccessor(loop->body, op23->data.label.label->block, path2_24->block);
|
||||||
op23->data.label.label = path2_24->block->labels;
|
op23->data.label.label = path2_24->block->labels;
|
||||||
|
@ -765,8 +758,7 @@ static void simpleunswitchloop(Loop *loop) {
|
||||||
op23 = &preheader21->lastPCode->args[i];
|
op23 = &preheader21->lastPCode->args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1267
|
CError_ASSERT(1267, op23 != NULL);
|
||||||
CError_ASSERT(op23 != NULL);
|
|
||||||
|
|
||||||
changesuccessor(preheader21, op23->data.label.label->block, loop->body);
|
changesuccessor(preheader21, op23->data.label.label->block, loop->body);
|
||||||
op23->data.label.label = loop->body->labels;
|
op23->data.label.label = loop->body->labels;
|
||||||
|
@ -777,8 +769,7 @@ static void simpleunswitchloop(Loop *loop) {
|
||||||
op23 = &loop->preheader->lastPCode->args[i];
|
op23 = &loop->preheader->lastPCode->args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1284
|
CError_ASSERT(1284, op23 != NULL);
|
||||||
CError_ASSERT(op23 != NULL);
|
|
||||||
|
|
||||||
changesuccessor(loop->preheader, op23->data.label.label->block, headercopy);
|
changesuccessor(loop->preheader, op23->data.label.label->block, headercopy);
|
||||||
op23->data.label.label = headercopy->labels;
|
op23->data.label.label = headercopy->labels;
|
||||||
|
@ -884,8 +875,7 @@ static void moveinvariantsfromloop(Loop *loop) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 1434
|
CError_FATAL(1434);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitvectorsetbit(defID, myvec);
|
bitvectorsetbit(defID, myvec);
|
||||||
|
|
|
@ -0,0 +1,857 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 & fPCBlockFlag20)
|
||||||
|
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);
|
||||||
|
}
|
|
@ -1,22 +1,393 @@
|
||||||
#include "compiler/FuncLevelAsmPPC.h"
|
#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"
|
||||||
|
|
||||||
void setup_assembly_argument(Object *obj, short i) {
|
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.little_endian) {
|
||||||
|
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 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_FLAGS_UNUSED;
|
||||||
|
vi->used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FuncAsm_PreScanDirectives() {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FuncAsm_AddEntryPoint() {
|
for (list = locals; list; list = list->next) {
|
||||||
|
object = list->object;
|
||||||
|
if (OBJECT_REG(object) == 0)
|
||||||
|
assign_local_memory(object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler() {
|
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(1))) {
|
||||||
|
InlineAsm_ProcessDirective(directive);
|
||||||
|
|
||||||
|
if (tk == ';' || tk == TK_NEG7) {
|
||||||
|
CPrep_TokenStreamFlush();
|
||||||
|
tk = lex();
|
||||||
|
} else {
|
||||||
|
InlineAsm_SyntaxError(CErrorStr113);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupAssembler() {
|
if (directive == IADirective_FrAlloc) {
|
||||||
|
requires_frame = 1;
|
||||||
|
break;
|
||||||
|
} else if (directive == IADirective_NoFrAlloc) {
|
||||||
|
user_responsible_for_frame = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanupAssembler() {
|
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(173);
|
||||||
|
|
||||||
|
CheckCLabels();
|
||||||
|
|
||||||
|
if (fatalerrors)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (copts.isGeneratingDebugInfo)
|
||||||
|
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_FLAGS_4;
|
||||||
|
|
||||||
|
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(188);
|
||||||
|
else
|
||||||
|
flag16 = 1;
|
||||||
|
|
||||||
|
asm_alloc_flags[3] = 1;
|
||||||
|
asm_alloc_flags[4] = 1;
|
||||||
|
branch_label(makepclabel());
|
||||||
|
|
||||||
|
epilogue = pclastblock;
|
||||||
|
pclastblock->flags |= fPCBlockFlag2;
|
||||||
|
|
||||||
|
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 |= fPCBlockFlag2;
|
||||||
|
|
||||||
|
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(187, "blr");
|
||||||
|
if (asm_alloc_flags[8])
|
||||||
|
PPCError_Warning(186);
|
||||||
|
} else {
|
||||||
|
PPCError_Warning(185, "blr");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func->section = sm_section;
|
||||||
|
|
||||||
|
if (copts.isGeneratingDebugInfo)
|
||||||
|
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) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,642 @@
|
||||||
|
#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.little_endian) {
|
||||||
|
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.little_endian) {
|
||||||
|
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_FLAGS_1) {
|
||||||
|
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);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,224 @@
|
||||||
|
#include "compiler/GlobalOptimizer.h"
|
||||||
|
#include "compiler/CMangler.h"
|
||||||
|
#include "compiler/CParser.h"
|
||||||
|
#include "compiler/AddPropagation.h"
|
||||||
|
#include "compiler/CodeGen.h"
|
||||||
|
#include "compiler/CodeMotion.h"
|
||||||
|
#include "compiler/ConstantPropagation.h"
|
||||||
|
#include "compiler/CopyPropagation.h"
|
||||||
|
#include "compiler/LoadDeletion.h"
|
||||||
|
#include "compiler/LoopDetection.h"
|
||||||
|
#include "compiler/LoopOptimization.h"
|
||||||
|
#include "compiler/PCodeListing.h"
|
||||||
|
#include "compiler/Peephole.h"
|
||||||
|
#include "compiler/StrengthReduction.h"
|
||||||
|
#include "compiler/ValueNumbering.h"
|
||||||
|
#include "compiler/VectorArraysToRegs.h"
|
||||||
|
|
||||||
|
static void optimizelevel2(Object *func) {
|
||||||
|
removecommonsubexpressions(func, 1);
|
||||||
|
if (removedcommonsubexpressions && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CSE");
|
||||||
|
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void optimizelevel3(Object *func) {
|
||||||
|
if (copts.peephole) {
|
||||||
|
if (copts.schedule_mode == 0 && copts.optimizationlevel > 1)
|
||||||
|
peepholemergeblocks(func, 0);
|
||||||
|
|
||||||
|
peepholeoptimizeforward(func);
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE FORWARD");
|
||||||
|
}
|
||||||
|
|
||||||
|
removecommonsubexpressions(func, 0);
|
||||||
|
if (removedcommonsubexpressions && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING");
|
||||||
|
|
||||||
|
propagatecopyinstructions(func, 0);
|
||||||
|
propagatedcopies = 0;
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
|
||||||
|
findloopsinflowgraph();
|
||||||
|
if (loopsinflowgraph) {
|
||||||
|
computeusedefchains(1);
|
||||||
|
analyzeloopsinflowgraph();
|
||||||
|
moveloopinvariantcode();
|
||||||
|
if (movedloopinvariantcode && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CODE MOTION");
|
||||||
|
|
||||||
|
computeusedefchains(0);
|
||||||
|
analyzeForCountableLoops(loopsinflowgraph);
|
||||||
|
strengthreduceloops();
|
||||||
|
if (strengthreducedloops) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER STRENGTH REDUCTION");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizeloops();
|
||||||
|
if (optimizedloops) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER LOOP TRANSFORMATIONS");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!propagatedcopies) {
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
if (propagatedcopies && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER COPY PROPAGATION");
|
||||||
|
}
|
||||||
|
|
||||||
|
propagateconstants();
|
||||||
|
if (propagatedconstants) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CONSTANT PROPAGATION");
|
||||||
|
|
||||||
|
deletedeadloads(func);
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copts.peephole) {
|
||||||
|
if (copts.schedule_mode == 0 && copts.optimizationlevel > 1)
|
||||||
|
peepholemergeblocks(func, 0);
|
||||||
|
|
||||||
|
peepholeoptimizeforward(func);
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE FORWARD 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
removecommonsubexpressions(func, 1);
|
||||||
|
if (removedcommonsubexpressions) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING 2");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void optimizelevel4(Object *func) {
|
||||||
|
if (copts.peephole) {
|
||||||
|
if (copts.schedule_mode == 0 && copts.optimizationlevel > 1)
|
||||||
|
peepholemergeblocks(func, 0);
|
||||||
|
|
||||||
|
peepholeoptimizeforward(func);
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE FORWARD");
|
||||||
|
}
|
||||||
|
|
||||||
|
removecommonsubexpressions(func, 0);
|
||||||
|
if (removedcommonsubexpressions && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING");
|
||||||
|
|
||||||
|
propagatecopyinstructions(func, 0);
|
||||||
|
propagatedcopies = 0;
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
|
||||||
|
findloopsinflowgraph();
|
||||||
|
if (loopsinflowgraph) {
|
||||||
|
computeusedefchains(1);
|
||||||
|
analyzeloopsinflowgraph();
|
||||||
|
moveloopinvariantcode();
|
||||||
|
if (movedloopinvariantcode && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CODE MOTION");
|
||||||
|
|
||||||
|
computeusedefchains(0);
|
||||||
|
analyzeForCountableLoops(loopsinflowgraph);
|
||||||
|
strengthreduceloops();
|
||||||
|
if (strengthreducedloops) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER STRENGTH REDUCTION");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
propagatedcopies = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizeloops();
|
||||||
|
if (optimizedloops) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER LOOP TRANSFORMATIONS");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!propagatedcopies)
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
|
||||||
|
propagateconstants();
|
||||||
|
if (propagatedconstants) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CONSTANT PROPAGATION");
|
||||||
|
|
||||||
|
deletedeadloads(func);
|
||||||
|
if (propagatedconstants)
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
propagateaddinstructions(func);
|
||||||
|
|
||||||
|
if (optimizedloop_full_unroll) {
|
||||||
|
changearraytoregisters();
|
||||||
|
if (optimizedloop_trans_regs && copts.debuglisting) {
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER ARRAY => REGISTER TRANSFORM");
|
||||||
|
propagateconstants();
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CONSTANT PROPAGATION 2");
|
||||||
|
if (propagatedconstants)
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copts.peephole) {
|
||||||
|
if (copts.schedule_mode == 0 && copts.optimizationlevel > 1)
|
||||||
|
peepholemergeblocks(func, 0);
|
||||||
|
|
||||||
|
peepholeoptimizeforward(func);
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER PEEPHOLE FORWARD 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
removecommonsubexpressions(func, 1);
|
||||||
|
if (removedcommonsubexpressions) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING 2");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_altivec_arrays && vectorarraystoregs()) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VECTOR ARRAY CONVERSION");
|
||||||
|
propagatecopyinstructions(func, 0);
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
findloopsinflowgraph();
|
||||||
|
if (loopsinflowgraph) {
|
||||||
|
computeusedefchains(1);
|
||||||
|
analyzeloopsinflowgraph();
|
||||||
|
moveloopinvariantcode();
|
||||||
|
if (movedloopinvariantcode && copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER CODE MOTION 2");
|
||||||
|
|
||||||
|
removecommonsubexpressions(func, 1);
|
||||||
|
if (removedcommonsubexpressions) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "AFTER VALUE NUMBERING 3");
|
||||||
|
propagatecopyinstructions(func, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void globallyoptimizepcode(Object *func) {
|
||||||
|
if (copts.debuglisting)
|
||||||
|
pclistblocks(CMangler_GetLinkName(func)->name, "BEFORE GLOBAL OPTIMIZATION");
|
||||||
|
|
||||||
|
if (copts.optimizationlevel == 2 || (has_catch_blocks && copts.optimizationlevel > 2))
|
||||||
|
optimizelevel2(func);
|
||||||
|
else if (copts.optimizationlevel == 3)
|
||||||
|
optimizelevel3(func);
|
||||||
|
else if (copts.optimizationlevel == 4)
|
||||||
|
optimizelevel4(func);
|
||||||
|
}
|
|
@ -230,8 +230,7 @@ CInt64 IRO_GetSelfAssignmentVal(IROLinear *linear) {
|
||||||
CInt64_SetLong(&result, -1);
|
CInt64_SetLong(&result, -1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 445
|
CError_FATAL(445);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_TYPE_POINTER_ONLY(linear->rtype)) {
|
if (IS_TYPE_POINTER_ONLY(linear->rtype)) {
|
||||||
|
@ -257,12 +256,10 @@ CInt64 IRO_GetSelfAssignmentVal(IROLinear *linear) {
|
||||||
result = CInt64_Neg(result);
|
result = CInt64_Neg(result);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 491
|
CError_FATAL(491);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 496
|
CError_FATAL(496);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -810,11 +807,9 @@ static void MarkUsesByIndirect(IROLinear *linear, BitVector *a, BitVector *b) {
|
||||||
for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) {
|
for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) {
|
||||||
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 1422
|
CError_ASSERT(1422, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
var = IRO_FindVar(obj, 1, 1);
|
var = IRO_FindVar(obj, 1, 1);
|
||||||
#line 1424
|
CError_ASSERT(1424, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
for (def = var->defs; def; def = def->varnext) {
|
for (def = var->defs; def; def = def->varnext) {
|
||||||
if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
|
if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
|
||||||
|
@ -883,8 +878,7 @@ static void MarkUsesByFunctionCall(IROLinear *linear, BitVector *a, BitVector *b
|
||||||
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 1522
|
CError_ASSERT(1522, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
depsList = NULL;
|
depsList = NULL;
|
||||||
PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList);
|
PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList);
|
||||||
|
@ -922,8 +916,7 @@ static void MarkUsesByFunctionCall(IROLinear *linear, BitVector *a, BitVector *b
|
||||||
|
|
||||||
for (olist = depsList; olist; olist = olist->next) {
|
for (olist = depsList; olist; olist = olist->next) {
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 1573
|
CError_ASSERT(1573, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
for (def = var->defs; def; def = def->varnext) {
|
for (def = var->defs; def; def = def->varnext) {
|
||||||
if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
|
if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) {
|
||||||
|
@ -1286,19 +1279,15 @@ static IROLinear *GetAssigned(IROLinear *nd) {
|
||||||
if (!nd)
|
if (!nd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (nd->type == IROLinearOp2Arg) {
|
if (nd->type == IROLinearOp2Arg)
|
||||||
nd = nd->u.diadic.left;
|
nd = nd->u.diadic.left;
|
||||||
} else if (nd->type == IROLinearOp1Arg) {
|
else if (nd->type == IROLinearOp1Arg)
|
||||||
nd = nd->u.monadic;
|
nd = nd->u.monadic;
|
||||||
} else {
|
else
|
||||||
#line 2338
|
CError_FATAL(2338);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nd->type != IROLinearOp1Arg || nd->nodetype != EINDIRECT) {
|
if (nd->type != IROLinearOp1Arg || nd->nodetype != EINDIRECT)
|
||||||
#line 2351
|
CError_FATAL(2351);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
nd = nd->u.monadic;
|
nd = nd->u.monadic;
|
||||||
|
|
||||||
|
@ -1341,24 +1330,19 @@ static void ReplaceAssigned(IROLinear *nd, Object *from, Object *to) {
|
||||||
assigned->type != IROLinearOperand ||
|
assigned->type != IROLinearOperand ||
|
||||||
assigned->u.node->type != EOBJREF ||
|
assigned->u.node->type != EOBJREF ||
|
||||||
assigned->u.node->data.objref != from
|
assigned->u.node->data.objref != from
|
||||||
) {
|
)
|
||||||
#line 2459
|
CError_FATAL(2459);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
assigned->u.node->data.objref = to;
|
assigned->u.node->data.objref = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReplaceUsed(IROLinear *nd, Object *from, Object *to) {
|
static void ReplaceUsed(IROLinear *nd, Object *from, Object *to) {
|
||||||
#line 2482
|
CError_ASSERT(2482, nd->type == IROLinearOperand && nd->u.node->type == EOBJREF);
|
||||||
CError_ASSERT(nd->type == IROLinearOperand && nd->u.node->type == EOBJREF);
|
|
||||||
|
|
||||||
if (nd->u.node->data.objref == from) {
|
if (nd->u.node->data.objref == from)
|
||||||
nd->u.node->data.objref = to;
|
nd->u.node->data.objref = to;
|
||||||
} else if (nd->u.node->data.objref != to) {
|
else if (nd->u.node->data.objref != to)
|
||||||
#line 2494
|
CError_FATAL(2494);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SplitOffRange(VarRecord *var) {
|
static void SplitOffRange(VarRecord *var) {
|
||||||
|
|
|
@ -120,8 +120,7 @@ Boolean InlineAsm_LookupSymbolOrTag(HashNameNode *name, IALookupResult *result,
|
||||||
case OT_MEMBERVAR:
|
case OT_MEMBERVAR:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
#line 245
|
CError_FATAL(245);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ extern int countexceptionactionregisters(ExceptionAction *);
|
||||||
extern void noteexceptionactionregisters(ExceptionAction *, PCodeArg *);
|
extern void noteexceptionactionregisters(ExceptionAction *, PCodeArg *);
|
||||||
|
|
||||||
char asm_alloc_flags[10];
|
char asm_alloc_flags[10];
|
||||||
unsigned char sm_section;
|
Section sm_section;
|
||||||
UInt32 cpu;
|
UInt32 cpu;
|
||||||
SInt32 fralloc_parameter_area_size;
|
SInt32 fralloc_parameter_area_size;
|
||||||
Boolean user_responsible_for_frame;
|
Boolean user_responsible_for_frame;
|
||||||
|
@ -1018,8 +1018,7 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
|
|
||||||
op = ia->args;
|
op = ia->args;
|
||||||
for (format = mnemonic->format; *format; format++) {
|
for (format = mnemonic->format; *format; format++) {
|
||||||
#line 1664
|
CError_ASSERT(1664, ia->argcount < argcount);
|
||||||
CError_ASSERT(ia->argcount < argcount);
|
|
||||||
|
|
||||||
if (*format == ',') {
|
if (*format == ',') {
|
||||||
eatcommatoken();
|
eatcommatoken();
|
||||||
|
@ -1114,12 +1113,10 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
code = *format;
|
code = *format;
|
||||||
value = 16;
|
value = 16;
|
||||||
if (code == 'a') {
|
if (code == 'a') {
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1]))
|
||||||
code = *(++format);
|
code = *(++format);
|
||||||
} else {
|
else
|
||||||
#line 1804
|
CError_FATAL(1804);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1])) {
|
||||||
|
@ -1147,10 +1144,8 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
if (negate)
|
if (negate)
|
||||||
op->u.imm.value = -op->u.imm.value;
|
op->u.imm.value = -op->u.imm.value;
|
||||||
|
|
||||||
if (pcode_check_imm_bits(op->u.imm.value, value, code)) {
|
if (pcode_check_imm_bits(op->u.imm.value, value, code))
|
||||||
#line 1838
|
CError_FATAL(1838);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1253,8 +1248,7 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
|
|
||||||
case 'd': {
|
case 'd': {
|
||||||
short effect2;
|
short effect2;
|
||||||
#line 1971
|
CError_ASSERT(1971, format[1] == '(');
|
||||||
CError_ASSERT(format[1] == '(');
|
|
||||||
format++;
|
format++;
|
||||||
effect2 = EffectRead;
|
effect2 = EffectRead;
|
||||||
if (format[1] == '=') {
|
if (format[1] == '=') {
|
||||||
|
@ -1265,10 +1259,8 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
format++;
|
format++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1983
|
CError_ASSERT(1983, format[1] == 'b');
|
||||||
CError_ASSERT(format[1] == 'b');
|
CError_ASSERT(1985, format[2] == ')');
|
||||||
#line 1985
|
|
||||||
CError_ASSERT(format[2] == ')');
|
|
||||||
format += 2;
|
format += 2;
|
||||||
|
|
||||||
switch (ia->opcode) {
|
switch (ia->opcode) {
|
||||||
|
@ -1385,8 +1377,7 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 2266
|
CError_FATAL(2266);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (format[1] && strchr("/<>|*", format[1])) {
|
while (format[1] && strchr("/<>|*", format[1])) {
|
||||||
|
@ -1410,30 +1401,25 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
case '|':
|
case '|':
|
||||||
if (op->type == IAOpnd_Imm) {
|
if (op->type == IAOpnd_Imm)
|
||||||
value = op->u.imm.value;
|
value = op->u.imm.value;
|
||||||
} else if (op->type == IAOpnd_Reg) {
|
else if (op->type == IAOpnd_Reg)
|
||||||
value = op->u.reg.num;
|
value = op->u.reg.num;
|
||||||
} else {
|
else
|
||||||
#line 2312
|
CError_FATAL(2312);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format[1] == 'p') {
|
if (format[1] == 'p') {
|
||||||
format++;
|
format++;
|
||||||
if (op[-1].type == IAOpnd_Imm) {
|
if (op[-1].type == IAOpnd_Imm)
|
||||||
value2 = op[-1].u.imm.value;
|
value2 = op[-1].u.imm.value;
|
||||||
} else if (op[-1].type == IAOpnd_Reg) {
|
else if (op[-1].type == IAOpnd_Reg)
|
||||||
value2 = op[-1].u.reg.num;
|
value2 = op[-1].u.reg.num;
|
||||||
} else {
|
else
|
||||||
#line 2322
|
CError_FATAL(2322);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
} else if (isdigit(format[1])) {
|
} else if (isdigit(format[1])) {
|
||||||
format += pcode_const_from_format(format + 1, &value2);
|
format += pcode_const_from_format(format + 1, &value2);
|
||||||
} else {
|
} else {
|
||||||
#line 2327
|
CError_FATAL(2327);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
@ -1450,18 +1436,15 @@ static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) {
|
||||||
value = value * value2;
|
value = value * value2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2348
|
CError_FATAL(2348);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->type == IAOpnd_Imm) {
|
if (op->type == IAOpnd_Imm)
|
||||||
op->u.imm.value = value;
|
op->u.imm.value = value;
|
||||||
} else if (op->type == IAOpnd_Reg) {
|
else if (op->type == IAOpnd_Reg)
|
||||||
op->u.reg.num = value;
|
op->u.reg.num = value;
|
||||||
} else {
|
else
|
||||||
#line 2355
|
CError_FATAL(2355);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1562,8 +1545,7 @@ void InlineAsm_InitializePPC(void) {
|
||||||
case CPU_PPC7400: case CPU_PPC7450: cpu = CPUMask_74xx; break;
|
case CPU_PPC7400: case CPU_PPC7450: cpu = CPUMask_74xx; break;
|
||||||
case CPU_Generic: cpu = CPUMask_Generic; break;
|
case CPU_Generic: cpu = CPUMask_Generic; break;
|
||||||
default:
|
default:
|
||||||
#line 2613
|
CError_FATAL(2613);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copts.altivec_model)
|
if (copts.altivec_model)
|
||||||
|
@ -1785,7 +1767,7 @@ void InlineAsm_ProcessDirective(SInt32 directive) {
|
||||||
tk = lex();
|
tk = lex();
|
||||||
if (tk == TK_IDENTIFIER) {
|
if (tk == TK_IDENTIFIER) {
|
||||||
if (!strcmp(tkidentifier->name, "PR"))
|
if (!strcmp(tkidentifier->name, "PR"))
|
||||||
sm_section = 1;
|
sm_section = SECT_TEXT;
|
||||||
else
|
else
|
||||||
CError_Error(CErrorStr144);
|
CError_Error(CErrorStr144);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1946,8 +1928,7 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8
|
||||||
extra_args -= (ia->argcount - argcount);
|
extra_args -= (ia->argcount - argcount);
|
||||||
argcount = ia->argcount;
|
argcount = ia->argcount;
|
||||||
} else {
|
} else {
|
||||||
#line 3317
|
CError_FATAL(3317);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2030,10 +2011,8 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8
|
||||||
dest->arg = src->u.reg.rclass;
|
dest->arg = src->u.reg.rclass;
|
||||||
dest->data.reg.reg = r20;
|
dest->data.reg.reg = r20;
|
||||||
dest->data.reg.effect = src->u.reg.effect;
|
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)) {
|
if (pc->op == PC_RLWIMI && (dest->data.reg.effect & EffectWrite) && dest->arg == RegClass_GPR && !(dest->data.reg.effect & EffectRead))
|
||||||
#line 3442
|
CError_FATAL(3442);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest->arg == RegClass_SPR) {
|
if (dest->arg == RegClass_SPR) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -2059,8 +2038,7 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8
|
||||||
if (src->u.reg.object) {
|
if (src->u.reg.object) {
|
||||||
if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag4) {
|
if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag4) {
|
||||||
int reg, regHi;
|
int reg, regHi;
|
||||||
#line 3474
|
CError_ASSERT(3474, dest->arg == RegClass_GPR);
|
||||||
CError_ASSERT(dest->arg == RegClass_GPR);
|
|
||||||
|
|
||||||
regHi = OBJECT_REG_HI(src->u.reg.object);
|
regHi = OBJECT_REG_HI(src->u.reg.object);
|
||||||
reg = OBJECT_REG(src->u.reg.object);
|
reg = OBJECT_REG(src->u.reg.object);
|
||||||
|
@ -2113,8 +2091,7 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 3528
|
CError_FATAL(3528);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2224,8 +2201,7 @@ void InlineAsm_TranslateIRtoPCode(Statement *stmt) {
|
||||||
dest = pc->args[0].data.label.label;
|
dest = pc->args[0].data.label.label;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 3715
|
CError_FATAL(3715);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest) {
|
if (dest) {
|
||||||
|
@ -2379,8 +2355,7 @@ static SInt32 InlineAsm_OpcodeSize(InlineAsm *ia) {
|
||||||
case PC_STVXL:
|
case PC_STVXL:
|
||||||
return 16;
|
return 16;
|
||||||
default:
|
default:
|
||||||
#line 3924
|
CError_FATAL(3924);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (opcodeinfo[ia->opcode].flags & fPCodeFlag80000000)
|
if (opcodeinfo[ia->opcode].flags & fPCodeFlag80000000)
|
||||||
|
@ -2397,14 +2372,12 @@ static SInt32 InlineAsm_OpcodeSize(InlineAsm *ia) {
|
||||||
case PC_TLBLI:
|
case PC_TLBLI:
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
default:
|
||||||
#line 3941
|
CError_FATAL(3941);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 3944
|
CError_FATAL(3944);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2474,8 +2447,7 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) {
|
||||||
effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
|
effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
|
||||||
effects->numoperands++;
|
effects->numoperands++;
|
||||||
} else {
|
} else {
|
||||||
#line 4051
|
CError_FATAL(4051);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2510,14 +2482,11 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) {
|
||||||
effects->x3 = 1;
|
effects->x3 = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 4087
|
CError_FATAL(4087);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 4090
|
CError_ASSERT(4090, effects->numoperands <= 16);
|
||||||
CError_ASSERT(effects->numoperands <= 16);
|
CError_ASSERT(4093, effects->numlabels <= 16);
|
||||||
#line 4093
|
|
||||||
CError_ASSERT(effects->numlabels <= 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
|
for (i = 0, op = ia->args; i < ia->argcount; i++, op++) {
|
||||||
|
@ -2538,8 +2507,7 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) {
|
||||||
effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
|
effects->operands[effects->numoperands].size = op->u.reg.object->type->size;
|
||||||
effects->numoperands++;
|
effects->numoperands++;
|
||||||
} else {
|
} else {
|
||||||
#line 4132
|
CError_FATAL(4132);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2558,8 +2526,7 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 4151
|
CError_ASSERT(4151, effects->numoperands <= 16);
|
||||||
CError_ASSERT(effects->numoperands <= 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info->flags & (fPCodeFlag1 | fPCodeFlag8)) && (SInt32)effects->numlabels == 0)
|
if ((info->flags & (fPCodeFlag1 | fPCodeFlag8)) && (SInt32)effects->numlabels == 0)
|
||||||
|
|
|
@ -122,14 +122,12 @@ static void buildinterferencematrix(void) {
|
||||||
if (coloring_class == RegClass_GPR && (instr->flags & fPCodeFlag8)) {
|
if (coloring_class == RegClass_GPR && (instr->flags & fPCodeFlag8)) {
|
||||||
i = branch_count_volatiles();
|
i = branch_count_volatiles();
|
||||||
op = instr->args;
|
op = instr->args;
|
||||||
#line 219
|
CError_ASSERT(219, instr->argCount != 0);
|
||||||
CError_ASSERT(instr->argCount != 0);
|
|
||||||
|
|
||||||
while (op->kind != PCOp_REGISTER && !(op->data.reg.effect & EffectWrite)) {
|
while (op->kind != PCOp_REGISTER && !(op->data.reg.effect & EffectWrite)) {
|
||||||
i++;
|
i++;
|
||||||
op++;
|
op++;
|
||||||
#line 226
|
CError_ASSERT(226, i <= instr->argCount);
|
||||||
CError_ASSERT(i <= instr->argCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op = instr->args + i;
|
op = instr->args + i;
|
||||||
|
@ -172,15 +170,13 @@ static void coalescenodes(void) {
|
||||||
for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
|
for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
|
||||||
if ((instr->flags & fPCodeFlag10) && !(instr->flags & fSideEffects)) {
|
if ((instr->flags & fPCodeFlag10) && !(instr->flags & fSideEffects)) {
|
||||||
if (PCODE_FLAG_SET_F(instr) & fPCodeFlag20000000) {
|
if (PCODE_FLAG_SET_F(instr) & fPCodeFlag20000000) {
|
||||||
#line 309
|
CError_FATAL(309);
|
||||||
CError_FATAL();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr->argCount > 2) {
|
if (instr->argCount > 2) {
|
||||||
if (instr->argCount != 3 || instr->args[2].kind != PCOp_PLACEHOLDEROPERAND) {
|
if (instr->argCount != 3 || instr->args[2].kind != PCOp_PLACEHOLDEROPERAND) {
|
||||||
#line 316
|
CError_FATAL(316);
|
||||||
CError_FATAL();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,12 +16,10 @@ void Bv_AllocVectorLocal(BitVector **bv, UInt32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bv_ClearBit(UInt32 bit, BitVector *bv) {
|
void Bv_ClearBit(UInt32 bit, BitVector *bv) {
|
||||||
if ((bit / 32) < bv->size) {
|
if ((bit / 32) < bv->size)
|
||||||
bv->data[bit / 32] &= ~(1 << (bit & 31));
|
bv->data[bit / 32] &= ~(1 << (bit & 31));
|
||||||
} else {
|
else
|
||||||
#line 73
|
CError_FATAL(73);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bv_And(const BitVector *a, BitVector *b) {
|
void Bv_And(const BitVector *a, BitVector *b) {
|
||||||
|
|
|
@ -69,14 +69,11 @@ static void GetDependsOfIndirect(IROLinear *nd) {
|
||||||
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 119
|
CError_ASSERT(119, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
var = IRO_FindVar(obj, 1, 1);
|
var = IRO_FindVar(obj, 1, 1);
|
||||||
#line 121
|
CError_ASSERT(121, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
#line 123
|
CError_ASSERT(123, index != 0);
|
||||||
CError_ASSERT(index != 0);
|
|
||||||
|
|
||||||
if (is_volatile_object(obj)) {
|
if (is_volatile_object(obj)) {
|
||||||
IRO_IsVolatile = 1;
|
IRO_IsVolatile = 1;
|
||||||
|
@ -158,8 +155,7 @@ static void GetDependsOfFunctionCallForDataFlow(IROLinear *nd) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 234
|
CError_ASSERT(234, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
depsList = NULL;
|
depsList = NULL;
|
||||||
PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList);
|
PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList);
|
||||||
|
@ -199,11 +195,9 @@ static void GetDependsOfFunctionCallForDataFlow(IROLinear *nd) {
|
||||||
|
|
||||||
for (olist = depsList; olist; olist = olist->next) {
|
for (olist = depsList; olist; olist = olist->next) {
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 285
|
CError_ASSERT(285, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
#line 287
|
CError_ASSERT(287, index != 0);
|
||||||
CError_ASSERT(index != 0);
|
|
||||||
|
|
||||||
if (is_volatile_object(olist->object)) {
|
if (is_volatile_object(olist->object)) {
|
||||||
IRO_IsVolatile = 1;
|
IRO_IsVolatile = 1;
|
||||||
|
@ -312,8 +306,7 @@ static void IRO_DependsOn(IROLinear *linear, Boolean flag) {
|
||||||
IRO_NotSubable = 1;
|
IRO_NotSubable = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 479
|
CError_FATAL(479);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,8 +377,7 @@ static void IRO_DependsOnForDataFlow(IROLinear *linear, Boolean flag) {
|
||||||
GetDependsOfFunctionCallForDataFlow(linear);
|
GetDependsOfFunctionCallForDataFlow(linear);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 650
|
CError_FATAL(650);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,8 +468,7 @@ void IRO_RemoveExpr(IROExpr *expr) {
|
||||||
while (scan != expr) {
|
while (scan != expr) {
|
||||||
prev = scan;
|
prev = scan;
|
||||||
scan = scan->next;
|
scan = scan->next;
|
||||||
#line 809
|
CError_ASSERT(809, scan);
|
||||||
CError_ASSERT(scan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expr->linear->expr = NULL;
|
expr->linear->expr = NULL;
|
||||||
|
@ -544,11 +535,9 @@ static void GetExprKillsByIndirectAssignment(IROLinear *linear) {
|
||||||
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 893
|
CError_ASSERT(893, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
var = IRO_FindVar(obj, 1, 1);
|
var = IRO_FindVar(obj, 1, 1);
|
||||||
#line 895
|
CError_ASSERT(895, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
|
|
||||||
for (expr = IRO_FirstExpr; expr; expr = expr->next) {
|
for (expr = IRO_FirstExpr; expr; expr = expr->next) {
|
||||||
|
@ -615,8 +604,7 @@ static void GetExprKillsByFunctionCall(IROLinear *funccall) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 991
|
CError_ASSERT(991, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
depsList = NULL;
|
depsList = NULL;
|
||||||
PointerAnalysis_GetFunctionKills(obj, funccall, &depsList);
|
PointerAnalysis_GetFunctionKills(obj, funccall, &depsList);
|
||||||
|
@ -656,11 +644,9 @@ static void GetExprKillsByFunctionCall(IROLinear *funccall) {
|
||||||
|
|
||||||
for (olist = depsList; olist; olist = olist->next) {
|
for (olist = depsList; olist; olist = olist->next) {
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 1042
|
CError_ASSERT(1042, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
#line 1044
|
CError_ASSERT(1044, index != 0);
|
||||||
CError_ASSERT(index != 0);
|
|
||||||
|
|
||||||
for (expr = IRO_FirstExpr; expr; expr = expr->next) {
|
for (expr = IRO_FirstExpr; expr; expr = expr->next) {
|
||||||
if (Bv_IsBitSet(index, expr->depends))
|
if (Bv_IsBitSet(index, expr->depends))
|
||||||
|
|
|
@ -93,8 +93,7 @@ static Boolean EmptyLoop(IRONode *fnode) {
|
||||||
if (!Bv_IsBitSet(pred->index, InLoop)) {
|
if (!Bv_IsBitSet(pred->index, InLoop)) {
|
||||||
flag2 = 1;
|
flag2 = 1;
|
||||||
if (pred->nextnode == fnode) {
|
if (pred->nextnode == fnode) {
|
||||||
#line 173
|
CError_ASSERT(173, !bestpred || pred == bestpred);
|
||||||
CError_ASSERT(!bestpred || pred == bestpred);
|
|
||||||
bestpred = pred;
|
bestpred = pred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,8 +440,7 @@ static int CheckStepOverFlow1_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val
|
||||||
if (IS_LINEAR_DIADIC(loop->nd18, ELESS))
|
if (IS_LINEAR_DIADIC(loop->nd18, ELESS))
|
||||||
*val1 = CInt64_Add(*val1, neg1);
|
*val1 = CInt64_Add(*val1, neg1);
|
||||||
|
|
||||||
#line 855
|
CError_ASSERT(855, !CInt64_IsZero(&addConst));
|
||||||
CError_ASSERT(!CInt64_IsZero(&addConst));
|
|
||||||
|
|
||||||
if (isUnsigned)
|
if (isUnsigned)
|
||||||
*val1 = CInt64_DivU(*val1, addConst);
|
*val1 = CInt64_DivU(*val1, addConst);
|
||||||
|
@ -453,15 +451,11 @@ static int CheckStepOverFlow1_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (isUnsigned) {
|
if (isUnsigned) {
|
||||||
if (CInt64_LessEqualU(*val1, cint64_zero)) {
|
if (CInt64_LessEqualU(*val1, cint64_zero))
|
||||||
#line 877
|
CError_FATAL(877);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (CInt64_LessEqual(*val1, cint64_zero)) {
|
if (CInt64_LessEqual(*val1, cint64_zero))
|
||||||
#line 886
|
CError_FATAL(886);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUnsigned) {
|
if (isUnsigned) {
|
||||||
|
@ -521,8 +515,7 @@ static int CheckStepOverFlow2_EmptyLoop(IROLoop *loop, CInt64 *val1, CInt64 *val
|
||||||
if (IS_LINEAR_DIADIC(loop->nd18, EGREATER))
|
if (IS_LINEAR_DIADIC(loop->nd18, EGREATER))
|
||||||
*val1 = CInt64_Add(*val1, neg1);
|
*val1 = CInt64_Add(*val1, neg1);
|
||||||
|
|
||||||
#line 995
|
CError_ASSERT(995, !CInt64_IsZero(&addConst));
|
||||||
CError_ASSERT(!CInt64_IsZero(&addConst));
|
|
||||||
|
|
||||||
if (isUnsigned)
|
if (isUnsigned)
|
||||||
*val1 = CInt64_DivU(*val1, addConst);
|
*val1 = CInt64_DivU(*val1, addConst);
|
||||||
|
|
|
@ -66,8 +66,7 @@ static void AddLabelSucc(IRONode *node, CLabel *label) {
|
||||||
AddSucc(node, targetnode);
|
AddSucc(node, targetnode);
|
||||||
targetnode->x39 = 1;
|
targetnode->x39 = 1;
|
||||||
} else {
|
} else {
|
||||||
#line 126
|
CError_FATAL(126);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,8 +228,7 @@ static inline void MarkSubExpr(IROLinear *linear) {
|
||||||
linear->u.funccall.args[i]->flags |= IROLF_Reffed;
|
linear->u.funccall.args[i]->flags |= IROLF_Reffed;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 368
|
CError_FATAL(368);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,12 +280,10 @@ static void AssignCommaRToTemp(ENode *enode, Boolean flag) {
|
||||||
ENode *indnode = IRO_NewENode(EINDIRECT);
|
ENode *indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(obj);
|
indnode->data.monadic = create_objectrefnode(obj);
|
||||||
|
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 548
|
CError_FATAL(548);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt = lalloc(sizeof(Statement));
|
stmt = lalloc(sizeof(Statement));
|
||||||
memset(stmt, 0, sizeof(Statement));
|
memset(stmt, 0, sizeof(Statement));
|
||||||
|
@ -311,8 +308,7 @@ static void AssignCommaRToTemp(ENode *enode, Boolean flag) {
|
||||||
|
|
||||||
enode->type = EINDIRECT;
|
enode->type = EINDIRECT;
|
||||||
enode->data.monadic = create_objectrefnode(obj);
|
enode->data.monadic = create_objectrefnode(obj);
|
||||||
#line 580
|
CError_ASSERT(580, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
} else {
|
} else {
|
||||||
stmt = lalloc(sizeof(Statement));
|
stmt = lalloc(sizeof(Statement));
|
||||||
memset(stmt, 0, sizeof(Statement));
|
memset(stmt, 0, sizeof(Statement));
|
||||||
|
@ -347,12 +343,10 @@ static void AssignDangerousArgumentToTemp(ENode *enode) {
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(obj);
|
indnode->data.monadic = create_objectrefnode(obj);
|
||||||
|
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 627
|
CError_FATAL(627);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
rightnode = IRO_NewENode(enode->type);
|
rightnode = IRO_NewENode(enode->type);
|
||||||
memcpy(rightnode, enode, sizeof(ENode));
|
memcpy(rightnode, enode, sizeof(ENode));
|
||||||
|
@ -390,12 +384,10 @@ static void CreateTempAssignmentToZero(ENode *enode, Object **objptr) {
|
||||||
*objptr = create_temp_object(enode->rtype);
|
*objptr = create_temp_object(enode->rtype);
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 678
|
CError_FATAL(678);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
rightnode = IRO_NewENode(EINTCONST);
|
rightnode = IRO_NewENode(EINTCONST);
|
||||||
rightnode->data.intval = cint64_zero;
|
rightnode->data.intval = cint64_zero;
|
||||||
|
@ -431,12 +423,10 @@ static void CreateTempAssignmentToOne(ENode *enode, Object **objptr) {
|
||||||
*objptr = create_temp_object(enode->rtype);
|
*objptr = create_temp_object(enode->rtype);
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 720
|
CError_FATAL(720);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
rightnode = IRO_NewENode(EINTCONST);
|
rightnode = IRO_NewENode(EINTCONST);
|
||||||
rightnode->data.intval = cint64_one;
|
rightnode->data.intval = cint64_one;
|
||||||
|
@ -534,8 +524,7 @@ static Object *GetTempFromtheList(ENode *expr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 839
|
CError_ASSERT(839, n);
|
||||||
CError_ASSERT(n);
|
|
||||||
return n->tempobj;
|
return n->tempobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,8 +581,7 @@ static void GenerateExpr1TempAssignment(ENode *enode, Object **objptr) {
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
#line 905
|
CError_ASSERT(905, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = lalloc(sizeof(Statement));
|
stmt = lalloc(sizeof(Statement));
|
||||||
|
@ -631,8 +619,7 @@ static void GenerateExpr2TempAssignment(ENode *enode, Object **objptr) {
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
#line 953
|
CError_ASSERT(953, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = lalloc(sizeof(Statement));
|
stmt = lalloc(sizeof(Statement));
|
||||||
|
@ -671,8 +658,7 @@ static void GenerateForceLoadTempAssignment(ENode *enode, Object **objptr) {
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
#line 1003
|
CError_ASSERT(1003, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = lalloc(sizeof(Statement));
|
stmt = lalloc(sizeof(Statement));
|
||||||
|
@ -845,12 +831,10 @@ static void TransformLogicalAndRHS(ENode *enode, Object **objptr, CLabel **label
|
||||||
|
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 1225
|
CError_FATAL(1225);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
rightnode = IRO_NewENode(EINTCONST);
|
rightnode = IRO_NewENode(EINTCONST);
|
||||||
rightnode->data.intval = cint64_one;
|
rightnode->data.intval = cint64_one;
|
||||||
|
@ -898,8 +882,7 @@ static void TransformLogicalAndRHS(ENode *enode, Object **objptr, CLabel **label
|
||||||
|
|
||||||
enode->type = EINDIRECT;
|
enode->type = EINDIRECT;
|
||||||
enode->data.monadic = create_objectrefnode(*objptr);
|
enode->data.monadic = create_objectrefnode(*objptr);
|
||||||
#line 1276
|
CError_ASSERT(1276, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TransformLogicalOrLHS(ENode *enode, Object **objptr, CLabel **labelptr) {
|
static void TransformLogicalOrLHS(ENode *enode, Object **objptr, CLabel **labelptr) {
|
||||||
|
@ -953,12 +936,10 @@ static void TransformLogicalOrRHS(ENode *enode, Object **objptr, CLabel **labelp
|
||||||
|
|
||||||
indnode = IRO_NewENode(EINDIRECT);
|
indnode = IRO_NewENode(EINDIRECT);
|
||||||
indnode->data.monadic = create_objectrefnode(*objptr);
|
indnode->data.monadic = create_objectrefnode(*objptr);
|
||||||
if (!IS_TYPE_VOID(enode->rtype)) {
|
if (!IS_TYPE_VOID(enode->rtype))
|
||||||
indnode->rtype = enode->rtype;
|
indnode->rtype = enode->rtype;
|
||||||
} else {
|
else
|
||||||
#line 1354
|
CError_FATAL(1354);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
rightnode = IRO_NewENode(EINTCONST);
|
rightnode = IRO_NewENode(EINTCONST);
|
||||||
rightnode->data.intval = cint64_zero;
|
rightnode->data.intval = cint64_zero;
|
||||||
|
@ -1006,24 +987,22 @@ static void TransformLogicalOrRHS(ENode *enode, Object **objptr, CLabel **labelp
|
||||||
|
|
||||||
enode->type = EINDIRECT;
|
enode->type = EINDIRECT;
|
||||||
enode->data.monadic = create_objectrefnode(*objptr);
|
enode->data.monadic = create_objectrefnode(*objptr);
|
||||||
#line 1405
|
CError_ASSERT(1405, !IS_TYPE_VOID(enode->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(enode->rtype));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
switch (a->type) {
|
switch (a->type) {
|
||||||
ENODE_CASE_MONADIC
|
ENODE_CASE_MONADIC:
|
||||||
LinearizeExpr1(a->data.monadic, a, 0, 0);
|
LinearizeExpr1(a->data.monadic, a, 0, 0);
|
||||||
if (a->type == EFORCELOAD) {
|
if (a->type == EFORCELOAD) {
|
||||||
Object *obj;
|
Object *obj;
|
||||||
GenerateForceLoadTempAssignment(a, &obj);
|
GenerateForceLoadTempAssignment(a, &obj);
|
||||||
a->type = EINDIRECT;
|
a->type = EINDIRECT;
|
||||||
a->data.monadic = create_objectrefnode(obj);
|
a->data.monadic = create_objectrefnode(obj);
|
||||||
#line 1428
|
CError_ASSERT(1428, !IS_TYPE_VOID(a->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(a->rtype));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
ENODE_CASE_DIADIC_1
|
ENODE_CASE_DIADIC_1:
|
||||||
case ECOMMA:
|
case ECOMMA:
|
||||||
case EPMODULO:
|
case EPMODULO:
|
||||||
case EROTL:
|
case EROTL:
|
||||||
|
@ -1042,7 +1021,7 @@ static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
LinearizeExpr1(a->data.diadic.right, a, 0, 0);
|
LinearizeExpr1(a->data.diadic.right, a, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
ENODE_CASE_ASSIGN
|
ENODE_CASE_ASSIGN:
|
||||||
LinearizeExpr1(a->data.diadic.right, a, 0, 0);
|
LinearizeExpr1(a->data.diadic.right, a, 0, 0);
|
||||||
LinearizeExpr1(a->data.diadic.left, a, 0, 0);
|
LinearizeExpr1(a->data.diadic.left, a, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -1081,8 +1060,7 @@ static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
if (!IS_TYPE_VOID(a->rtype)) {
|
if (!IS_TYPE_VOID(a->rtype)) {
|
||||||
a->type = EINDIRECT;
|
a->type = EINDIRECT;
|
||||||
a->data.monadic = create_objectrefnode(obj);
|
a->data.monadic = create_objectrefnode(obj);
|
||||||
#line 1596
|
CError_ASSERT(1596, !IS_TYPE_VOID(a->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(a->rtype));
|
|
||||||
} else {
|
} else {
|
||||||
a->type = EINTCONST;
|
a->type = EINTCONST;
|
||||||
a->data.intval = cint64_zero;
|
a->data.intval = cint64_zero;
|
||||||
|
@ -1093,8 +1071,7 @@ static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
Object *temp = GetTempFromtheList(a);
|
Object *temp = GetTempFromtheList(a);
|
||||||
a->type = EINDIRECT;
|
a->type = EINDIRECT;
|
||||||
a->data.monadic = create_objectrefnode(temp);
|
a->data.monadic = create_objectrefnode(temp);
|
||||||
#line 1614
|
CError_ASSERT(1614, !IS_TYPE_VOID(a->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(a->rtype));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ENULLCHECK: {
|
case ENULLCHECK: {
|
||||||
|
@ -1109,8 +1086,7 @@ static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
if (!IS_TYPE_VOID(a->rtype)) {
|
if (!IS_TYPE_VOID(a->rtype)) {
|
||||||
a->type = EINDIRECT;
|
a->type = EINDIRECT;
|
||||||
a->data.monadic = create_objectrefnode(obj);
|
a->data.monadic = create_objectrefnode(obj);
|
||||||
#line 1639
|
CError_ASSERT(1639, !IS_TYPE_VOID(a->rtype));
|
||||||
CError_ASSERT(!IS_TYPE_VOID(a->rtype));
|
|
||||||
} else {
|
} else {
|
||||||
a->type = EINTCONST;
|
a->type = EINTCONST;
|
||||||
a->data.intval = cint64_zero;
|
a->data.intval = cint64_zero;
|
||||||
|
@ -1165,8 +1141,7 @@ static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 1723
|
CError_FATAL(1723);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,7 +1149,7 @@ static IROLinear *LinearizeExpr(ENode *enode) {
|
||||||
IROLinear *linear = NULL;
|
IROLinear *linear = NULL;
|
||||||
|
|
||||||
switch (enode->type) {
|
switch (enode->type) {
|
||||||
ENODE_CASE_MONADIC
|
ENODE_CASE_MONADIC:
|
||||||
linear = IRO_NewLinear(IROLinearOp1Arg);
|
linear = IRO_NewLinear(IROLinearOp1Arg);
|
||||||
linear->u.monadic = LinearizeExpr(enode->data.monadic);
|
linear->u.monadic = LinearizeExpr(enode->data.monadic);
|
||||||
linear->nodetype = enode->type;
|
linear->nodetype = enode->type;
|
||||||
|
@ -1189,7 +1164,7 @@ static IROLinear *LinearizeExpr(ENode *enode) {
|
||||||
MarkSubscript(linear->u.monadic);
|
MarkSubscript(linear->u.monadic);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
ENODE_CASE_DIADIC_1
|
ENODE_CASE_DIADIC_1:
|
||||||
case ECOMMA:
|
case ECOMMA:
|
||||||
case EPMODULO:
|
case EPMODULO:
|
||||||
case EROTL:
|
case EROTL:
|
||||||
|
@ -1210,7 +1185,7 @@ static IROLinear *LinearizeExpr(ENode *enode) {
|
||||||
if (IRO_IsAssignOp[linear->nodetype])
|
if (IRO_IsAssignOp[linear->nodetype])
|
||||||
MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]);
|
MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]);
|
||||||
break;
|
break;
|
||||||
ENODE_CASE_ASSIGN
|
ENODE_CASE_ASSIGN:
|
||||||
linear = IRO_NewLinear(IROLinearOp2Arg);
|
linear = IRO_NewLinear(IROLinearOp2Arg);
|
||||||
linear->nodeflags = enode->flags;
|
linear->nodeflags = enode->flags;
|
||||||
linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right);
|
linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right);
|
||||||
|
@ -1278,8 +1253,7 @@ static IROLinear *LinearizeExpr(ENode *enode) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
#line 1943
|
CError_FATAL(1943);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linear)
|
if (linear)
|
||||||
|
@ -1303,8 +1277,7 @@ void IRO_PreLinearize(Statement *stmt) {
|
||||||
case ST_GOTO:
|
case ST_GOTO:
|
||||||
break;
|
break;
|
||||||
case ST_OVF:
|
case ST_OVF:
|
||||||
#line 1989
|
CError_FATAL(1989);
|
||||||
CError_FATAL();
|
|
||||||
case ST_EXPRESSION:
|
case ST_EXPRESSION:
|
||||||
LinearizeExpr1(stmt->expr, NULL, 0, 0);
|
LinearizeExpr1(stmt->expr, NULL, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -1337,8 +1310,7 @@ void IRO_PreLinearize(Statement *stmt) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 2038
|
CError_FATAL(2038);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PrevStmt = stmt;
|
PrevStmt = stmt;
|
||||||
|
@ -1409,8 +1381,7 @@ void IRO_Linearize(Statement *stmt) {
|
||||||
linear->u.monadic = NULL;
|
linear->u.monadic = NULL;
|
||||||
break;
|
break;
|
||||||
case ST_OVF:
|
case ST_OVF:
|
||||||
#line 2143
|
CError_FATAL(2143);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
case ST_EXIT:
|
case ST_EXIT:
|
||||||
linear = IRO_NewLinear(IROLinearExit);
|
linear = IRO_NewLinear(IROLinearExit);
|
||||||
|
@ -1448,8 +1419,7 @@ void IRO_Linearize(Statement *stmt) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2194
|
CError_FATAL(2194);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linear)
|
if (linear)
|
||||||
|
@ -1567,8 +1537,7 @@ static ENode *BuildExpr(IROLinear *linear) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
IRO_Dump("Oh, oh, bad expression type in BuildExpr at: %d\n", linear->index);
|
IRO_Dump("Oh, oh, bad expression type in BuildExpr at: %d\n", linear->index);
|
||||||
#line 2390
|
CError_FATAL(2390);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enode->pointsTo = linear->pointsToFunction;
|
enode->pointsTo = linear->pointsToFunction;
|
||||||
|
@ -1667,8 +1636,7 @@ Statement *IRO_Delinearize(IRONode *node, IROLinear *linear) {
|
||||||
stmt = NULL;
|
stmt = NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2685
|
CError_FATAL(2685);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt) {
|
if (stmt) {
|
||||||
|
@ -1742,8 +1710,7 @@ static void TravExprToUpdateFlags(IROLinear *linear) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
IRO_Dump("Oh, oh, bad expression type in TravExprToUpdateFlags at: %d\n", linear->index);
|
IRO_Dump("Oh, oh, bad expression type in TravExprToUpdateFlags at: %d\n", linear->index);
|
||||||
#line 2853
|
CError_FATAL(2853);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1793,8 +1760,7 @@ void IRO_UpdateFlagsOnInts(void) {
|
||||||
case IROLinearEnd:
|
case IROLinearEnd:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2931
|
CError_FATAL(2931);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (linear == node->last)
|
if (linear == node->last)
|
||||||
|
|
|
@ -402,8 +402,7 @@ static int Reducable(IROLinear *nd, IROLinear **resultNd1, IROLinear **resultNd2
|
||||||
)
|
)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#line 802
|
CError_ASSERT(802, indirect->u.monadic->u.node != NULL);
|
||||||
CError_ASSERT(indirect->u.monadic->u.node != NULL);
|
|
||||||
*resultVar = IRO_FindVar(indirect->u.monadic->u.node->data.objref, 0, 1);
|
*resultVar = IRO_FindVar(indirect->u.monadic->u.node->data.objref, 0, 1);
|
||||||
if (!*resultVar || (*resultVar)->xA != 2)
|
if (!*resultVar || (*resultVar)->xA != 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -419,8 +418,7 @@ static int Reducable(IROLinear *nd, IROLinear **resultNd1, IROLinear **resultNd2
|
||||||
while (ind && ind->var != *resultVar)
|
while (ind && ind->var != *resultVar)
|
||||||
ind = ind->next;
|
ind = ind->next;
|
||||||
|
|
||||||
#line 845
|
CError_ASSERT(845, ind != NULL);
|
||||||
CError_ASSERT(ind != NULL);
|
|
||||||
|
|
||||||
if (ind->addNode == NULL) {
|
if (ind->addNode == NULL) {
|
||||||
if (ind->addConst < (val = CInt64_GetULong(&val64)))
|
if (ind->addConst < (val = CInt64_GetULong(&val64)))
|
||||||
|
@ -632,8 +630,7 @@ static IRONode *CreatePreHeader(IRONode *fnode1, IRONode *fnode2) {
|
||||||
fnode2->nextnode = newfnode;
|
fnode2->nextnode = newfnode;
|
||||||
newfnode->nextnode = fnode1;
|
newfnode->nextnode = fnode1;
|
||||||
} else {
|
} else {
|
||||||
#line 1254
|
CError_ASSERT(1254, fnode1->first->type == IROLinearLabel);
|
||||||
CError_ASSERT(fnode1->first->type == IROLinearLabel);
|
|
||||||
labelnode->next = IRO_NewLinear(IROLinearGoto);
|
labelnode->next = IRO_NewLinear(IROLinearGoto);
|
||||||
labelnode->next->u.label.label = fnode1->first->u.label.label;
|
labelnode->next->u.label.label = fnode1->first->u.label.label;
|
||||||
IRO_LastNode->last->next = labelnode;
|
IRO_LastNode->last->next = labelnode;
|
||||||
|
@ -695,8 +692,7 @@ static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) {
|
||||||
SwitchCase *swcase;
|
SwitchCase *swcase;
|
||||||
UInt16 i;
|
UInt16 i;
|
||||||
|
|
||||||
#line 1355
|
CError_ASSERT(1355, fnode1 != NULL && LoopExitNumber == 1);
|
||||||
CError_ASSERT(fnode1 != NULL && LoopExitNumber == 1);
|
|
||||||
|
|
||||||
fnode2 = NULL;
|
fnode2 = NULL;
|
||||||
flag = 0;
|
flag = 0;
|
||||||
|
@ -704,8 +700,7 @@ static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) {
|
||||||
for (i = 0; i < fnode1->numpred; i++) {
|
for (i = 0; i < fnode1->numpred; i++) {
|
||||||
iter = IRO_NodeTable[fnode1->pred[i]];
|
iter = IRO_NodeTable[fnode1->pred[i]];
|
||||||
if (Bv_IsBitSet(iter->index, InLoop_Exits)) {
|
if (Bv_IsBitSet(iter->index, InLoop_Exits)) {
|
||||||
#line 1366
|
CError_ASSERT(1366, fnode2 == NULL);
|
||||||
CError_ASSERT(fnode2 == NULL);
|
|
||||||
fnode2 = iter;
|
fnode2 = iter;
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
if (
|
if (
|
||||||
|
@ -721,8 +716,7 @@ static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1382
|
CError_ASSERT(1382, fnode2 != NULL);
|
||||||
CError_ASSERT(fnode2 != NULL);
|
|
||||||
|
|
||||||
newfnode = oalloc(sizeof(IRONode));
|
newfnode = oalloc(sizeof(IRONode));
|
||||||
memset(newfnode, 0, sizeof(IRONode));
|
memset(newfnode, 0, sizeof(IRONode));
|
||||||
|
@ -745,8 +739,7 @@ static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) {
|
||||||
fnode2->nextnode = newfnode;
|
fnode2->nextnode = newfnode;
|
||||||
newfnode->nextnode = fnode1;
|
newfnode->nextnode = fnode1;
|
||||||
} else {
|
} else {
|
||||||
#line 1422
|
CError_ASSERT(1422, fnode1->first->type == IROLinearLabel);
|
||||||
CError_ASSERT(fnode1->first->type == IROLinearLabel);
|
|
||||||
labelnode->next = IRO_NewLinear(IROLinearGoto);
|
labelnode->next = IRO_NewLinear(IROLinearGoto);
|
||||||
labelnode->next->u.label.label = fnode1->first->u.label.label;
|
labelnode->next->u.label.label = fnode1->first->u.label.label;
|
||||||
IRO_LastNode->last->next = labelnode;
|
IRO_LastNode->last->next = labelnode;
|
||||||
|
@ -1260,8 +1253,7 @@ static void MyHandleLoop_Vector(IRONode *fnode) {
|
||||||
node22 = pred;
|
node22 = pred;
|
||||||
flag21 = 1;
|
flag21 = 1;
|
||||||
if (pred->nextnode == fnode) {
|
if (pred->nextnode == fnode) {
|
||||||
#line 2880
|
CError_ASSERT(2880, v2 == NULL || pred == v2);
|
||||||
CError_ASSERT(v2 == NULL || pred == v2);
|
|
||||||
v2 = pred;
|
v2 = pred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1326,8 +1318,7 @@ static void MyHandleLoop_Vector(IRONode *fnode) {
|
||||||
induction = FirstInd;
|
induction = FirstInd;
|
||||||
while (induction && induction->var != var)
|
while (induction && induction->var != var)
|
||||||
induction = induction->next;
|
induction = induction->next;
|
||||||
#line 3529
|
CError_ASSERT(3529, induction != NULL);
|
||||||
CError_ASSERT(induction != NULL);
|
|
||||||
|
|
||||||
IRO_FindDepends(reduceNd1);
|
IRO_FindDepends(reduceNd1);
|
||||||
if (!Bv_BitsInCommon(IRO_Depends, AllKills)) {
|
if (!Bv_BitsInCommon(IRO_Depends, AllKills)) {
|
||||||
|
@ -1445,8 +1436,7 @@ static void MyHandleLoop_Motion(IRONode *fnode) {
|
||||||
node21 = pred;
|
node21 = pred;
|
||||||
flag20 = 1;
|
flag20 = 1;
|
||||||
if (pred->nextnode == fnode) {
|
if (pred->nextnode == fnode) {
|
||||||
#line 3880
|
CError_ASSERT(3880, v2 == NULL || pred == v2);
|
||||||
CError_ASSERT(v2 == NULL || pred == v2);
|
|
||||||
v2 = pred;
|
v2 = pred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1536,8 +1526,7 @@ static void MyHandleLoop_Motion(IRONode *fnode) {
|
||||||
IRO_AddToList(ass, &list);
|
IRO_AddToList(ass, &list);
|
||||||
IRO_Paste(list.head, list.tail, PredInt);
|
IRO_Paste(list.head, list.tail, PredInt);
|
||||||
} else {
|
} else {
|
||||||
#line 4123
|
CError_FATAL(4123);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LoopExitSuccessor->numpred != 1)
|
if (LoopExitSuccessor->numpred != 1)
|
||||||
|
|
|
@ -396,14 +396,12 @@ Boolean IRO_CopyAndConstantPropagation(void) {
|
||||||
for (ass2 = IRO_FirstAssign; ass2; ass2 = ass2->next) {
|
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) {
|
if (ass2->varIndex == var->index && Bv_IsBitSet(ass2->index, IRO_Avail) && ass2->linear->rtype->size == effects.operands[i].size) {
|
||||||
ENode *enode;
|
ENode *enode;
|
||||||
if (ass2->varObj) {
|
if (ass2->varObj)
|
||||||
enode = create_objectrefnode(ass2->varObj);
|
enode = create_objectrefnode(ass2->varObj);
|
||||||
} else if (ass2->linear2->type == IROLinearOperand) {
|
else if (ass2->linear2->type == IROLinearOperand)
|
||||||
enode = ass2->linear2->u.node;
|
enode = ass2->linear2->u.node;
|
||||||
} else {
|
else
|
||||||
#line 768
|
CError_FATAL(768);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
CodeGen_PropagateIntoAsm(linear->u.asm_stmt, effects.operands[i].object, enode);
|
CodeGen_PropagateIntoAsm(linear->u.asm_stmt, effects.operands[i].object, enode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,8 +193,7 @@ static void SetRangesForKillsByIndirectAssignment(IROLinear *nd) {
|
||||||
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 302
|
CError_ASSERT(302, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
range = nd->x16;
|
range = nd->x16;
|
||||||
if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
|
if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
|
||||||
|
@ -266,8 +265,7 @@ static void InvalidateRangesForKillsByFunctionCall(IROLinear *nd) {
|
||||||
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = scannd->u.node->data.objref;
|
obj = scannd->u.node->data.objref;
|
||||||
#line 385
|
CError_ASSERT(385, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
killList = NULL;
|
killList = NULL;
|
||||||
PointerAnalysis_GetFunctionKills(obj, nd, &killList);
|
PointerAnalysis_GetFunctionKills(obj, nd, &killList);
|
||||||
|
|
|
@ -149,14 +149,12 @@ Type *IRO_UnsignedType(Type *type) {
|
||||||
return TYPE(&stunsignedlong);
|
return TYPE(&stunsignedlong);
|
||||||
if (type->size == stunsignedlonglong.size)
|
if (type->size == stunsignedlonglong.size)
|
||||||
return TYPE(&stunsignedlonglong);
|
return TYPE(&stunsignedlonglong);
|
||||||
#line 281
|
CError_FATAL(281);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_TYPE_INT(type)) {
|
if (!IS_TYPE_INT(type)) {
|
||||||
#line 287
|
CError_FATAL(287);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +172,7 @@ Type *IRO_UnsignedType(Type *type) {
|
||||||
if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
|
if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
|
||||||
return TYPE(&stunsignedlonglong);
|
return TYPE(&stunsignedlonglong);
|
||||||
|
|
||||||
#line 319
|
CError_FATAL(319);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,14 +188,12 @@ Type *IRO_SignedType(Type *type) {
|
||||||
return TYPE(&stsignedlong);
|
return TYPE(&stsignedlong);
|
||||||
if (type->size == stsignedlonglong.size)
|
if (type->size == stsignedlonglong.size)
|
||||||
return TYPE(&stsignedlonglong);
|
return TYPE(&stsignedlonglong);
|
||||||
#line 357
|
CError_FATAL(357);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_TYPE_INT(type)) {
|
if (!IS_TYPE_INT(type)) {
|
||||||
#line 363
|
CError_FATAL(363);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +214,7 @@ Type *IRO_SignedType(Type *type) {
|
||||||
if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
|
if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong))
|
||||||
return TYPE(&stsignedlonglong);
|
return TYPE(&stsignedlonglong);
|
||||||
|
|
||||||
#line 399
|
CError_FATAL(399);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +365,7 @@ IROLinear *IRO_FindFirst(IROLinear *linear) {
|
||||||
i = linear->u.funccall.argCount - 1;
|
i = linear->u.funccall.argCount - 1;
|
||||||
return IRO_FindFirst(linear->u.funccall.args[i]);
|
return IRO_FindFirst(linear->u.funccall.args[i]);
|
||||||
default:
|
default:
|
||||||
#line 641
|
CError_FATAL(641);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,8 +555,7 @@ void IRO_Cut(IROLinear *a, IROLinear *b) {
|
||||||
for (scan = IRO_FirstLinear; scan && scan != a; scan = scan->next)
|
for (scan = IRO_FirstLinear; scan && scan != a; scan = scan->next)
|
||||||
prev = scan;
|
prev = scan;
|
||||||
|
|
||||||
#line 951
|
CError_ASSERT(951, scan);
|
||||||
CError_ASSERT(scan);
|
|
||||||
|
|
||||||
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
||||||
if (node->first == a) {
|
if (node->first == a) {
|
||||||
|
@ -591,15 +583,13 @@ void IRO_Paste(IROLinear *a, IROLinear *b, IROLinear *c) {
|
||||||
IROLinear *scan;
|
IROLinear *scan;
|
||||||
IRONode *node;
|
IRONode *node;
|
||||||
|
|
||||||
#line 1002
|
CError_ASSERT(1002, c && c->type != IROLinearLabel);
|
||||||
CError_ASSERT(c && c->type != IROLinearLabel);
|
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for (scan = IRO_FirstLinear; scan && scan != c; scan = scan->next)
|
for (scan = IRO_FirstLinear; scan && scan != c; scan = scan->next)
|
||||||
prev = scan;
|
prev = scan;
|
||||||
|
|
||||||
#line 1016
|
CError_ASSERT(1016, scan);
|
||||||
CError_ASSERT(scan);
|
|
||||||
|
|
||||||
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
||||||
if (node->first == c) {
|
if (node->first == c) {
|
||||||
|
@ -623,8 +613,7 @@ void IRO_PasteAfter(IROLinear *a, IROLinear *b, IROLinear *c) {
|
||||||
case IROLinearIf:
|
case IROLinearIf:
|
||||||
case IROLinearIfNot:
|
case IROLinearIfNot:
|
||||||
case IROLinearSwitch:
|
case IROLinearSwitch:
|
||||||
#line 1060
|
CError_FATAL(1060);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
for (node = IRO_FirstNode; node; node = node->nextnode) {
|
||||||
|
@ -719,8 +708,7 @@ IROLinear *IRO_FindLabelNode(CLabel *label, IROLinear *linear) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 1244
|
CError_ASSERT(1244, scan);
|
||||||
CError_ASSERT(scan);
|
|
||||||
return scan;
|
return scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,8 +889,7 @@ inline IROLinear *LocateFatherHelper(IROLinear *linear, Boolean a, IROLinear ***
|
||||||
case IROLinearEnd:
|
case IROLinearEnd:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1536
|
CError_FATAL(1536);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
scan = scan->next;
|
scan = scan->next;
|
||||||
}
|
}
|
||||||
|
@ -923,8 +910,7 @@ IROLinear *IRO_LocateFather_Cut_And_Paste(IROLinear *a, IROLinear *b) {
|
||||||
IROLinear **p;
|
IROLinear **p;
|
||||||
IROLinear *l = LocateFatherHelper(a, 0, &p);
|
IROLinear *l = LocateFatherHelper(a, 0, &p);
|
||||||
if (l) {
|
if (l) {
|
||||||
#line 1568
|
CError_ASSERT(1568, p && *p);
|
||||||
CError_ASSERT(p && *p);
|
|
||||||
IRO_NopOut(a);
|
IRO_NopOut(a);
|
||||||
*p = b;
|
*p = b;
|
||||||
}
|
}
|
||||||
|
@ -935,8 +921,7 @@ IROLinear *IRO_LocateFather_Cut_And_Paste_Without_Nopping(IROLinear *a, IROLinea
|
||||||
IROLinear **p;
|
IROLinear **p;
|
||||||
IROLinear *l = LocateFatherHelper(a, 0, &p);
|
IROLinear *l = LocateFatherHelper(a, 0, &p);
|
||||||
if (l) {
|
if (l) {
|
||||||
#line 1585
|
CError_ASSERT(1585, p && *p);
|
||||||
CError_ASSERT(p && *p);
|
|
||||||
*p = b;
|
*p = b;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
|
@ -947,8 +932,7 @@ void IRO_ReplaceReference(IROLinear *a, Object *obj, IROLinear *b) {
|
||||||
IROList list;
|
IROList list;
|
||||||
|
|
||||||
if (LocateFatherHelper(a, 1, &ptr)) {
|
if (LocateFatherHelper(a, 1, &ptr)) {
|
||||||
#line 1605
|
CError_ASSERT(1605, ptr && *ptr);
|
||||||
CError_ASSERT(ptr && *ptr);
|
|
||||||
IRO_InitList(&list);
|
IRO_InitList(&list);
|
||||||
*ptr = IRO_TempReference(obj, &list);
|
*ptr = IRO_TempReference(obj, &list);
|
||||||
IRO_PasteAfter(list.head, list.tail, b);
|
IRO_PasteAfter(list.head, list.tail, b);
|
||||||
|
@ -964,8 +948,7 @@ void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b) {
|
||||||
IROList list;
|
IROList list;
|
||||||
|
|
||||||
if (LocateFatherHelper(a, 1, &ptr)) {
|
if (LocateFatherHelper(a, 1, &ptr)) {
|
||||||
#line 1664
|
CError_ASSERT(1664, ptr && *ptr);
|
||||||
CError_ASSERT(ptr && *ptr);
|
|
||||||
*ptr = b;
|
*ptr = b;
|
||||||
b->flags |= IROLF_Reffed;
|
b->flags |= IROLF_Reffed;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -467,14 +467,12 @@ VarRecord *IRO_FindAssigned(IROLinear *linear) {
|
||||||
VarRecord *rec;
|
VarRecord *rec;
|
||||||
|
|
||||||
IRO_IsBitField = 0;
|
IRO_IsBitField = 0;
|
||||||
if (linear->type == IROLinearOp2Arg) {
|
if (linear->type == IROLinearOp2Arg)
|
||||||
linear = linear->u.diadic.left;
|
linear = linear->u.diadic.left;
|
||||||
} else if (linear->type == IROLinearOp1Arg) {
|
else if (linear->type == IROLinearOp1Arg)
|
||||||
linear = linear->u.monadic;
|
linear = linear->u.monadic;
|
||||||
} else {
|
else
|
||||||
#line 818
|
CError_FATAL(818);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_LINEAR_MONADIC(linear, EINDIRECT))
|
if (IS_LINEAR_MONADIC(linear, EINDIRECT))
|
||||||
linear = linear->u.monadic;
|
linear = linear->u.monadic;
|
||||||
|
@ -561,16 +559,13 @@ static void GetKillsByIndirectAssignment(IROLinear *linear) {
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 952
|
CError_ASSERT(952, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
var = IRO_FindVar(obj, 1, 1);
|
var = IRO_FindVar(obj, 1, 1);
|
||||||
#line 954
|
CError_ASSERT(954, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
#line 956
|
CError_ASSERT(956, index != 0);
|
||||||
CError_ASSERT(index != 0);
|
|
||||||
|
|
||||||
Bv_SetBit(index, IRO_VarKills);
|
Bv_SetBit(index, IRO_VarKills);
|
||||||
}
|
}
|
||||||
|
@ -631,8 +626,7 @@ static void GetKillsByFunctionCall(IROLinear *linear) {
|
||||||
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
||||||
foundLinear = 1;
|
foundLinear = 1;
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 1028
|
CError_ASSERT(1028, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
killList = NULL;
|
killList = NULL;
|
||||||
PointerAnalysis_GetFunctionKills(obj, linear, &killList);
|
PointerAnalysis_GetFunctionKills(obj, linear, &killList);
|
||||||
|
@ -674,12 +668,10 @@ static void GetKillsByFunctionCall(IROLinear *linear) {
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 1079
|
CError_ASSERT(1079, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
index = var->index;
|
index = var->index;
|
||||||
#line 1081
|
CError_ASSERT(1081, index != 0);
|
||||||
CError_ASSERT(index != 0);
|
|
||||||
|
|
||||||
Bv_SetBit(index, IRO_VarKills);
|
Bv_SetBit(index, IRO_VarKills);
|
||||||
}
|
}
|
||||||
|
@ -915,12 +907,10 @@ void IRO_RewriteBitFieldTemps(void) {
|
||||||
for (nd = IRO_FirstLinear; nd; nd = nd->next) {
|
for (nd = IRO_FirstLinear; nd; nd = nd->next) {
|
||||||
if ((obj = IRO_IsVariable(nd)) && (nd->flags & IROLF_BitfieldIndirect)) {
|
if ((obj = IRO_IsVariable(nd)) && (nd->flags & IROLF_BitfieldIndirect)) {
|
||||||
var = IRO_FindVar(obj, 0, 1);
|
var = IRO_FindVar(obj, 0, 1);
|
||||||
#line 1526
|
CError_ASSERT(1526, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
expr2 = var->x1E;
|
expr2 = var->x1E;
|
||||||
#line 1532
|
CError_ASSERT(1532, expr2 != NULL);
|
||||||
CError_ASSERT(expr2 != NULL);
|
|
||||||
|
|
||||||
IRO_InitList(&list);
|
IRO_InitList(&list);
|
||||||
IRO_DuplicateExpr(expr2, &list);
|
IRO_DuplicateExpr(expr2, &list);
|
||||||
|
@ -962,8 +952,7 @@ static Boolean FunctionCallMightUseOrKillAnyAddressedVar(IROLinear *funccall) {
|
||||||
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 1592
|
CError_ASSERT(1592, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
|
|
||||||
killList = NULL;
|
killList = NULL;
|
||||||
PointerAnalysis_GetFunctionKills(obj, funccall, &killList);
|
PointerAnalysis_GetFunctionKills(obj, funccall, &killList);
|
||||||
|
@ -972,8 +961,7 @@ static Boolean FunctionCallMightUseOrKillAnyAddressedVar(IROLinear *funccall) {
|
||||||
result = 1;
|
result = 1;
|
||||||
} else {
|
} else {
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 1604
|
CError_ASSERT(1604, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
if (var->xB)
|
if (var->xB)
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
@ -996,8 +984,7 @@ static Boolean FunctionCallMightUseOrKillAnyAddressedVar(IROLinear *funccall) {
|
||||||
result = 1;
|
result = 1;
|
||||||
} else {
|
} else {
|
||||||
var = IRO_FindVar(olist->object, 1, 1);
|
var = IRO_FindVar(olist->object, 1, 1);
|
||||||
#line 1632
|
CError_ASSERT(1632, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
if (var->xB)
|
if (var->xB)
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
@ -1074,11 +1061,9 @@ static Boolean IndirectMightUseOrKillAnyAddressedVar(IROLinear *indirect) {
|
||||||
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) {
|
||||||
foundObjRef = 1;
|
foundObjRef = 1;
|
||||||
obj = nd->u.node->data.objref;
|
obj = nd->u.node->data.objref;
|
||||||
#line 1723
|
CError_ASSERT(1723, obj != NULL);
|
||||||
CError_ASSERT(obj != NULL);
|
|
||||||
var = IRO_FindVar(obj, 1, 1);
|
var = IRO_FindVar(obj, 1, 1);
|
||||||
#line 1725
|
CError_ASSERT(1725, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
|
|
||||||
if (var->xB)
|
if (var->xB)
|
||||||
result = 1;
|
result = 1;
|
||||||
|
@ -1131,12 +1116,10 @@ void IRO_ScalarizeClassDataMembers(void) {
|
||||||
int i;
|
int i;
|
||||||
CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects);
|
CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects);
|
||||||
for (i = 0; i < effects.numoperands; i++) {
|
for (i = 0; i < effects.numoperands; i++) {
|
||||||
if ((var = IRO_FindVar(effects.operands[i].object, 0, 1))) {
|
if ((var = IRO_FindVar(effects.operands[i].object, 0, 1)))
|
||||||
CheckAddressConsistency(nd, var, -1, &stvoid);
|
CheckAddressConsistency(nd, var, -1, &stvoid);
|
||||||
} else {
|
else
|
||||||
#line 1823
|
CError_FATAL(1823);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nd->type == IROLinearFunccall && !flag)
|
if (nd->type == IROLinearFunccall && !flag)
|
||||||
|
@ -1254,8 +1237,7 @@ static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag) {
|
||||||
IS_TYPE_ARRAY(inner->u.node->data.objref->type)) {
|
IS_TYPE_ARRAY(inner->u.node->data.objref->type)) {
|
||||||
if (inner->u.node->data.objref->datatype == DLOCAL) {
|
if (inner->u.node->data.objref->datatype == DLOCAL) {
|
||||||
var = IRO_FindVar(inner->u.node->data.objref, 0, 1);
|
var = IRO_FindVar(inner->u.node->data.objref, 0, 1);
|
||||||
#line 2240
|
CError_ASSERT(2240, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
CheckAddressConsistency(nd, var, 0, nd->rtype);
|
CheckAddressConsistency(nd, var, 0, nd->rtype);
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
@ -1276,8 +1258,7 @@ static Boolean CheckAddress(IROLinear *nd, Boolean *resultFlag) {
|
||||||
) {
|
) {
|
||||||
if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) {
|
if (inner->u.diadic.left->u.node->data.objref->datatype == DLOCAL) {
|
||||||
var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1);
|
var = IRO_FindVar(inner->u.diadic.left->u.node->data.objref, 0, 1);
|
||||||
#line 2267
|
CError_ASSERT(2267, var != NULL);
|
||||||
CError_ASSERT(var != NULL);
|
|
||||||
CheckAddressConsistency(nd, var, inner->u.diadic.right->u.node->data.intval.lo, nd->rtype);
|
CheckAddressConsistency(nd, var, inner->u.diadic.right->u.node->data.intval.lo, nd->rtype);
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,13 +271,11 @@ void insertpreheaderblock(Loop *loop) {
|
||||||
if (link->block->pcodeCount) {
|
if (link->block->pcodeCount) {
|
||||||
pcode27 = link->block->lastPCode;
|
pcode27 = link->block->lastPCode;
|
||||||
if (pcode27->op == PC_B) {
|
if (pcode27->op == PC_B) {
|
||||||
#line 462
|
CError_ASSERT(462, pcode27->args[0].kind == PCOp_LABEL);
|
||||||
CError_ASSERT(pcode27->args[0].kind == PCOp_LABEL);
|
|
||||||
if (pcode27->args[0].data.label.label->block == block28)
|
if (pcode27->args[0].data.label.label->block == block28)
|
||||||
pcode27->args[0].data.label.label = preheader->labels;
|
pcode27->args[0].data.label.label = preheader->labels;
|
||||||
} else if (pcode27->op == PC_BT || pcode27->op == PC_BF) {
|
} else if (pcode27->op == PC_BT || pcode27->op == PC_BF) {
|
||||||
#line 474
|
CError_ASSERT(474, pcode27->args[2].kind == PCOp_LABEL);
|
||||||
CError_ASSERT(pcode27->args[2].kind == PCOp_LABEL);
|
|
||||||
if (pcode27->args[2].data.label.label->block == block28)
|
if (pcode27->args[2].data.label.label->block == block28)
|
||||||
pcode27->args[2].data.label.label = preheader->labels;
|
pcode27->args[2].data.label.label = preheader->labels;
|
||||||
} else if (pcode27->op == PC_BCTR) {
|
} else if (pcode27->op == PC_BCTR) {
|
||||||
|
@ -297,8 +295,7 @@ void insertpreheaderblock(Loop *loop) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 505
|
CError_ASSERT(505, link->block->nextBlock == block28);
|
||||||
CError_ASSERT(link->block->nextBlock == block28);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,8 +145,7 @@ static void skiplooptest(Loop *loop) {
|
||||||
|
|
||||||
preheader = loop->preheader;
|
preheader = loop->preheader;
|
||||||
lastInstr = loop->body->lastPCode;
|
lastInstr = loop->body->lastPCode;
|
||||||
#line 340
|
CError_ASSERT(340, lastInstr->args[2].kind == PCOp_LABEL);
|
||||||
CError_ASSERT(lastInstr->args[2].kind == PCOp_LABEL);
|
|
||||||
|
|
||||||
label = lastInstr->args[2].data.label.label;
|
label = lastInstr->args[2].data.label.label;
|
||||||
preheader->lastPCode->args[0].data.label.label = label;
|
preheader->lastPCode->args[0].data.label.label = label;
|
||||||
|
@ -166,8 +165,7 @@ static void skiplooptest(Loop *loop) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
instr = loop->body->firstPCode;
|
instr = loop->body->firstPCode;
|
||||||
#line 369
|
CError_ASSERT(369, instr);
|
||||||
CError_ASSERT(instr);
|
|
||||||
|
|
||||||
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
||||||
break;
|
break;
|
||||||
|
@ -204,12 +202,9 @@ static void unrollloop(Loop *loop) {
|
||||||
newBlock->firstPCode = newBlock->lastPCode = NULL;
|
newBlock->firstPCode = newBlock->lastPCode = NULL;
|
||||||
for (i = 0; i < factor - 1; i++) {
|
for (i = 0; i < factor - 1; i++) {
|
||||||
firstInstr = loop->body->firstPCode;
|
firstInstr = loop->body->firstPCode;
|
||||||
#line 448
|
CError_ASSERT(448, firstInstr);
|
||||||
CError_ASSERT(firstInstr);
|
if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI)
|
||||||
if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI) {
|
CError_FATAL(450);
|
||||||
#line 450
|
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (instr = firstInstr->nextPCode; instr && !(instr->flags & fPCodeFlag1); instr = instr->nextPCode)
|
for (instr = firstInstr->nextPCode; instr && !(instr->flags & fPCodeFlag1); instr = instr->nextPCode)
|
||||||
appendpcode(newBlock, copypcode(instr));
|
appendpcode(newBlock, copypcode(instr));
|
||||||
|
@ -236,8 +231,7 @@ void pccomputepredecessors1(PCodeBlock *block) {
|
||||||
|
|
||||||
for (succ = block->successors; succ; succ = succ->nextLink) {
|
for (succ = block->successors; succ; succ = succ->nextLink) {
|
||||||
if (!succ->block) {
|
if (!succ->block) {
|
||||||
#line 496
|
CError_FATAL(496);
|
||||||
CError_FATAL();
|
|
||||||
} else {
|
} else {
|
||||||
for (pred = succ->block->predecessors; pred; pred = pred->nextLink) {
|
for (pred = succ->block->predecessors; pred; pred = pred->nextLink) {
|
||||||
if (pred->block == block)
|
if (pred->block == block)
|
||||||
|
@ -427,12 +421,9 @@ static void unrollloopconditional(Loop *loop) {
|
||||||
}
|
}
|
||||||
|
|
||||||
firstInstr = loop->body->firstPCode;
|
firstInstr = loop->body->firstPCode;
|
||||||
#line 762
|
CError_ASSERT(762, firstInstr != NULL);
|
||||||
CError_ASSERT(firstInstr != NULL);
|
if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI)
|
||||||
if (firstInstr->op != PC_CMP && firstInstr->op != PC_CMPL && firstInstr->op != PC_CMPI && firstInstr->op != PC_CMPLI) {
|
CError_FATAL(764);
|
||||||
#line 764
|
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (instr = firstInstr->nextPCode; instr && !(instr->flags & fPCodeFlag1); instr = instr->nextPCode)
|
for (instr = firstInstr->nextPCode; instr && !(instr->flags & fPCodeFlag1); instr = instr->nextPCode)
|
||||||
appendpcode(blocks2[inputBlockCount - 1], copypcode(instr));
|
appendpcode(blocks2[inputBlockCount - 1], copypcode(instr));
|
||||||
|
@ -734,8 +725,7 @@ static void deleteloop(Loop *loop) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
instr = body->firstPCode;
|
instr = body->firstPCode;
|
||||||
#line 1294
|
CError_ASSERT(1294, instr != NULL);
|
||||||
CError_ASSERT(instr != NULL);
|
|
||||||
|
|
||||||
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
||||||
break;
|
break;
|
||||||
|
@ -978,8 +968,7 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
instr = loop->body->firstPCode;
|
instr = loop->body->firstPCode;
|
||||||
#line 1857
|
CError_ASSERT(1857, instr);
|
||||||
CError_ASSERT(instr);
|
|
||||||
|
|
||||||
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
if (instr->op == PC_CMP || instr->op == PC_CMPI || instr->op == PC_CMPLI || instr->op == PC_CMPL)
|
||||||
break;
|
break;
|
||||||
|
@ -1452,8 +1441,7 @@ void changearraytoregisters(void) {
|
||||||
floatCounter -= best->elementCount;
|
floatCounter -= best->elementCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 2394
|
CError_ASSERT(2394, intCounter <= 8 && floatCounter <= 8);
|
||||||
CError_ASSERT(intCounter <= 8 && floatCounter <= 8);
|
|
||||||
|
|
||||||
if (!arrays)
|
if (!arrays)
|
||||||
return;
|
return;
|
||||||
|
@ -1522,8 +1510,7 @@ void changearraytoregisters(void) {
|
||||||
newInstr = makepcode(PC_FMR, reg, reg2);
|
newInstr = makepcode(PC_FMR, reg, reg2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2494
|
CError_FATAL(2494);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,878 @@
|
||||||
|
#include "compiler/MachO.h"
|
||||||
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CParser.h"
|
||||||
|
#include "compiler/CPrep.h"
|
||||||
|
#include "compiler/CompilerTools.h"
|
||||||
|
#include "compiler/ObjGenMachO.h"
|
||||||
|
#include "cos.h"
|
||||||
|
|
||||||
|
static MachOSegment *FirstSeg;
|
||||||
|
static MachOSegment *LastSeg;
|
||||||
|
static UInt32 SectNum;
|
||||||
|
static UInt32 SymNum;
|
||||||
|
static UInt32 NumStabs;
|
||||||
|
static UInt32 ilocalsym;
|
||||||
|
static UInt32 nlocalsym;
|
||||||
|
static UInt32 iextdefsym;
|
||||||
|
static UInt32 nextdefsym;
|
||||||
|
static UInt32 iundefsym;
|
||||||
|
static UInt32 nundefsym;
|
||||||
|
static MachOSymbol *FirstSym;
|
||||||
|
static MachOSymbol *LastSym;
|
||||||
|
static MachOSymbol *FirstStab;
|
||||||
|
static MachOSymbol *LastStab;
|
||||||
|
static UInt32 FileOffset;
|
||||||
|
static UInt32 VmAddr;
|
||||||
|
static GList ObjFile;
|
||||||
|
static SInt32 SymPad;
|
||||||
|
static UInt32 CodeSize;
|
||||||
|
static UInt32 IdataSize;
|
||||||
|
static UInt32 UdataSize;
|
||||||
|
static GList IndirectSymbolTable;
|
||||||
|
static GList StringTable;
|
||||||
|
static UInt32 IndirectSymbolTableOffset;
|
||||||
|
|
||||||
|
void MachO_Setup(void) {
|
||||||
|
FirstSeg = LastSeg = NULL;
|
||||||
|
FirstSym = LastSym = NULL;
|
||||||
|
FirstStab = LastStab = NULL;
|
||||||
|
|
||||||
|
SectNum = 0;
|
||||||
|
SymNum = 0;
|
||||||
|
NumStabs = 0;
|
||||||
|
|
||||||
|
ilocalsym = -1;
|
||||||
|
nlocalsym = 0;
|
||||||
|
|
||||||
|
iextdefsym = -1;
|
||||||
|
nextdefsym = 0;
|
||||||
|
|
||||||
|
iundefsym = -1;
|
||||||
|
nundefsym = 0;
|
||||||
|
|
||||||
|
InitGList(&IndirectSymbolTable, 256);
|
||||||
|
InitGList(&StringTable, 4096);
|
||||||
|
AppendGListByte(&StringTable, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 GetSectVMAddr(UInt32 id) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
if (section->num == id)
|
||||||
|
return section->section.addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 AllocateForLoadCommands(void) {
|
||||||
|
UInt32 ncmds = 0;
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
FileOffset += sizeof(struct segment_command);
|
||||||
|
segment->cmd.cmdsize += sizeof(struct segment_command);
|
||||||
|
ncmds++;
|
||||||
|
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
segment->cmd.cmdsize += sizeof(struct section);
|
||||||
|
FileOffset += sizeof(struct section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ncmds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 AlignModulus[] = {
|
||||||
|
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800
|
||||||
|
};
|
||||||
|
|
||||||
|
static void AllocateAddresses(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
UInt32 pad;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
segment->cmd.vmaddr = VmAddr;
|
||||||
|
segment->cmd.fileoff = FileOffset;
|
||||||
|
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
if (section->glist.size)
|
||||||
|
section->section.size = section->glist.size;
|
||||||
|
|
||||||
|
pad = AlignModulus[section->section.align] - (VmAddr % AlignModulus[section->section.align]);
|
||||||
|
pad %= AlignModulus[section->section.align];
|
||||||
|
|
||||||
|
VmAddr += pad;
|
||||||
|
section->section.addr = VmAddr;
|
||||||
|
VmAddr += section->section.size;
|
||||||
|
|
||||||
|
FileOffset += pad;
|
||||||
|
if (section->glist.size) {
|
||||||
|
section->section.offset = FileOffset;
|
||||||
|
FileOffset += section->glist.size;
|
||||||
|
} else {
|
||||||
|
section->section.offset = FileOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(section->section.segname, "__TEXT", 6)) {
|
||||||
|
CodeSize += section->section.size;
|
||||||
|
} else {
|
||||||
|
if (section->glist.size)
|
||||||
|
IdataSize += section->section.size;
|
||||||
|
else
|
||||||
|
UdataSize += section->section.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
segment->cmd.filesize = FileOffset - segment->cmd.fileoff;
|
||||||
|
segment->cmd.vmsize = VmAddr - segment->cmd.vmaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyRelocs(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
MachOReloc *reloc;
|
||||||
|
enum reloc_type_ppc pairType;
|
||||||
|
UInt32 pairValue;
|
||||||
|
UInt32 opMask;
|
||||||
|
UInt32 argMask;
|
||||||
|
UInt32 value;
|
||||||
|
UInt32 *ptr;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
for (reloc = section->firstReloc; reloc; reloc = reloc->next) {
|
||||||
|
if (reloc->is_extern) {
|
||||||
|
opMask = 0xFFFFFFFF;
|
||||||
|
argMask = 0;
|
||||||
|
value = 0;
|
||||||
|
switch (reloc->reltype) {
|
||||||
|
case PPC_RELOC_HI16:
|
||||||
|
case PPC_RELOC_LO16:
|
||||||
|
case PPC_RELOC_HA16:
|
||||||
|
pairValue = 0;
|
||||||
|
pairType = reloc->reltype;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (reloc->reltype == PPC_RELOC_PAIR) {
|
||||||
|
if (reloc->value != 0xFFFFFF) {
|
||||||
|
value = pairValue - (reloc->value + section->section.addr);
|
||||||
|
value += reloc->address;
|
||||||
|
} else {
|
||||||
|
value = pairValue + reloc->address;
|
||||||
|
}
|
||||||
|
switch (pairType) {
|
||||||
|
case PPC_RELOC_HI16:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
value >>= 16;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_HA16:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
if (value & 0x8000)
|
||||||
|
value += 0x10000;
|
||||||
|
value >>= 16;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_LO16:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
value = value & 0xFFFF;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_HI16_SECTDIFF:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
value >>= 16;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_HA16_SECTDIFF:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
if (value & 0x8000)
|
||||||
|
value += 0x10000;
|
||||||
|
value >>= 16;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_LO16_SECTDIFF:
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
value = value & 0xFFFF;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_SECTDIFF:
|
||||||
|
opMask = 0;
|
||||||
|
argMask = 0xFFFFFFFF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CError_FATAL(388);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = GetSectVMAddr(reloc->value);
|
||||||
|
switch (reloc->reltype) {
|
||||||
|
case PPC_RELOC_VANILLA:
|
||||||
|
opMask = 0;
|
||||||
|
argMask = 0xFFFFFFFF;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_BR14:
|
||||||
|
opMask = 0xFFFF0003;
|
||||||
|
argMask = 0xFFFC;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_BR24:
|
||||||
|
opMask = 0xFC000003;
|
||||||
|
argMask = 0x3FFFFFC;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_LO14:
|
||||||
|
opMask = 0xFFFF0003;
|
||||||
|
argMask = 0xFFFC;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_HI16:
|
||||||
|
case PPC_RELOC_HA16:
|
||||||
|
case PPC_RELOC_LO16:
|
||||||
|
case PPC_RELOC_HI16_SECTDIFF:
|
||||||
|
case PPC_RELOC_HA16_SECTDIFF:
|
||||||
|
case PPC_RELOC_LO16_SECTDIFF:
|
||||||
|
case PPC_RELOC_SECTDIFF:
|
||||||
|
// first half of a pair
|
||||||
|
opMask = 0xFFFF0000;
|
||||||
|
argMask = 0xFFFF;
|
||||||
|
pairValue = value;
|
||||||
|
pairType = reloc->reltype;
|
||||||
|
value = 0;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_PB_LA_PTR:
|
||||||
|
CError_FATAL(428);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CError_FATAL(432);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reloc->reltype != PPC_RELOC_PAIR)
|
||||||
|
ptr = (UInt32 *) ((*section->glist.data) + reloc->address);
|
||||||
|
|
||||||
|
if (reloc->is_pcrel) {
|
||||||
|
if (!reloc->is_extern)
|
||||||
|
*ptr = (*ptr & opMask) | (argMask & (value - (reloc->address + section->section.addr) + (*ptr & argMask)));
|
||||||
|
} else {
|
||||||
|
if (reloc->reltype == PPC_RELOC_PAIR)
|
||||||
|
*ptr = (*ptr & opMask) | (value & argMask);
|
||||||
|
else
|
||||||
|
*ptr = (*ptr & opMask) | (argMask & (value + (*ptr & argMask)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AllocForRelocs(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
if (section->section.nreloc) {
|
||||||
|
section->section.reloff = FileOffset;
|
||||||
|
FileOffset += section->section.nreloc * 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteSegLoadCommands(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
AppendGListData(&ObjFile, &segment->cmd, sizeof(segment->cmd));
|
||||||
|
for (section = segment->firstSection; section; section = section->next)
|
||||||
|
AppendGListData(&ObjFile, §ion->section, sizeof(section->section));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteSymtabLoadCommand(void) {
|
||||||
|
struct symtab_command cmd;
|
||||||
|
UInt32 total;
|
||||||
|
|
||||||
|
cmd.cmd = LC_SYMTAB;
|
||||||
|
cmd.cmdsize = sizeof(cmd);
|
||||||
|
cmd.symoff = FileOffset;
|
||||||
|
total = SymNum + NumStabs;
|
||||||
|
cmd.nsyms = total;
|
||||||
|
FileOffset += total * sizeof(struct nlist);
|
||||||
|
cmd.stroff = FileOffset;
|
||||||
|
cmd.strsize = StringTable.size;
|
||||||
|
|
||||||
|
AppendGListData(&ObjFile, &cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteDynamicSymtabLoadCommand(void) {
|
||||||
|
struct dysymtab_command cmd;
|
||||||
|
|
||||||
|
if (!nlocalsym)
|
||||||
|
ilocalsym = 0;
|
||||||
|
if (!nextdefsym)
|
||||||
|
iextdefsym = ilocalsym + nlocalsym;
|
||||||
|
if (!nundefsym)
|
||||||
|
iundefsym = iextdefsym + nextdefsym;
|
||||||
|
|
||||||
|
ilocalsym += NumStabs;
|
||||||
|
iextdefsym += NumStabs;
|
||||||
|
iundefsym += NumStabs;
|
||||||
|
|
||||||
|
CError_ASSERT(644, (ilocalsym + nlocalsym) <= (SymNum + NumStabs));
|
||||||
|
|
||||||
|
CError_ASSERT(648, (iextdefsym + nextdefsym) <= (SymNum + NumStabs));
|
||||||
|
|
||||||
|
CError_ASSERT(652, (iundefsym + nundefsym) <= (SymNum + NumStabs));
|
||||||
|
|
||||||
|
cmd.cmd = LC_DYSYMTAB;
|
||||||
|
cmd.cmdsize = sizeof(cmd);
|
||||||
|
|
||||||
|
cmd.ilocalsym = ilocalsym;
|
||||||
|
cmd.nlocalsym = nlocalsym;
|
||||||
|
cmd.iextdefsym = iextdefsym;
|
||||||
|
cmd.nextdefsym = nextdefsym;
|
||||||
|
cmd.iundefsym = iundefsym;
|
||||||
|
cmd.nundefsym = nundefsym;
|
||||||
|
|
||||||
|
cmd.tocoff = 0;
|
||||||
|
cmd.ntoc = 0;
|
||||||
|
cmd.modtaboff = 0;
|
||||||
|
cmd.nmodtab = 0;
|
||||||
|
cmd.extrefsymoff = 0;
|
||||||
|
cmd.nextrefsyms = 0;
|
||||||
|
cmd.indirectsymoff = IndirectSymbolTableOffset;
|
||||||
|
cmd.nindirectsyms = IndirectSymbolTable.size / 4;
|
||||||
|
cmd.extreloff = 0;
|
||||||
|
cmd.nextrel = 0;
|
||||||
|
cmd.locreloff = 0;
|
||||||
|
cmd.nlocrel = 0;
|
||||||
|
|
||||||
|
AppendGListData(&ObjFile, &cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteSectionData(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
UInt32 pad;
|
||||||
|
|
||||||
|
VmAddr = 0;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
pad = AlignModulus[section->section.align] - (VmAddr % AlignModulus[section->section.align]);
|
||||||
|
pad %= AlignModulus[section->section.align];
|
||||||
|
|
||||||
|
while (pad) {
|
||||||
|
AppendGListByte(&ObjFile, 0);
|
||||||
|
VmAddr++;
|
||||||
|
FileOffset++;
|
||||||
|
pad--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section->glist.size) {
|
||||||
|
CError_ASSERT(711, ObjFile.size == section->section.offset);
|
||||||
|
|
||||||
|
COS_LockHandle(section->glist.data);
|
||||||
|
AppendGListData(&ObjFile, *section->glist.data, section->glist.size);
|
||||||
|
COS_UnlockHandle(section->glist.data);
|
||||||
|
|
||||||
|
VmAddr += section->glist.size;
|
||||||
|
FreeGList(§ion->glist);
|
||||||
|
} else {
|
||||||
|
VmAddr += pad + section->section.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteRelocs(void) {
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *section;
|
||||||
|
MachOReloc *reloc;
|
||||||
|
enum reloc_type_ppc pairType;
|
||||||
|
UInt32 pairValue;
|
||||||
|
SInt32 scatterFlag;
|
||||||
|
UInt32 combo;
|
||||||
|
|
||||||
|
static char length_code[] = {
|
||||||
|
0, 0, 1, 1, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
pairType = 0;
|
||||||
|
pairValue = 0;
|
||||||
|
scatterFlag = 0;
|
||||||
|
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
for (section = segment->firstSection; section; section = section->next) {
|
||||||
|
for (reloc = section->firstReloc; reloc; reloc = reloc->next) {
|
||||||
|
if (reloc->is_extern)
|
||||||
|
reloc->value += NumStabs;
|
||||||
|
|
||||||
|
switch (reloc->reltype) {
|
||||||
|
case PPC_RELOC_LO16:
|
||||||
|
case PPC_RELOC_HA16:
|
||||||
|
case PPC_RELOC_LO14:
|
||||||
|
pairType = reloc->reltype;
|
||||||
|
if (reloc->is_extern) {
|
||||||
|
pairValue = 0;
|
||||||
|
} else {
|
||||||
|
pairValue = reloc->next->address + GetSectVMAddr(reloc->value);
|
||||||
|
}
|
||||||
|
case PPC_RELOC_VANILLA:
|
||||||
|
case PPC_RELOC_BR14:
|
||||||
|
case PPC_RELOC_BR24:
|
||||||
|
case PPC_RELOC_HI16:
|
||||||
|
case PPC_RELOC_PB_LA_PTR:
|
||||||
|
AppendGListLong(&ObjFile, reloc->address);
|
||||||
|
AppendGListLong(&ObjFile,
|
||||||
|
(reloc->value << 8) |
|
||||||
|
(reloc->is_pcrel << 7) |
|
||||||
|
(length_code[reloc->length] << 5) |
|
||||||
|
(reloc->is_extern << 4) |
|
||||||
|
reloc->reltype
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_PAIR:
|
||||||
|
switch (pairType) {
|
||||||
|
case PPC_RELOC_HI16:
|
||||||
|
case PPC_RELOC_HA16:
|
||||||
|
scatterFlag = 0;
|
||||||
|
reloc->address = pairValue & 0xFFFF;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_LO16:
|
||||||
|
scatterFlag = 0;
|
||||||
|
reloc->address = pairValue >> 16;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_HI16_SECTDIFF:
|
||||||
|
case PPC_RELOC_HA16_SECTDIFF:
|
||||||
|
scatterFlag = R_SCATTERED;
|
||||||
|
reloc->value += section->section.addr;
|
||||||
|
pairValue -= reloc->value;
|
||||||
|
reloc->address = pairValue & 0xFFFF;
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_LO16_SECTDIFF:
|
||||||
|
scatterFlag = R_SCATTERED;
|
||||||
|
reloc->value += section->section.addr;
|
||||||
|
pairValue -= reloc->value;
|
||||||
|
reloc->address = pairValue >> 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CError_FATAL(891);
|
||||||
|
reloc->address = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pairValue = 0;
|
||||||
|
pairType = 0;
|
||||||
|
if (scatterFlag) {
|
||||||
|
AppendGListLong(&ObjFile,
|
||||||
|
scatterFlag |
|
||||||
|
(reloc->is_pcrel << 30) |
|
||||||
|
(length_code[reloc->length] << 28) |
|
||||||
|
(reloc->reltype << 24) |
|
||||||
|
reloc->address
|
||||||
|
);
|
||||||
|
AppendGListLong(&ObjFile, reloc->value);
|
||||||
|
} else {
|
||||||
|
combo =
|
||||||
|
(reloc->value << 8) |
|
||||||
|
(reloc->is_pcrel << 7) |
|
||||||
|
(length_code[reloc->length] << 5) |
|
||||||
|
reloc->reltype;
|
||||||
|
AppendGListLong(&ObjFile, reloc->address);
|
||||||
|
AppendGListLong(&ObjFile, combo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PPC_RELOC_SECTDIFF:
|
||||||
|
case PPC_RELOC_HI16_SECTDIFF:
|
||||||
|
case PPC_RELOC_LO16_SECTDIFF:
|
||||||
|
case PPC_RELOC_HA16_SECTDIFF:
|
||||||
|
// build scattered relocation
|
||||||
|
reloc->value = reloc->next->address + GetSectVMAddr(reloc->value);
|
||||||
|
pairType = reloc->reltype;
|
||||||
|
pairValue = reloc->value;
|
||||||
|
AppendGListLong(&ObjFile,
|
||||||
|
R_SCATTERED |
|
||||||
|
(reloc->is_pcrel << 30) |
|
||||||
|
(length_code[reloc->length] << 28) |
|
||||||
|
(reloc->reltype << 24) |
|
||||||
|
reloc->address
|
||||||
|
);
|
||||||
|
AppendGListLong(&ObjFile, reloc->value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CError_FATAL(930);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteIndirectSymbolTable(void) {
|
||||||
|
UInt32 i;
|
||||||
|
UInt32 *ptr;
|
||||||
|
|
||||||
|
while (SymPad) {
|
||||||
|
AppendGListByte(&ObjFile, 0);
|
||||||
|
SymPad--;
|
||||||
|
}
|
||||||
|
|
||||||
|
COS_LockHandle(IndirectSymbolTable.data);
|
||||||
|
ptr = (UInt32 *) *IndirectSymbolTable.data;
|
||||||
|
for (i = 0; i < MachO_NumIndirectSym(); ptr++, i++)
|
||||||
|
*ptr += NumStabs;
|
||||||
|
|
||||||
|
AppendGListData(&ObjFile, *IndirectSymbolTable.data, IndirectSymbolTable.size);
|
||||||
|
COS_UnlockHandle(IndirectSymbolTable.data);
|
||||||
|
FreeGList(&IndirectSymbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteSymbolTable(void) {
|
||||||
|
MachOSymbol *symbol;
|
||||||
|
struct nlist nlist;
|
||||||
|
|
||||||
|
if (FirstStab) {
|
||||||
|
LastStab->next = FirstSym;
|
||||||
|
FirstSym = FirstStab;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (symbol = FirstSym; symbol; symbol = symbol->next) {
|
||||||
|
nlist.n_strx = symbol->data.u.strx;
|
||||||
|
nlist.n_type = symbol->data.type;
|
||||||
|
if (symbol->data.section)
|
||||||
|
nlist.n_sect = symbol->data.section->num;
|
||||||
|
else
|
||||||
|
nlist.n_sect = 0;
|
||||||
|
nlist.n_desc = symbol->data.desc;
|
||||||
|
|
||||||
|
if (
|
||||||
|
symbol->data.type == N_STSYM ||
|
||||||
|
symbol->data.type == N_FUN ||
|
||||||
|
symbol->data.type == N_LCSYM ||
|
||||||
|
symbol->data.type == N_SLINE ||
|
||||||
|
symbol->data.type == N_SO ||
|
||||||
|
symbol->data.type == N_SOL ||
|
||||||
|
symbol->data.type == N_ENTRY ||
|
||||||
|
symbol->data.type == N_ECOML ||
|
||||||
|
(symbol->data.type & N_TYPE) == N_SECT
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (symbol->data.section)
|
||||||
|
symbol->data.value += symbol->data.section->section.addr;
|
||||||
|
else
|
||||||
|
CError_FATAL(1010);
|
||||||
|
}
|
||||||
|
|
||||||
|
nlist.n_value = symbol->data.value;
|
||||||
|
AppendGListData(&ObjFile, &nlist, sizeof(nlist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteStringTable(void) {
|
||||||
|
COS_LockHandle(StringTable.data);
|
||||||
|
AppendGListData(&ObjFile, *StringTable.data, StringTable.size);
|
||||||
|
COS_UnlockHandle(StringTable.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_Finish(void) {
|
||||||
|
struct mach_header hdr;
|
||||||
|
|
||||||
|
CodeSize = 0;
|
||||||
|
IdataSize = UdataSize = 0;
|
||||||
|
VmAddr = 0;
|
||||||
|
FileOffset = sizeof(hdr);
|
||||||
|
|
||||||
|
hdr.ncmds = AllocateForLoadCommands();
|
||||||
|
|
||||||
|
FileOffset += 24; // what am I?
|
||||||
|
hdr.ncmds++;
|
||||||
|
|
||||||
|
if (copts.codegen_dynamic) {
|
||||||
|
FileOffset += 80; // what am I?
|
||||||
|
hdr.ncmds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr.sizeofcmds = FileOffset - sizeof(hdr);
|
||||||
|
|
||||||
|
AllocateAddresses();
|
||||||
|
ApplyRelocs();
|
||||||
|
AllocForRelocs();
|
||||||
|
|
||||||
|
SymPad = (4 - (FileOffset & 3)) & 3;
|
||||||
|
FileOffset += SymPad;
|
||||||
|
IndirectSymbolTableOffset = 0;
|
||||||
|
|
||||||
|
if (IndirectSymbolTable.size > 0) {
|
||||||
|
IndirectSymbolTableOffset = FileOffset;
|
||||||
|
FileOffset += IndirectSymbolTable.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitGList(&ObjFile, 4096);
|
||||||
|
|
||||||
|
hdr.magic = MH_MAGIC;
|
||||||
|
hdr.cputype = CPU_TYPE_POWERPC;
|
||||||
|
hdr.cpusubtype = CPU_SUBTYPE_MC98000_ALL;
|
||||||
|
hdr.filetype = MH_OBJECT;
|
||||||
|
hdr.flags = 0;
|
||||||
|
AppendGListData(&ObjFile, &hdr, sizeof(hdr));
|
||||||
|
|
||||||
|
WriteSegLoadCommands();
|
||||||
|
WriteSymtabLoadCommand();
|
||||||
|
if (copts.codegen_dynamic)
|
||||||
|
WriteDynamicSymtabLoadCommand();
|
||||||
|
WriteSectionData();
|
||||||
|
WriteRelocs();
|
||||||
|
WriteIndirectSymbolTable();
|
||||||
|
WriteSymbolTable();
|
||||||
|
WriteStringTable();
|
||||||
|
|
||||||
|
COS_ResizeHandle(ObjFile.data, ObjFile.size);
|
||||||
|
|
||||||
|
cparamblkptr->objectDataHandle = ObjFile.data;
|
||||||
|
cparamblkptr->objectdata.codesize = CodeSize;
|
||||||
|
cparamblkptr->objectdata.udatasize = UdataSize;
|
||||||
|
cparamblkptr->objectdata.idatasize = IdataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_Cleanup(void) {
|
||||||
|
if (StringTable.data)
|
||||||
|
FreeGList(&StringTable);
|
||||||
|
if (IndirectSymbolTable.data)
|
||||||
|
FreeGList(&IndirectSymbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
MachOSegment *MachO_CreateSegment(char *segname, int maxprot, int initprot, UInt32 flags) {
|
||||||
|
MachOSegment *segment = galloc(sizeof(MachOSegment));
|
||||||
|
|
||||||
|
memset(&segment->cmd, 0, sizeof(segment->cmd));
|
||||||
|
segment->cmd.cmd = LC_SEGMENT;
|
||||||
|
strncpy(segment->cmd.segname, segname, sizeof(segment->cmd.segname));
|
||||||
|
segment->cmd.maxprot = maxprot;
|
||||||
|
segment->cmd.initprot = initprot;
|
||||||
|
segment->cmd.flags = flags;
|
||||||
|
|
||||||
|
segment->firstSection = segment->lastSection = NULL;
|
||||||
|
segment->next = NULL;
|
||||||
|
if (FirstSeg == NULL)
|
||||||
|
FirstSeg = segment;
|
||||||
|
else
|
||||||
|
LastSeg->next = segment;
|
||||||
|
LastSeg = segment;
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachOSection *MachO_CreateSection(MachOSegment *segment, char *segname, char *sectname, UInt32 align, UInt32 flags, UInt32 sectionID) {
|
||||||
|
MachOSection *section;
|
||||||
|
UInt32 alignConv;
|
||||||
|
|
||||||
|
alignConv = 0;
|
||||||
|
while (!(align & 1)) {
|
||||||
|
align >>= 1;
|
||||||
|
alignConv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
section = galloc(sizeof(MachOSection));
|
||||||
|
memset(section, 0, sizeof(MachOSection));
|
||||||
|
|
||||||
|
strncpy(section->section.segname, segname, sizeof(section->section.segname));
|
||||||
|
strncpy(section->section.sectname, sectname, sizeof(section->section.sectname));
|
||||||
|
section->section.align = alignConv;
|
||||||
|
section->section.flags = flags;
|
||||||
|
|
||||||
|
section->num = ++SectNum;
|
||||||
|
section->id = sectionID;
|
||||||
|
|
||||||
|
section->next = NULL;
|
||||||
|
if (segment->firstSection == NULL)
|
||||||
|
segment->firstSection = section;
|
||||||
|
else
|
||||||
|
segment->lastSection->next = section;
|
||||||
|
segment->lastSection = section;
|
||||||
|
|
||||||
|
segment->cmd.nsects++;
|
||||||
|
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *MachO_GetGList(MachOSection *section) {
|
||||||
|
if (!section->glist.data)
|
||||||
|
InitGList(§ion->glist, 256);
|
||||||
|
return §ion->glist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_SetSectionSize(void) {
|
||||||
|
// empty, unused, unknown args
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_Relocate(MachOSection *section, UInt32 address, UInt32 value, char length, char is_pcrel, Boolean is_extern, int reltype) {
|
||||||
|
MachOReloc *reloc;
|
||||||
|
|
||||||
|
reloc = galloc(sizeof(MachOReloc));
|
||||||
|
reloc->address = address;
|
||||||
|
reloc->value = value;
|
||||||
|
reloc->length = length;
|
||||||
|
reloc->is_pcrel = is_pcrel;
|
||||||
|
reloc->is_extern = is_extern;
|
||||||
|
reloc->reltype = reltype;
|
||||||
|
|
||||||
|
reloc->next = NULL;
|
||||||
|
if (section->firstReloc == NULL)
|
||||||
|
section->firstReloc = reloc;
|
||||||
|
else
|
||||||
|
section->lastReloc->next = reloc;
|
||||||
|
section->lastReloc = reloc;
|
||||||
|
|
||||||
|
section->section.nreloc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SInt32 DeclareString(char *str) {
|
||||||
|
SInt32 offset;
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
offset = StringTable.size;
|
||||||
|
AppendGListID(&StringTable, str);
|
||||||
|
} else {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 MachO_DeclareSymbol(char *name, MachOSection *section, UInt32 value, Boolean isAbsolute, short type, short desc) {
|
||||||
|
MachOSymbol *symbol;
|
||||||
|
|
||||||
|
symbol = galloc(sizeof(MachOSymbol));
|
||||||
|
memset(symbol, 0, sizeof(MachOSymbol));
|
||||||
|
|
||||||
|
if (section) {
|
||||||
|
if (type) {
|
||||||
|
if (nextdefsym == 0)
|
||||||
|
iextdefsym = SymNum;
|
||||||
|
nextdefsym++;
|
||||||
|
} else {
|
||||||
|
if (nlocalsym == 0)
|
||||||
|
ilocalsym = SymNum;
|
||||||
|
nlocalsym++;
|
||||||
|
}
|
||||||
|
symbol->data.type = type | N_SECT;
|
||||||
|
symbol->data.section = section;
|
||||||
|
} else if (isAbsolute) {
|
||||||
|
symbol->data.type = type | N_ABS;
|
||||||
|
} else {
|
||||||
|
if (nundefsym == 0)
|
||||||
|
iundefsym = SymNum;
|
||||||
|
nundefsym++;
|
||||||
|
symbol->data.type = type & ~N_PEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol->data.value = value;
|
||||||
|
symbol->data.u.strx = DeclareString(name);
|
||||||
|
symbol->data.desc = desc;
|
||||||
|
symbol->index = SymNum++;
|
||||||
|
|
||||||
|
if (FirstSym == NULL)
|
||||||
|
FirstSym = symbol;
|
||||||
|
else
|
||||||
|
LastSym->next = symbol;
|
||||||
|
LastSym = symbol;
|
||||||
|
|
||||||
|
return symbol->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_ReOrderSections(void) {
|
||||||
|
MachOSection *section;
|
||||||
|
MachOSegment *segment;
|
||||||
|
MachOSection *prev;
|
||||||
|
MachOSection *firstRemoved;
|
||||||
|
MachOSection *lastRemoved;
|
||||||
|
UInt32 counter;
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
for (segment = FirstSeg; segment; segment = segment->next) {
|
||||||
|
prev = NULL;
|
||||||
|
section = segment->firstSection;
|
||||||
|
firstRemoved = lastRemoved = NULL;
|
||||||
|
while (section) {
|
||||||
|
if (section->section.size && section->glist.data == NULL && section != segment->firstSection) {
|
||||||
|
// detach this section
|
||||||
|
if (prev)
|
||||||
|
prev->next = section->next;
|
||||||
|
else
|
||||||
|
segment->firstSection = section->next;
|
||||||
|
|
||||||
|
if (section == segment->lastSection)
|
||||||
|
segment->lastSection = prev;
|
||||||
|
|
||||||
|
section->next = NULL;
|
||||||
|
|
||||||
|
// add it to the list to be pushed to the end
|
||||||
|
if (firstRemoved == NULL)
|
||||||
|
firstRemoved = section;
|
||||||
|
else
|
||||||
|
lastRemoved->next = section;
|
||||||
|
lastRemoved = section;
|
||||||
|
|
||||||
|
// continue iterating
|
||||||
|
if (prev)
|
||||||
|
section = prev->next;
|
||||||
|
else
|
||||||
|
section = segment->firstSection;
|
||||||
|
} else {
|
||||||
|
prev = section;
|
||||||
|
section = section->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attach the other sections
|
||||||
|
if (firstRemoved) {
|
||||||
|
if (segment->firstSection == NULL)
|
||||||
|
segment->firstSection = firstRemoved;
|
||||||
|
else
|
||||||
|
segment->lastSection->next = firstRemoved;
|
||||||
|
segment->lastSection = lastRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
// renumber them all
|
||||||
|
for (section = segment->firstSection; section; section = section->next)
|
||||||
|
section->num = ++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachO_AddIndirectSymbol(SInt32 symbol) {
|
||||||
|
CError_ASSERT(1577, symbol >= 0);
|
||||||
|
|
||||||
|
AppendGListLong(&IndirectSymbolTable, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 MachO_NumIndirectSym(void) {
|
||||||
|
return IndirectSymbolTable.size / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
SInt32 MachO_OutputStab(SymbolData *data, SInt32 strIndex) {
|
||||||
|
MachOSymbol *symbol;
|
||||||
|
|
||||||
|
symbol = galloc(sizeof(MachOSymbol));
|
||||||
|
memset(symbol, 0, sizeof(MachOSymbol));
|
||||||
|
if (strIndex == -1)
|
||||||
|
data->u.strx = DeclareString(data->u.name);
|
||||||
|
else
|
||||||
|
data->u.strx = strIndex;
|
||||||
|
|
||||||
|
memcpy(&symbol->data, data, sizeof(SymbolData));
|
||||||
|
|
||||||
|
if (FirstStab == NULL)
|
||||||
|
FirstStab = symbol;
|
||||||
|
else
|
||||||
|
LastStab->next = symbol;
|
||||||
|
LastStab = symbol;
|
||||||
|
NumStabs++;
|
||||||
|
|
||||||
|
return data->u.strx;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,16 @@
|
||||||
#include "compiler/Operands.h"
|
#include "compiler/Operands.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CMachine.h"
|
||||||
|
#include "compiler/CParser.h"
|
||||||
#include "compiler/PCode.h"
|
#include "compiler/PCode.h"
|
||||||
#include "compiler/PCodeInfo.h"
|
#include "compiler/PCodeInfo.h"
|
||||||
#include "compiler/PCodeUtilities.h"
|
#include "compiler/PCodeUtilities.h"
|
||||||
|
#include "compiler/Registers.h"
|
||||||
|
#include "compiler/StackFrame.h"
|
||||||
#include "compiler/enode.h"
|
#include "compiler/enode.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler.h"
|
#include "compiler/CodeGen.h"
|
||||||
|
#include "compiler/RegisterInfo.h"
|
||||||
|
|
||||||
unsigned long long uns_to_float_cc = 0x4330000000000000;
|
unsigned long long uns_to_float_cc = 0x4330000000000000;
|
||||||
unsigned long long int_to_float_cc = 0x4330000080000000;
|
unsigned long long int_to_float_cc = 0x4330000080000000;
|
||||||
|
@ -27,8 +32,7 @@ void load_immediate(short reg, SInt32 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_op_flags(Operand *op, ENode *expr) {
|
static void set_op_flags(Operand *op, ENode *expr) {
|
||||||
#line 118
|
CError_ASSERT(118, op);
|
||||||
CError_ASSERT(op);
|
|
||||||
|
|
||||||
if (expr) {
|
if (expr) {
|
||||||
if (expr->type == EINTCONST) {
|
if (expr->type == EINTCONST) {
|
||||||
|
@ -55,8 +59,7 @@ void symbol_operand(Operand *op, Object *obj) {
|
||||||
void indirect(Operand *op, ENode *expr) {
|
void indirect(Operand *op, ENode *expr) {
|
||||||
switch (op->optype) {
|
switch (op->optype) {
|
||||||
case OpndType_GPRPair:
|
case OpndType_GPRPair:
|
||||||
#line 163
|
CError_FATAL(163);
|
||||||
CError_FATAL();
|
|
||||||
case OpndType_CRField:
|
case OpndType_CRField:
|
||||||
case OpndType_IndirectGPR_ImmOffset:
|
case OpndType_IndirectGPR_ImmOffset:
|
||||||
case OpndType_IndirectGPR_Indexed:
|
case OpndType_IndirectGPR_Indexed:
|
||||||
|
@ -91,8 +94,7 @@ void indirect(Operand *op, ENode *expr) {
|
||||||
set_op_flags(op, expr);
|
set_op_flags(op, expr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 215
|
CError_FATAL(215);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +270,7 @@ void combine(Operand *opA, Operand *opB, short output_reg, Operand *opOut) {
|
||||||
opOut->immediate = opA->immediate + opB->immediate;
|
opOut->immediate = opA->immediate + opB->immediate;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 415
|
CError_FATAL(415);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,17 +334,16 @@ void coerce_to_addressable(Operand *op) {
|
||||||
if (op->optype == OpndType_GPR_ImmOffset) {
|
if (op->optype == OpndType_GPR_ImmOffset) {
|
||||||
op->optype = OpndType_IndirectGPR_ImmOffset;
|
op->optype = OpndType_IndirectGPR_ImmOffset;
|
||||||
} else {
|
} else {
|
||||||
#line 563
|
CError_FATAL(563);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 581
|
CError_FATAL(581);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Coerce_to_register(Operand *op, Type *type, short output_reg) {
|
||||||
SInt32 offset;
|
SInt32 offset;
|
||||||
short opcode;
|
short opcode;
|
||||||
short reg;
|
short reg;
|
||||||
|
@ -402,8 +402,7 @@ void coerce_to_addressable(Operand *op) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 680
|
CError_ASSERT(680, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
||||||
CError_ASSERT(IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
|
||||||
}
|
}
|
||||||
load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
|
load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
|
@ -424,8 +423,7 @@ void coerce_to_addressable(Operand *op) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 724
|
CError_ASSERT(724, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
||||||
CError_ASSERT(IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
|
||||||
}
|
}
|
||||||
emitpcode(opcode, reg, op->reg, op->regOffset);
|
emitpcode(opcode, reg, op->reg, op->regOffset);
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
|
@ -452,8 +450,7 @@ void coerce_to_addressable(Operand *op) {
|
||||||
cond = 1;
|
cond = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 758
|
CError_FATAL(758);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
bit_offset = cond + (op->reg << 2);
|
bit_offset = cond + (op->reg << 2);
|
||||||
bit_size = 1;
|
bit_size = 1;
|
||||||
|
@ -462,8 +459,7 @@ void coerce_to_addressable(Operand *op) {
|
||||||
emitpcode(PC_XORI, tmp, tmp, 1);
|
emitpcode(PC_XORI, tmp, tmp, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 769
|
CError_FATAL(769);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->optype = OpndType_GPR;
|
op->optype = OpndType_GPR;
|
||||||
|
@ -479,8 +475,7 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
|
|
||||||
regHi = -1;
|
regHi = -1;
|
||||||
|
|
||||||
#line 794
|
CError_ASSERT(794, TYPE_IS_8BYTES(type) || (IS_TYPE_STRUCT(type) && type->size == 8));
|
||||||
CError_ASSERT(TYPE_IS_8BYTES(type) || (IS_TYPE_STRUCT(type) && type->size == 8));
|
|
||||||
|
|
||||||
coerce_to_addressable(op);
|
coerce_to_addressable(op);
|
||||||
switch (op->optype) {
|
switch (op->optype) {
|
||||||
|
@ -494,8 +489,7 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
tmp2 = output_regHi ? output_regHi : op->regHi;
|
tmp2 = output_regHi ? output_regHi : op->regHi;
|
||||||
if (tmp1 != op->reg) {
|
if (tmp1 != op->reg) {
|
||||||
if (tmp1 == op->regHi) {
|
if (tmp1 == op->regHi) {
|
||||||
#line 818
|
CError_ASSERT(818, tmp1 != tmp2);
|
||||||
CError_ASSERT(tmp1 != tmp2);
|
|
||||||
emitpcode(PC_MR, tmp2, op->regHi);
|
emitpcode(PC_MR, tmp2, op->regHi);
|
||||||
emitpcode(PC_MR, tmp1, op->reg);
|
emitpcode(PC_MR, tmp1, op->reg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -505,8 +499,7 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
}
|
}
|
||||||
} else if (tmp2 != op->regHi) {
|
} else if (tmp2 != op->regHi) {
|
||||||
if (tmp2 == op->reg) {
|
if (tmp2 == op->reg) {
|
||||||
#line 832
|
CError_ASSERT(832, tmp1 != tmp2);
|
||||||
CError_ASSERT(tmp1 != tmp2);
|
|
||||||
emitpcode(PC_MR, tmp1, op->reg);
|
emitpcode(PC_MR, tmp1, op->reg);
|
||||||
emitpcode(PC_MR, tmp2, op->regHi);
|
emitpcode(PC_MR, tmp2, op->regHi);
|
||||||
} else {
|
} else {
|
||||||
|
@ -520,16 +513,13 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
regHi = op->regHi;
|
regHi = op->regHi;
|
||||||
break;
|
break;
|
||||||
case OpndType_GPR:
|
case OpndType_GPR:
|
||||||
#line 849
|
CError_FATAL(849);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
case OpndType_GPR_ImmOffset:
|
case OpndType_GPR_ImmOffset:
|
||||||
#line 852
|
CError_FATAL(852);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
case OpndType_GPR_Indexed:
|
case OpndType_GPR_Indexed:
|
||||||
#line 855
|
CError_FATAL(855);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
case OpndType_Absolute:
|
case OpndType_Absolute:
|
||||||
reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
|
reg = output_reg ? output_reg : used_virtual_registers[RegClass_GPR]++;
|
||||||
|
@ -555,8 +545,7 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
|
regHi = output_regHi ? output_regHi : used_virtual_registers[RegClass_GPR]++;
|
||||||
if (op->reg == regHi) {
|
if (op->reg == regHi) {
|
||||||
if (op->reg == reg) {
|
if (op->reg == reg) {
|
||||||
#line 887
|
CError_FATAL(887);
|
||||||
CError_FATAL();
|
|
||||||
} else {
|
} else {
|
||||||
load_store_register(PC_LWZ, reg, op->reg, op->object, op->immOffset + low_offset);
|
load_store_register(PC_LWZ, reg, op->reg, op->object, op->immOffset + low_offset);
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
|
@ -580,13 +569,11 @@ void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short ou
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 912
|
CError_FATAL(912);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regHi == -1) {
|
if (regHi == -1) {
|
||||||
#line 916
|
CError_FATAL(916);
|
||||||
CError_FATAL();
|
|
||||||
} else {
|
} else {
|
||||||
op->optype = OpndType_GPRPair;
|
op->optype = OpndType_GPRPair;
|
||||||
op->reg = reg;
|
op->reg = reg;
|
||||||
|
@ -614,8 +601,7 @@ void Coerce_to_fp_register(Operand *op, TypeIntegral *tint, short output_reg) {
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 986
|
CError_FATAL(986);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->optype = OpndType_FPR;
|
op->optype = OpndType_FPR;
|
||||||
|
@ -662,16 +648,14 @@ void Coerce_to_v_register(Operand *op, TypeStruct *tstruct, short output_reg) {
|
||||||
emitpcode(PC_VSPLTISW, reg, op->immediate);
|
emitpcode(PC_VSPLTISW, reg, op->immediate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1049
|
CError_FATAL(1049);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
op->optype = OpndType_VR;
|
op->optype = OpndType_VR;
|
||||||
op->reg = reg;
|
op->reg = reg;
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1059
|
CError_FATAL(1059);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->optype = OpndType_VR;
|
op->optype = OpndType_VR;
|
||||||
|
@ -695,8 +679,7 @@ void store(short reg, Operand *op, Type *type) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 1171
|
CError_ASSERT(1171, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
||||||
CError_ASSERT(IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
|
||||||
}
|
}
|
||||||
load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
|
load_store_register(opcode, reg, op->reg, op->object, op->immOffset);
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
|
@ -713,23 +696,20 @@ void store(short reg, Operand *op, Type *type) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 1188
|
CError_ASSERT(1188, IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
||||||
CError_ASSERT(IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type));
|
|
||||||
}
|
}
|
||||||
emitpcode(opcode, reg, op->reg, op->regOffset);
|
emitpcode(opcode, reg, op->reg, op->regOffset);
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1193
|
CError_FATAL(1193);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void store_pair(short reg, short regHi, Operand *op, Type *type) {
|
void store_pair(short reg, short regHi, Operand *op, Type *type) {
|
||||||
short tmp;
|
short tmp;
|
||||||
|
|
||||||
#line 1208
|
CError_ASSERT(1208, TYPE_IS_8BYTES(type));
|
||||||
CError_ASSERT(TYPE_IS_8BYTES(type));
|
|
||||||
|
|
||||||
coerce_to_addressable(op);
|
coerce_to_addressable(op);
|
||||||
switch (op->optype) {
|
switch (op->optype) {
|
||||||
|
@ -748,8 +728,7 @@ void store_pair(short reg, short regHi, Operand *op, Type *type) {
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1228
|
CError_FATAL(1228);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,8 +744,7 @@ void store_fp(short reg, Operand *op, Type *tint) {
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1259
|
CError_FATAL(1259);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,8 +760,7 @@ void store_v(short reg, Operand *op, Type *tstruct) {
|
||||||
setpcodeflags(op->flags);
|
setpcodeflags(op->flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1283
|
CError_FATAL(1283);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,8 +825,7 @@ void extend32(Operand *op, Type *type, short output_reg) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 1389
|
CError_FATAL(1389);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op->optype = OpndType_GPR;
|
op->optype = OpndType_GPR;
|
||||||
|
@ -1037,7 +1013,6 @@ void load_address(short dest_reg, Operand *op) {
|
||||||
} else if (op->optype == OpndType_IndirectGPR_Indexed) {
|
} else if (op->optype == OpndType_IndirectGPR_Indexed) {
|
||||||
emitpcode(PC_ADD, dest_reg, op->reg, op->regOffset);
|
emitpcode(PC_ADD, dest_reg, op->reg, op->regOffset);
|
||||||
} else {
|
} else {
|
||||||
#line 1849
|
CError_FATAL(1849);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,18 @@
|
||||||
#include "compiler.h"
|
|
||||||
#include "compiler/objects.h"
|
|
||||||
#include "compiler/PCodeInfo.h"
|
#include "compiler/PCodeInfo.h"
|
||||||
#include "compiler/PCodeUtilities.h"
|
|
||||||
#include "compiler/CError.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
|
#pragma pool_strings on
|
||||||
|
|
||||||
|
@ -38,8 +48,7 @@ void pcode_get_hi_lo(int bits, char typechar, SInt32 *hi, SInt32 *lo) {
|
||||||
*lo = -(1 << (bits - 1));
|
*lo = -(1 << (bits - 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#line 65
|
CError_FATAL(65);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +92,7 @@ int pcode_check_imm_bits(SInt32 value, int bits, char typechar) {
|
||||||
if (forcedBits > 0 && value != ((value >> forcedBits) << forcedBits))
|
if (forcedBits > 0 && value != ((value >> forcedBits) << forcedBits))
|
||||||
return 1;
|
return 1;
|
||||||
} else if (bits > 32) {
|
} else if (bits > 32) {
|
||||||
#line 110
|
CError_FATAL(110);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,10 +162,8 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
lastArg = pcode->args + pcode->argCount;
|
lastArg = pcode->args + pcode->argCount;
|
||||||
arg = pcode->args;
|
arg = pcode->args;
|
||||||
while (*format) {
|
while (*format) {
|
||||||
if (arg >= lastArg) {
|
if (arg >= lastArg)
|
||||||
#line 189
|
CError_FATAL(189);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*format == ',' || *format == ';')
|
if (*format == ',' || *format == ';')
|
||||||
format++;
|
format++;
|
||||||
|
@ -274,12 +280,10 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->data.reg.effect = effect;
|
arg->data.reg.effect = effect;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1]))
|
||||||
format += pcode_const_from_format(format + 1, &thing);
|
format += pcode_const_from_format(format + 1, &thing);
|
||||||
} else {
|
else
|
||||||
#line 319
|
CError_FATAL(319);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
tmp = va_arg(argList, int);
|
tmp = va_arg(argList, int);
|
||||||
tmp2 = -1;
|
tmp2 = -1;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
@ -318,8 +322,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->data.reg.reg = 0x11D;
|
arg->data.reg.reg = 0x11D;
|
||||||
arg->data.reg.effect = effect;
|
arg->data.reg.effect = effect;
|
||||||
} else {
|
} else {
|
||||||
#line 353
|
CError_FATAL(353);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
pcsetsideeffects(pcode);
|
pcsetsideeffects(pcode);
|
||||||
arg->kind = PCOp_SYSREG;
|
arg->kind = PCOp_SYSREG;
|
||||||
|
@ -330,12 +333,10 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
tmp2 = -1;
|
tmp2 = -1;
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1]))
|
||||||
format += pcode_const_from_format(format + 1, &thing2);
|
format += pcode_const_from_format(format + 1, &thing2);
|
||||||
} else {
|
else
|
||||||
#line 371
|
CError_FATAL(371);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (thing2 == spr_to_sysreg[i]) {
|
if (thing2 == spr_to_sysreg[i]) {
|
||||||
|
@ -368,12 +369,10 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
tmp2 = (unsigned char) c;
|
tmp2 = (unsigned char) c;
|
||||||
thing3 = 16;
|
thing3 = 16;
|
||||||
if (*format == 'a') {
|
if (*format == 'a') {
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1]))
|
||||||
tmp2 = (unsigned char) *(++format);
|
tmp2 = (unsigned char) *(++format);
|
||||||
} else {
|
else
|
||||||
#line 408
|
CError_FATAL(408);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1])) {
|
||||||
format += pcode_const_from_format(format + 1, &thing3);
|
format += pcode_const_from_format(format + 1, &thing3);
|
||||||
|
@ -381,30 +380,24 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
arg->data.imm.value = va_arg(argList, int);
|
arg->data.imm.value = va_arg(argList, int);
|
||||||
arg->data.imm.obj = NULL;
|
arg->data.imm.obj = NULL;
|
||||||
if (pcode_check_imm_bits(arg->data.imm.value, thing3, tmp2)) {
|
if (pcode_check_imm_bits(arg->data.imm.value, thing3, tmp2))
|
||||||
#line 419
|
CError_FATAL(419);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N':
|
case 'N':
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
arg->data.imm.value = va_arg(argList, int);
|
arg->data.imm.value = va_arg(argList, int);
|
||||||
arg->data.imm.obj = NULL;
|
arg->data.imm.obj = NULL;
|
||||||
if (pcode_check_imm_bits(arg->data.imm.value, 6, 'u')) {
|
if (pcode_check_imm_bits(arg->data.imm.value, 6, 'u'))
|
||||||
#line 429
|
CError_FATAL(429);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
arg->data.imm.value = va_arg(argList, int);
|
arg->data.imm.value = va_arg(argList, int);
|
||||||
arg->data.imm.obj = NULL;
|
arg->data.imm.obj = NULL;
|
||||||
if (pcode_check_imm_bits(arg->data.imm.value, 10, 'u')) {
|
if (pcode_check_imm_bits(arg->data.imm.value, 10, 'u'))
|
||||||
#line 438
|
CError_FATAL(438);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
|
@ -412,10 +405,8 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
arg->data.imm.value = va_arg(argList, int);
|
arg->data.imm.value = va_arg(argList, int);
|
||||||
arg->data.imm.obj = NULL;
|
arg->data.imm.obj = NULL;
|
||||||
if (pcode_check_imm_bits(arg->data.imm.value, 5, 'u')) {
|
if (pcode_check_imm_bits(arg->data.imm.value, 5, 'u'))
|
||||||
#line 448
|
CError_FATAL(448);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
|
@ -428,10 +419,8 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
arg->data.imm.value = va_arg(argList, int);
|
arg->data.imm.value = va_arg(argList, int);
|
||||||
arg->data.imm.obj = NULL;
|
arg->data.imm.obj = NULL;
|
||||||
if (pcode_check_imm_bits(arg->data.imm.value, 4, 'u')) {
|
if (pcode_check_imm_bits(arg->data.imm.value, 4, 'u'))
|
||||||
#line 463
|
CError_FATAL(463);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
|
@ -441,8 +430,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
} else {
|
} else {
|
||||||
arg->kind = PCOp_MEMORY;
|
arg->kind = PCOp_MEMORY;
|
||||||
obj = va_arg(argList, Object *);
|
obj = va_arg(argList, Object *);
|
||||||
#line 476
|
CError_ASSERT(476, obj->otype == OT_OBJECT);
|
||||||
CError_ASSERT(obj->otype == OT_OBJECT);
|
|
||||||
arg->data.mem.obj = obj;
|
arg->data.mem.obj = obj;
|
||||||
arg->data.mem.offset = 0;
|
arg->data.mem.offset = 0;
|
||||||
arg->arg = 1;
|
arg->arg = 1;
|
||||||
|
@ -450,8 +438,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
#line 490
|
CError_ASSERT(490, format[1] == '(');
|
||||||
CError_ASSERT(format[1] == '(');
|
|
||||||
effect = EffectRead;
|
effect = EffectRead;
|
||||||
format += 2;
|
format += 2;
|
||||||
if (*format == '=') {
|
if (*format == '=') {
|
||||||
|
@ -462,8 +449,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
format++;
|
format++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 502
|
CError_ASSERT(502, format[0] == 'b');
|
||||||
CError_ASSERT(format[0] == 'b');
|
|
||||||
|
|
||||||
tmp = va_arg(argList, int);
|
tmp = va_arg(argList, int);
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
|
@ -477,8 +463,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
case 'm':
|
case 'm':
|
||||||
obj = va_arg(argList, Object *);
|
obj = va_arg(argList, Object *);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
#line 515
|
CError_ASSERT(515, obj->otype == OT_OBJECT);
|
||||||
CError_ASSERT(obj->otype == OT_OBJECT);
|
|
||||||
|
|
||||||
if (obj->datatype == DABSOLUTE) {
|
if (obj->datatype == DABSOLUTE) {
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
|
@ -490,7 +475,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->data.mem.offset = va_arg(argList, SInt32);
|
arg->data.mem.offset = va_arg(argList, SInt32);
|
||||||
|
|
||||||
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4 | fPCodeFlag20000 | fPCodeFlag40000)) {
|
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4 | fPCodeFlag20000 | fPCodeFlag40000)) {
|
||||||
pcode->_18 = make_alias(obj, arg->data.mem.offset, nbytes_loaded_or_stored_by(pcode));
|
pcode->alias = make_alias(obj, arg->data.mem.offset, nbytes_loaded_or_stored_by(pcode));
|
||||||
if (is_volatile_object(obj))
|
if (is_volatile_object(obj))
|
||||||
pcode->flags |= fIsVolatile;
|
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->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
|
||||||
|
@ -498,10 +483,9 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
pcode->flags |= fIsConst;
|
pcode->flags |= fIsConst;
|
||||||
} else {
|
} else {
|
||||||
if (pcode->op == PC_ADDI)
|
if (pcode->op == PC_ADDI)
|
||||||
pcode->_18 = make_alias(obj, arg->data.mem.offset, 1);
|
pcode->alias = make_alias(obj, arg->data.mem.offset, 1);
|
||||||
}
|
}
|
||||||
#line 536
|
CError_ASSERT(536, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
|
||||||
CError_ASSERT(obj->datatype == DLOCAL || arg->data.mem.offset == 0);
|
|
||||||
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) {
|
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) {
|
||||||
//if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
|
//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))
|
if (OBJ_GET_TARGET_VOLATILE(obj))
|
||||||
|
@ -534,8 +518,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
case 'M':
|
case 'M':
|
||||||
obj = va_arg(argList, Object *);
|
obj = va_arg(argList, Object *);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
#line 578
|
CError_ASSERT(578, obj->otype == OT_OBJECT);
|
||||||
CError_ASSERT(obj->otype == OT_OBJECT);
|
|
||||||
|
|
||||||
if (obj->datatype == DABSOLUTE) {
|
if (obj->datatype == DABSOLUTE) {
|
||||||
arg->kind = PCOp_IMMEDIATE;
|
arg->kind = PCOp_IMMEDIATE;
|
||||||
|
@ -546,8 +529,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
arg->data.mem.obj = obj;
|
arg->data.mem.obj = obj;
|
||||||
arg->data.mem.offset = va_arg(argList, SInt32);
|
arg->data.mem.offset = va_arg(argList, SInt32);
|
||||||
|
|
||||||
#line 590
|
CError_ASSERT(590, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
|
||||||
CError_ASSERT(obj->datatype == DLOCAL || arg->data.mem.offset == 0);
|
|
||||||
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) {
|
if (pcode->flags & (fPCodeFlag2 | fPCodeFlag4)) {
|
||||||
//if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
|
//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))
|
if (OBJ_GET_TARGET_VOLATILE(obj))
|
||||||
|
@ -581,8 +563,7 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 629
|
CError_FATAL(629);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (format[1] && strchr("/<>|*", format[1])) {
|
while (format[1] && strchr("/<>|*", format[1])) {
|
||||||
|
@ -595,14 +576,13 @@ PCode *vformatpcode(short opcode, va_list argList) {
|
||||||
case '*':
|
case '*':
|
||||||
case '|':
|
case '|':
|
||||||
case '>':
|
case '>':
|
||||||
if (format[1] == 'p') {
|
if (format[1] == 'p')
|
||||||
format++;
|
format++;
|
||||||
} else if (isdigit(format[1])) {
|
else if (isdigit(format[1]))
|
||||||
format += pcode_const_from_format(format + 1, &thing4);
|
format += pcode_const_from_format(format + 1, &thing4);
|
||||||
} else {
|
else
|
||||||
#line 659
|
CError_FATAL(659);
|
||||||
CError_FATAL();
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,10 +716,8 @@ int expectandformatoperand(PCodeArg *operand, PCOpKind expectedKind, char a3, in
|
||||||
buf += tmp;
|
buf += tmp;
|
||||||
}
|
}
|
||||||
name = CMangler_GetLinkName(operand->data.mem.obj)->name;
|
name = CMangler_GetLinkName(operand->data.mem.obj)->name;
|
||||||
if (strlen(name) == 0 || strlen(name) > 3200 || name[0] < 0) {
|
if (strlen(name) == 0 || strlen(name) > 3200 || name[0] < 0)
|
||||||
#line 849
|
CError_FATAL(849);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
if (strlen(name) > 50)
|
if (strlen(name) > 50)
|
||||||
tmp = sprintf(buf, "%45.45s...", name);
|
tmp = sprintf(buf, "%45.45s...", name);
|
||||||
else
|
else
|
||||||
|
@ -911,32 +889,26 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
#line 1124
|
CError_ASSERT(1124, pa->data.reg.reg == 0);
|
||||||
CError_ASSERT(pa->data.reg.reg == 0);
|
|
||||||
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
#line 1129
|
CError_ASSERT(1129, pa->data.reg.reg == 2);
|
||||||
CError_ASSERT(pa->data.reg.reg == 2);
|
|
||||||
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
#line 1134
|
CError_ASSERT(1134, pa->data.reg.reg == 1);
|
||||||
CError_ASSERT(pa->data.reg.reg == 1);
|
|
||||||
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
#line 1139
|
CError_ASSERT(1139, pa->data.reg.reg == 0);
|
||||||
CError_ASSERT(pa->data.reg.reg == 0);
|
|
||||||
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if (isdigit(format[1])) {
|
if (isdigit(format[1]))
|
||||||
format += pcode_const_from_format(format + 1, &thing);
|
format += pcode_const_from_format(format + 1, &thing);
|
||||||
} else {
|
else
|
||||||
#line 1149
|
CError_FATAL(1149);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
case 'S':
|
case 'S':
|
||||||
case 'T':
|
case 'T':
|
||||||
case 's':
|
case 's':
|
||||||
|
@ -945,8 +917,7 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (pa->data.reg.reg == spr_to_sysreg[i]) {
|
if (pa->data.reg.reg == spr_to_sysreg[i]) {
|
||||||
#line 1161
|
CError_FATAL(1161);
|
||||||
CError_FATAL();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,8 +973,7 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
format++;
|
format++;
|
||||||
tmp = *format;
|
tmp = *format;
|
||||||
} else {
|
} else {
|
||||||
#line 1227
|
CError_FATAL(1227);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tmp2 = isdigit(format[1])))
|
if ((tmp2 = isdigit(format[1])))
|
||||||
|
@ -1046,14 +1016,12 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
buf += expectandformatoperand(pa + 1, PCOp_MEMORY, 0, -1, buf);
|
buf += expectandformatoperand(pa + 1, PCOp_MEMORY, 0, -1, buf);
|
||||||
else
|
else
|
||||||
buf += expectandformatoperand(pa + 1, PCOp_IMMEDIATE, 0, -1, buf);
|
buf += expectandformatoperand(pa + 1, PCOp_IMMEDIATE, 0, -1, buf);
|
||||||
#line 1283
|
CError_ASSERT(1283, format[1] == '(');
|
||||||
CError_ASSERT(format[1] == '(');
|
|
||||||
format++;
|
format++;
|
||||||
*(buf++) = *(format++);
|
*(buf++) = *(format++);
|
||||||
if (*format == '+')
|
if (*format == '+')
|
||||||
format++;
|
format++;
|
||||||
#line 1291
|
CError_ASSERT(1291, format[0] == 'b');
|
||||||
CError_ASSERT(format[0] == 'b');
|
|
||||||
if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
|
if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
|
||||||
if (pa->data.reg.effect & (EffectRead | EffectWrite)) {
|
if (pa->data.reg.effect & (EffectRead | EffectWrite)) {
|
||||||
pclist_bad_operand = 1;
|
pclist_bad_operand = 1;
|
||||||
|
@ -1088,8 +1056,7 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
if (pa->kind == PCOp_MEMORY) {
|
if (pa->kind == PCOp_MEMORY) {
|
||||||
#line 1335
|
CError_ASSERT(1335, pa->arg == RefType_8 || pa->arg == RefType_B || pa->arg == RefType_C);
|
||||||
CError_ASSERT(pa->arg == RefType_8 || pa->arg == RefType_B || pa->arg == RefType_C);
|
|
||||||
buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
|
||||||
} else if (pa->kind == PCOp_LABELDIFF)
|
} else if (pa->kind == PCOp_LABELDIFF)
|
||||||
buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
|
buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
|
||||||
|
@ -1107,8 +1074,7 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 1465
|
CError_FATAL(1465);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (format[1] && strchr("/<>|*", format[1])) {
|
while (format[1] && strchr("/<>|*", format[1])) {
|
||||||
|
@ -1121,14 +1087,13 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||||
case '*':
|
case '*':
|
||||||
case '|':
|
case '|':
|
||||||
case '>':
|
case '>':
|
||||||
if (format[1] == 'p') {
|
if (format[1] == 'p')
|
||||||
format++;
|
format++;
|
||||||
} else if (isdigit(format[1])) {
|
else if (isdigit(format[1]))
|
||||||
format += pcode_const_from_format(format + 1, &thing4);
|
format += pcode_const_from_format(format + 1, &thing4);
|
||||||
} else {
|
else
|
||||||
#line 1495
|
CError_FATAL(1495);
|
||||||
CError_FATAL();
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1286,13 +1251,11 @@ int nbytes_loaded_or_stored_by(PCode *pcode) {
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 2011
|
CError_FATAL(2011);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 2014
|
CError_FATAL(2014);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,10 +134,8 @@ static void pclistblock(PCodeBlock *block, char *format, UInt32 vecSize) {
|
||||||
|
|
||||||
fflush(pcfile);
|
fflush(pcfile);
|
||||||
|
|
||||||
if (pclist_bad_operand) {
|
if (pclist_bad_operand)
|
||||||
#line 252
|
CError_FATAL(252);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pclistonoff(int flag) {
|
static void pclistonoff(int flag) {
|
||||||
|
@ -282,10 +280,8 @@ void pclistblocks_start_scheduler(char *str1, char *str2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pclistblocks_end_scheduler(void) {
|
void pclistblocks_end_scheduler(void) {
|
||||||
if (pclist_bad_operand) {
|
if (pclist_bad_operand)
|
||||||
#line 1318
|
CError_FATAL(1318);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printheapsize(void) {
|
static void printheapsize(void) {
|
||||||
|
@ -316,10 +312,8 @@ int formatalias(Alias *alias, char *buf, int bufSize) {
|
||||||
case AliasType0:
|
case AliasType0:
|
||||||
case AliasType1:
|
case AliasType1:
|
||||||
name = CMangler_GetLinkName(alias->object)->name;
|
name = CMangler_GetLinkName(alias->object)->name;
|
||||||
if (!strlen(name) || name[0] < 0) {
|
if (!strlen(name) || name[0] < 0)
|
||||||
#line 1458
|
CError_FATAL(1458);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(name) + 16 > bufSize)
|
if (strlen(name) + 16 > bufSize)
|
||||||
return sprintf(buf, "...");
|
return sprintf(buf, "...");
|
||||||
|
@ -369,8 +363,7 @@ int formatalias(Alias *alias, char *buf, int bufSize) {
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 1543
|
CError_FATAL(1543);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,10 +392,8 @@ int dumpalias(Alias *alias, int len, Boolean flag1, Boolean flag2) {
|
||||||
case AliasType0:
|
case AliasType0:
|
||||||
case AliasType1:
|
case AliasType1:
|
||||||
name = CMangler_GetLinkName(alias->object)->name;
|
name = CMangler_GetLinkName(alias->object)->name;
|
||||||
if (!strlen(name) || name[0] < 0) {
|
if (!strlen(name) || name[0] < 0)
|
||||||
#line 1581
|
CError_FATAL(1581);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (alias->object->datatype) {
|
switch (alias->object->datatype) {
|
||||||
case DNONLAZYPTR:
|
case DNONLAZYPTR:
|
||||||
|
@ -472,8 +463,7 @@ int dumpalias(Alias *alias, int len, Boolean flag1, Boolean flag2) {
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 1661
|
CError_FATAL(1661);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "compiler/PCodeUtilities.h"
|
#include "compiler/PCodeUtilities.h"
|
||||||
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CParser.h"
|
||||||
#include "compiler/PCode.h"
|
#include "compiler/PCode.h"
|
||||||
#include "compiler/PCodeInfo.h"
|
#include "compiler/PCodeInfo.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/Registers.h"
|
||||||
#include "compiler/enode.h"
|
#include "compiler/enode.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler.h"
|
|
||||||
|
|
||||||
void pcsetrecordbit(PCode *pc) {
|
void pcsetrecordbit(PCode *pc) {
|
||||||
int reg;
|
int reg;
|
||||||
|
@ -29,14 +30,12 @@ void pcsetrecordbit(PCode *pc) {
|
||||||
change_num_operands(pc, 5);
|
change_num_operands(pc, 5);
|
||||||
pc->op = PC_ADDICR;
|
pc->op = PC_ADDICR;
|
||||||
|
|
||||||
#line 76
|
CError_ASSERT(76, pc->args[3].kind == PCOp_PLACEHOLDEROPERAND);
|
||||||
CError_ASSERT(pc->args[3].kind == PCOp_PLACEHOLDEROPERAND);
|
|
||||||
pc->args[3].kind = PCOp_REGISTER;
|
pc->args[3].kind = PCOp_REGISTER;
|
||||||
pc->args[3].arg = RegClass_SPR;
|
pc->args[3].arg = RegClass_SPR;
|
||||||
pc->args[3].data.reg.reg = 0;
|
pc->args[3].data.reg.reg = 0;
|
||||||
pc->args[3].data.reg.effect = EffectWrite;
|
pc->args[3].data.reg.effect = EffectWrite;
|
||||||
#line 80
|
CError_ASSERT(80, pc->args[4].kind == PCOp_PLACEHOLDEROPERAND);
|
||||||
CError_ASSERT(pc->args[4].kind == PCOp_PLACEHOLDEROPERAND);
|
|
||||||
pc->args[4].kind = PCOp_REGISTER;
|
pc->args[4].kind = PCOp_REGISTER;
|
||||||
pc->args[4].arg = RegClass_CRFIELD;
|
pc->args[4].arg = RegClass_CRFIELD;
|
||||||
pc->args[4].data.reg.reg = reg;
|
pc->args[4].data.reg.reg = reg;
|
||||||
|
@ -59,8 +58,7 @@ void pcsetrecordbit(PCode *pc) {
|
||||||
pc->argCount++;
|
pc->argCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 105
|
CError_ASSERT(105, arg->kind == PCOp_PLACEHOLDEROPERAND);
|
||||||
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
|
|
||||||
arg->kind = PCOp_REGISTER;
|
arg->kind = PCOp_REGISTER;
|
||||||
arg->arg = RegClass_CRFIELD;
|
arg->arg = RegClass_CRFIELD;
|
||||||
arg->data.reg.reg = reg;
|
arg->data.reg.reg = reg;
|
||||||
|
@ -103,8 +101,7 @@ void pcsetlinkbit(PCode *pc) {
|
||||||
argIdx--;
|
argIdx--;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 169
|
CError_ASSERT(169, arg->kind == PCOp_PLACEHOLDEROPERAND);
|
||||||
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
|
|
||||||
arg->kind = PCOp_REGISTER;
|
arg->kind = PCOp_REGISTER;
|
||||||
arg->arg = RegClass_SPR;
|
arg->arg = RegClass_SPR;
|
||||||
arg->data.reg.reg = 1;
|
arg->data.reg.reg = 1;
|
||||||
|
@ -164,7 +161,7 @@ void branch_always(PCodeLabel *label) {
|
||||||
makepcblock();
|
makepcblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void branch_decrement_always(short opcode, PCodeLabel *label) {
|
void branch_decrement_always(Opcode opcode, PCodeLabel *label) {
|
||||||
PCodeLabel *tmplabel = makepclabel();
|
PCodeLabel *tmplabel = makepclabel();
|
||||||
emitpcode(opcode, label);
|
emitpcode(opcode, label);
|
||||||
pcbranch(pclastblock, label);
|
pcbranch(pclastblock, label);
|
||||||
|
@ -181,10 +178,10 @@ void branch_indirect(Object *obj) {
|
||||||
int branch_count_volatiles(void) {
|
int branch_count_volatiles(void) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int i;
|
int i;
|
||||||
char rclass;
|
RegClass rclass;
|
||||||
|
|
||||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||||
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
|
for (i = 0; i < n_scratch_registers[rclass]; i++) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,15 +191,15 @@ int branch_count_volatiles(void) {
|
||||||
|
|
||||||
PCodeArg *branch_record_volatiles(PCodeArg *arglist, UInt32 *masks) {
|
PCodeArg *branch_record_volatiles(PCodeArg *arglist, UInt32 *masks) {
|
||||||
int i;
|
int i;
|
||||||
char rclass;
|
RegClass rclass;
|
||||||
|
|
||||||
for (rclass = RegClassMax - 1; rclass >= 0; rclass--) {
|
for (rclass = RegClassMax - 1; rclass >= 0; rclass--) {
|
||||||
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
|
for (i = 0; i < n_scratch_registers[rclass]; i++) {
|
||||||
arglist->kind = PCOp_REGISTER;
|
arglist->kind = PCOp_REGISTER;
|
||||||
arglist->arg = rclass;
|
arglist->arg = rclass;
|
||||||
arglist->data.reg.reg = scratch_registers[(char)rclass][i];
|
arglist->data.reg.reg = scratch_registers[rclass][i];
|
||||||
arglist->data.reg.effect = EffectWrite;
|
arglist->data.reg.effect = EffectWrite;
|
||||||
if (masks[(char)rclass] & (1 << scratch_registers[(char)rclass][i]))
|
if (masks[rclass] & (1 << scratch_registers[rclass][i]))
|
||||||
arglist->data.reg.effect |= EffectRead;
|
arglist->data.reg.effect |= EffectRead;
|
||||||
arglist++;
|
arglist++;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +251,7 @@ void branch_subroutine_ctr(UInt32 *masks) {
|
||||||
recordexceptionactions(pc, current_statement->dobjstack);
|
recordexceptionactions(pc, current_statement->dobjstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_immediate(short dest_reg, short base_reg, Object *obj, short offset) {
|
void add_immediate(short dest_reg, short base_reg, Object *obj, SInt16 offset) {
|
||||||
short tmp_reg = base_reg;
|
short tmp_reg = base_reg;
|
||||||
|
|
||||||
if (obj && offset && obj->datatype != DLOCAL) {
|
if (obj && offset && obj->datatype != DLOCAL) {
|
||||||
|
@ -269,11 +266,10 @@ void add_immediate(short dest_reg, short base_reg, Object *obj, short offset) {
|
||||||
emitpcode(PC_ADDI, dest_reg, tmp_reg, obj, offset);
|
emitpcode(PC_ADDI, dest_reg, tmp_reg, obj, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCode *add_immediate_lo(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
|
PCode *add_immediate_lo(short dest_reg, short base_reg, Object *obj, SInt16 offset, char add_to_block) {
|
||||||
PCode *pc;
|
PCode *pc;
|
||||||
|
|
||||||
#line 577
|
CError_ASSERT(577, obj);
|
||||||
CError_ASSERT(obj);
|
|
||||||
|
|
||||||
pc = makepcode(PC_ADDI, dest_reg, base_reg, obj, offset);
|
pc = makepcode(PC_ADDI, dest_reg, base_reg, obj, offset);
|
||||||
if (add_to_block)
|
if (add_to_block)
|
||||||
|
@ -289,12 +285,10 @@ PCode *op_absolute_ha(short dest_reg, short base_reg, Object *obj, short offset,
|
||||||
pc = makepcode(PC_ADDIS, dest_reg, base_reg, obj, offset);
|
pc = makepcode(PC_ADDIS, dest_reg, base_reg, obj, offset);
|
||||||
} else if (copts.codegen_pic) {
|
} else if (copts.codegen_pic) {
|
||||||
tmp_reg = base_reg;
|
tmp_reg = base_reg;
|
||||||
#line 601
|
CError_ASSERT(601, tmp_reg);
|
||||||
CError_ASSERT(tmp_reg);
|
|
||||||
pc = makepcode(PC_ADDIS, dest_reg, tmp_reg, obj, offset);
|
pc = makepcode(PC_ADDIS, dest_reg, tmp_reg, obj, offset);
|
||||||
} else {
|
} else {
|
||||||
#line 606
|
CError_ASSERT(606, base_reg == 0);
|
||||||
CError_ASSERT(base_reg == 0);
|
|
||||||
pc = makepcode(PC_LIS, dest_reg, obj, offset);
|
pc = makepcode(PC_LIS, dest_reg, obj, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +297,7 @@ PCode *op_absolute_ha(short dest_reg, short base_reg, Object *obj, short offset,
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_store_register(short opcode, short dest_reg, short base_reg, Object *obj, SInt32 offset) {
|
void load_store_register(Opcode opcode, short dest_reg, short base_reg, Object *obj, SInt32 offset) {
|
||||||
short addi_tmp;
|
short addi_tmp;
|
||||||
short offset_reg1;
|
short offset_reg1;
|
||||||
short offset_reg2;
|
short offset_reg2;
|
||||||
|
|
|
@ -8,8 +8,7 @@ static void PPCError_GetErrorString(char *str, short code) {
|
||||||
short scode;
|
short scode;
|
||||||
|
|
||||||
scode = (short) code;
|
scode = (short) code;
|
||||||
#line 40
|
CError_ASSERT(40, scode >= 100 && scode < 212);
|
||||||
CError_ASSERT(scode >= 100 && scode < 212);
|
|
||||||
|
|
||||||
COS_GetString(str, 10001, scode - 99);
|
COS_GetString(str, 10001, scode - 99);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,8 +42,7 @@ void asm_used_register(RegClass rclass, short reg) {
|
||||||
void retain_register(Object *obj, RegClass rclass, short reg) {
|
void retain_register(Object *obj, RegClass rclass, short reg) {
|
||||||
VarInfo *vi;
|
VarInfo *vi;
|
||||||
|
|
||||||
#line 95
|
CError_ASSERT(95, (short) reg < RegisterMax);
|
||||||
CError_ASSERT((short) reg < RegisterMax);
|
|
||||||
|
|
||||||
if (reg_state[rclass][reg] == RegState0) {
|
if (reg_state[rclass][reg] == RegState0) {
|
||||||
assignable_registers[rclass]--;
|
assignable_registers[rclass]--;
|
||||||
|
@ -96,8 +95,7 @@ char GetRegisterClassName(RegClass rclass) {
|
||||||
case RegClass_GPR: return 'r';
|
case RegClass_GPR: return 'r';
|
||||||
case RegClass_FPR: return 'f';
|
case RegClass_FPR: return 'f';
|
||||||
default:
|
default:
|
||||||
#line 242
|
CError_FATAL(242);
|
||||||
CError_FATAL();
|
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,8 +205,7 @@ void assign_register_by_type(Object *obj) {
|
||||||
|
|
||||||
if (vi->rclass < RegClassMax) {
|
if (vi->rclass < RegClassMax) {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
#line 520
|
CError_ASSERT(520, vi->rclass == RegClass_GPR);
|
||||||
CError_ASSERT(vi->rclass == RegClass_GPR);
|
|
||||||
if (assignable_registers[vi->rclass] > 1)
|
if (assignable_registers[vi->rclass] > 1)
|
||||||
assign_GPR_pair(obj);
|
assign_GPR_pair(obj);
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,8 +225,7 @@ void assign_GPR_pair(Object *obj) {
|
||||||
reg = used_virtual_registers[RegClass_GPR]++;
|
reg = used_virtual_registers[RegClass_GPR]++;
|
||||||
regHi = used_virtual_registers[RegClass_GPR]++;
|
regHi = used_virtual_registers[RegClass_GPR]++;
|
||||||
} else {
|
} else {
|
||||||
#line 554
|
CError_ASSERT(554, assignable_registers[RegClass_GPR] >= 2);
|
||||||
CError_ASSERT(assignable_registers[RegClass_GPR] >= 2);
|
|
||||||
reg = obtain_nonvolatile_register(RegClass_GPR);
|
reg = obtain_nonvolatile_register(RegClass_GPR);
|
||||||
regHi = obtain_nonvolatile_register(RegClass_GPR);
|
regHi = obtain_nonvolatile_register(RegClass_GPR);
|
||||||
retain_GPR_pair(obj, reg, regHi);
|
retain_GPR_pair(obj, reg, regHi);
|
||||||
|
@ -241,8 +237,7 @@ void assign_GPR_pair(Object *obj) {
|
||||||
vi->reg = reg;
|
vi->reg = reg;
|
||||||
vi->regHi = regHi;
|
vi->regHi = regHi;
|
||||||
} else {
|
} else {
|
||||||
#line 567
|
CError_FATAL(567);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,18 +274,14 @@ VarInfo *Registers_GetVarInfo(Object *obj) {
|
||||||
obj->u.data.info = Registers_GetNewVarInfo();
|
obj->u.data.info = Registers_GetNewVarInfo();
|
||||||
return obj->u.data.info;
|
return obj->u.data.info;
|
||||||
case DNONLAZYPTR:
|
case DNONLAZYPTR:
|
||||||
// not sure if this is the right union
|
|
||||||
if (!obj->u.toc.info) {
|
if (!obj->u.toc.info) {
|
||||||
#line 639
|
CError_FATAL(639);
|
||||||
CError_FATAL();
|
|
||||||
obj->u.toc.info = CodeGen_GetNewVarInfo();
|
obj->u.toc.info = CodeGen_GetNewVarInfo();
|
||||||
}
|
}
|
||||||
return obj->u.toc.info;
|
return obj->u.toc.info;
|
||||||
case DLOCAL:
|
case DLOCAL:
|
||||||
if (!obj->u.var.info) {
|
if (!obj->u.var.info)
|
||||||
#line 647
|
CError_FATAL(647);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
return obj->u.var.info;
|
return obj->u.var.info;
|
||||||
case DABSOLUTE:
|
case DABSOLUTE:
|
||||||
// not sure if this is the right union
|
// not sure if this is the right union
|
||||||
|
@ -298,8 +289,7 @@ VarInfo *Registers_GetVarInfo(Object *obj) {
|
||||||
obj->u.data.info = Registers_GetNewVarInfo();
|
obj->u.data.info = Registers_GetNewVarInfo();
|
||||||
return obj->u.data.info;
|
return obj->u.data.info;
|
||||||
default:
|
default:
|
||||||
#line 660
|
CError_FATAL(660);
|
||||||
CError_FATAL();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "compiler/ScanFloat.h"
|
||||||
|
|
||||||
|
char *ScanFloat(const char *str, double *result, Boolean *failed) {
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
*result = strtod(str, &end);
|
||||||
|
*failed = 0;
|
||||||
|
return end;
|
||||||
|
}
|
|
@ -268,8 +268,7 @@ static void findsuccessors(DGNode *nodes, DGNode *node) {
|
||||||
op->data.reg.reg > used_virtual_registers[(char) op->arg]
|
op->data.reg.reg > used_virtual_registers[(char) op->arg]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#line 491
|
CError_FATAL(491);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
|
if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
|
||||||
|
|
|
@ -79,8 +79,7 @@ static Object *makespilltemporary(Type *type) {
|
||||||
static PCode *rematerialize_spilled_register(short reg, IGNode *node) {
|
static PCode *rematerialize_spilled_register(short reg, IGNode *node) {
|
||||||
PCode *instr = copypcode(node->instr8);
|
PCode *instr = copypcode(node->instr8);
|
||||||
|
|
||||||
#line 128
|
CError_ASSERT(128, instr->args[0].kind == PCOp_REGISTER);
|
||||||
CError_ASSERT(instr->args[0].kind == PCOp_REGISTER);
|
|
||||||
|
|
||||||
instr->args[0].data.reg.reg = reg;
|
instr->args[0].data.reg.reg = reg;
|
||||||
return instr;
|
return instr;
|
||||||
|
@ -113,23 +112,19 @@ static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node)
|
||||||
opcode = PC_LWZ;
|
opcode = PC_LWZ;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 187
|
CError_FATAL(187);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memclrw(&operand, sizeof(Operand));
|
memclrw(&operand, sizeof(Operand));
|
||||||
operand.optype = OpndType_Symbol;
|
operand.optype = OpndType_Symbol;
|
||||||
operand.object = node->spillTemporary;
|
operand.object = node->spillTemporary;
|
||||||
#line 222
|
CError_ASSERT(222, node->spillTemporary->datatype == DLOCAL);
|
||||||
CError_ASSERT(node->spillTemporary->datatype == DLOCAL);
|
|
||||||
|
|
||||||
coerce_to_addressable(&operand);
|
coerce_to_addressable(&operand);
|
||||||
|
|
||||||
#line 233
|
CError_ASSERT(233, operand.optype == OpndType_GPR_ImmOffset);
|
||||||
CError_ASSERT(operand.optype == OpndType_GPR_ImmOffset);
|
|
||||||
|
|
||||||
#line 237
|
CError_ASSERT(237, node->spillTemporary->datatype == DLOCAL);
|
||||||
CError_ASSERT(node->spillTemporary->datatype == DLOCAL);
|
|
||||||
|
|
||||||
if (node->flags & fPairLow)
|
if (node->flags & fPairLow)
|
||||||
offset = low_offset;
|
offset = low_offset;
|
||||||
|
@ -141,8 +136,7 @@ static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RegClass_FPR:
|
case RegClass_FPR:
|
||||||
#line 253
|
CError_ASSERT(253, node->spillTemporary->datatype == DLOCAL);
|
||||||
CError_ASSERT(node->spillTemporary->datatype == DLOCAL);
|
|
||||||
|
|
||||||
if (node->flags & fPairLow)
|
if (node->flags & fPairLow)
|
||||||
offset = low_offset;
|
offset = low_offset;
|
||||||
|
@ -165,8 +159,7 @@ static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RegClass_VR:
|
case RegClass_VR:
|
||||||
#line 320
|
CError_ASSERT(320, node->spillTemporary->datatype == DLOCAL);
|
||||||
CError_ASSERT(node->spillTemporary->datatype == DLOCAL);
|
|
||||||
|
|
||||||
object = node->spillTemporary;
|
object = node->spillTemporary;
|
||||||
newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
|
newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
|
||||||
|
@ -176,8 +169,7 @@ static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 333
|
CError_FATAL(333);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,8 +201,7 @@ static void insert_store_spilled_register(PCode *instr, Boolean flag, short reg,
|
||||||
opcode = PC_STW;
|
opcode = PC_STW;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 391
|
CError_FATAL(391);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->flags & fPairLow)
|
if (node->flags & fPairLow)
|
||||||
|
@ -249,8 +240,7 @@ static void insert_store_spilled_register(PCode *instr, Boolean flag, short reg,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#line 527
|
CError_FATAL(527);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +260,7 @@ static void spillinstruction(PCodeBlock *block, PCode *instr) {
|
||||||
regs = used_virtual_registers[coloring_class];
|
regs = used_virtual_registers[coloring_class];
|
||||||
flag = 0;
|
flag = 0;
|
||||||
for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
|
for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
|
||||||
#line 563
|
CError_ASSERT(563, instr->block != NULL);
|
||||||
CError_ASSERT(instr->block != NULL);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
|
PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
|
||||||
|
@ -401,8 +390,7 @@ static void assign_spill_locations(void) {
|
||||||
type = TYPE(&stvectorunsignedchar);
|
type = TYPE(&stvectorunsignedchar);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 771
|
CError_FATAL(771);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node->spillTemporary = makespilltemporary(type);
|
node->spillTemporary = makespilltemporary(type);
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
#include "compiler/StackFrame.h"
|
#include "compiler/StackFrame.h"
|
||||||
#include "compiler/CError.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/PCode.h"
|
||||||
#include "compiler/PCodeInfo.h"
|
#include "compiler/PCodeInfo.h"
|
||||||
#include "compiler/PCodeUtilities.h"
|
#include "compiler/PCodeUtilities.h"
|
||||||
|
#include "compiler/RegisterInfo.h"
|
||||||
#include "compiler/objects.h"
|
#include "compiler/objects.h"
|
||||||
#include "compiler.h"
|
#include "compiler/types.h"
|
||||||
|
|
||||||
#define ALIGN(thing, alignment) ( ~((alignment) - 1) & ((thing) + (alignment) - 1) )
|
#define ALIGN(thing, alignment) ( ~((alignment) - 1) & ((thing) + (alignment) - 1) )
|
||||||
#define ALIGN_REMAINDER(thing, alignment) ( ALIGN(thing, alignment) - (thing) )
|
#define ALIGN_REMAINDER(thing, alignment) ( ALIGN(thing, alignment) - (thing) )
|
||||||
|
@ -62,7 +68,7 @@ static void restore_nonvolatile_FPRs(int reg, SInt32 offset);
|
||||||
static void restore_nonvolatile_VRs(int reg, SInt32 offset);
|
static void restore_nonvolatile_VRs(int reg, SInt32 offset);
|
||||||
static void save_nonvolatile_GPRs(int reg, SInt32 offset);
|
static void save_nonvolatile_GPRs(int reg, SInt32 offset);
|
||||||
static void restore_nonvolatile_GPRs(int reg, SInt32 offset);
|
static void restore_nonvolatile_GPRs(int reg, SInt32 offset);
|
||||||
static void do_allocate_dynamic_stack_space(Boolean flag1, int reg1, int reg2, SInt32 size);
|
static void do_allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size);
|
||||||
|
|
||||||
void init_stack_globals(Object *funcobj) {
|
void init_stack_globals(Object *funcobj) {
|
||||||
char rclass;
|
char rclass;
|
||||||
|
@ -236,8 +242,7 @@ void compute_frame_sizes(void) {
|
||||||
SInt32 altivec_size;
|
SInt32 altivec_size;
|
||||||
SInt32 altivec_offset;
|
SInt32 altivec_offset;
|
||||||
|
|
||||||
#line 897
|
CError_ASSERT(897, alloca_alignment == 0 || alloca_alignment == frame_alignment);
|
||||||
CError_ASSERT(alloca_alignment == 0 || alloca_alignment == frame_alignment);
|
|
||||||
|
|
||||||
update_asm_nonvolatile_registers();
|
update_asm_nonvolatile_registers();
|
||||||
LR_save_offset = 8;
|
LR_save_offset = 8;
|
||||||
|
@ -265,8 +270,7 @@ void compute_frame_sizes(void) {
|
||||||
local_data_size = ALIGN(local_data_size, frame_alignment);
|
local_data_size = ALIGN(local_data_size, frame_alignment);
|
||||||
nonvolatile_save_size = ALIGN(nonvolatile_save_size, frame_alignment);
|
nonvolatile_save_size = ALIGN(nonvolatile_save_size, frame_alignment);
|
||||||
if (!requires_frame && (local_data_size + nonvolatile_save_size) <= 224) {
|
if (!requires_frame && (local_data_size + nonvolatile_save_size) <= 224) {
|
||||||
#line 1005
|
CError_ASSERT(1005, !dynamic_align_stack);
|
||||||
CError_ASSERT(!dynamic_align_stack);
|
|
||||||
linkage_area_size = 0;
|
linkage_area_size = 0;
|
||||||
frame_size = 0;
|
frame_size = 0;
|
||||||
genuine_frame_size = local_data_size + nonvolatile_save_size;
|
genuine_frame_size = local_data_size + nonvolatile_save_size;
|
||||||
|
@ -276,8 +280,7 @@ void compute_frame_sizes(void) {
|
||||||
parameter_area_size = 32;
|
parameter_area_size = 32;
|
||||||
parameter_area_size = ALIGN(parameter_area_size + 24, frame_alignment) - 24;
|
parameter_area_size = ALIGN(parameter_area_size + 24, frame_alignment) - 24;
|
||||||
if (large_stack) {
|
if (large_stack) {
|
||||||
#line 1019
|
CError_ASSERT(1019, !large_data_far_size);
|
||||||
CError_ASSERT(!large_data_far_size);
|
|
||||||
large_data_near_size += parameter_area_size;
|
large_data_near_size += parameter_area_size;
|
||||||
parameter_area_size = 0;
|
parameter_area_size = 0;
|
||||||
}
|
}
|
||||||
|
@ -295,12 +298,10 @@ void compute_frame_sizes(void) {
|
||||||
|
|
||||||
static void allocate_new_frame(int reg1, int reg2) {
|
static void allocate_new_frame(int reg1, int reg2) {
|
||||||
if (dynamic_align_stack) {
|
if (dynamic_align_stack) {
|
||||||
#line 1116
|
CError_ASSERT(1116, reg1 != _CALLER_SP_);
|
||||||
CError_ASSERT(reg1 != _CALLER_SP_);
|
|
||||||
emitpcode(PC_RLWINM, reg1, 1, 0, align_bits(frame_alignment, 1), 31);
|
emitpcode(PC_RLWINM, reg1, 1, 0, align_bits(frame_alignment, 1), 31);
|
||||||
if (frame_size > 0x7FFF) {
|
if (frame_size > 0x7FFF) {
|
||||||
#line 1122
|
CError_FATAL(1122);
|
||||||
CError_FATAL();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,12 +315,10 @@ static void allocate_new_frame(int reg1, int reg2) {
|
||||||
|
|
||||||
emitpcode(PC_STWUX, 1, 1, reg1);
|
emitpcode(PC_STWUX, 1, 1, reg1);
|
||||||
} else {
|
} else {
|
||||||
if (frame_size > 0x7FFF) {
|
if (frame_size > 0x7FFF)
|
||||||
#line 1153
|
CError_FATAL(1153);
|
||||||
CError_FATAL();
|
else
|
||||||
} else {
|
|
||||||
emitpcode(PC_STWU, 1, 1, 0, -frame_size);
|
emitpcode(PC_STWU, 1, 1, 0, -frame_size);
|
||||||
}
|
|
||||||
|
|
||||||
if (reg2)
|
if (reg2)
|
||||||
emitpcode(PC_MR, reg2, 1);
|
emitpcode(PC_MR, reg2, 1);
|
||||||
|
@ -347,10 +346,9 @@ void generate_prologue(PCodeBlock *block, Boolean has_varargs) {
|
||||||
setup_caller_sp->args[1].kind == PCOp_REGISTER &&
|
setup_caller_sp->args[1].kind == PCOp_REGISTER &&
|
||||||
setup_caller_sp->args[1].arg == RegClass_GPR &&
|
setup_caller_sp->args[1].arg == RegClass_GPR &&
|
||||||
setup_caller_sp->args[1].data.reg.reg == _FP_
|
setup_caller_sp->args[1].data.reg.reg == _FP_
|
||||||
) {
|
)
|
||||||
#line 1197
|
CError_FATAL(1197);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
_CALLER_SP_ = setup_caller_sp->args[0].data.reg.reg;
|
_CALLER_SP_ = setup_caller_sp->args[0].data.reg.reg;
|
||||||
deletepcode(setup_caller_sp);
|
deletepcode(setup_caller_sp);
|
||||||
setup_caller_sp = NULL;
|
setup_caller_sp = NULL;
|
||||||
|
@ -401,8 +399,7 @@ void generate_prologue(PCodeBlock *block, Boolean has_varargs) {
|
||||||
}
|
}
|
||||||
allocate_new_frame(12, (_CALLER_SP_ > 0 && _CALLER_SP_ != _FP_) ? _CALLER_SP_ : 0);
|
allocate_new_frame(12, (_CALLER_SP_ > 0 && _CALLER_SP_ != _FP_) ? _CALLER_SP_ : 0);
|
||||||
} else {
|
} else {
|
||||||
#line 1326
|
CError_ASSERT(1326, !dynamic_align_stack);
|
||||||
CError_ASSERT(!dynamic_align_stack);
|
|
||||||
if (vrsave_mask)
|
if (vrsave_mask)
|
||||||
emitpcode(PC_MFSPR, vrsave_register, 256);
|
emitpcode(PC_MFSPR, vrsave_register, 256);
|
||||||
}
|
}
|
||||||
|
@ -626,9 +623,9 @@ static void restore_nonvolatile_GPRs(int reg, SInt32 offset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_allocate_dynamic_stack_space(Boolean flag1, int reg1, int reg2, SInt32 size) {
|
static void do_allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size) {
|
||||||
load_store_register(PC_LWZ, reg2, 1, NULL, 0);
|
load_store_register(PC_LWZ, reg2, 1, NULL, 0);
|
||||||
if (flag1) {
|
if (isConstantSize) {
|
||||||
size = ALIGN(size, frame_alignment);
|
size = ALIGN(size, frame_alignment);
|
||||||
if (size < 0x8000) {
|
if (size < 0x8000) {
|
||||||
emitpcode(PC_STWU, reg2, 1, 0, -size);
|
emitpcode(PC_STWU, reg2, 1, 0, -size);
|
||||||
|
@ -645,10 +642,10 @@ static void do_allocate_dynamic_stack_space(Boolean flag1, int reg1, int reg2, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocate_dynamic_stack_space(Boolean flag1, int reg1, int reg2, SInt32 size) {
|
void allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size) {
|
||||||
if (copts.altivec_model)
|
if (copts.altivec_model)
|
||||||
update_frame_align(16);
|
update_frame_align(16);
|
||||||
do_allocate_dynamic_stack_space(flag1, reg1, reg2, size);
|
do_allocate_dynamic_stack_space(isConstantSize, reg1, reg2, size);
|
||||||
add_immediate(reg1, 1, dummylocal, 0);
|
add_immediate(reg1, 1, dummylocal, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,10 +793,8 @@ void check_dynamic_aligned_frame(void) {
|
||||||
if (frame_alignment > in_param_alignment) {
|
if (frame_alignment > in_param_alignment) {
|
||||||
dynamic_align_stack = 1;
|
dynamic_align_stack = 1;
|
||||||
requires_frame = 1;
|
requires_frame = 1;
|
||||||
#line 2091
|
CError_ASSERT(2091, !has_varargs || _CALLER_SP_ != -1);
|
||||||
CError_ASSERT(!has_varargs || _CALLER_SP_ != -1);
|
CError_ASSERT(2096, _CALLER_SP_ != _FP_);
|
||||||
#line 2096
|
|
||||||
CError_ASSERT(_CALLER_SP_ != _FP_);
|
|
||||||
if (setup_caller_sp && setup_caller_sp->block) {
|
if (setup_caller_sp && setup_caller_sp->block) {
|
||||||
align_instr1 = makepcode(PC_RLWINM, 12, 1, 0, 5, 31);
|
align_instr1 = makepcode(PC_RLWINM, 12, 1, 0, 5, 31);
|
||||||
insertpcodebefore(setup_caller_sp, align_instr1);
|
insertpcodebefore(setup_caller_sp, align_instr1);
|
||||||
|
@ -894,7 +889,7 @@ void assign_arguments_to_memory(Object *func, UInt8 mysteryFlag, Boolean hasVara
|
||||||
flag = hasVarargs;
|
flag = hasVarargs;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
pos = ALIGN(pos + 24, 16) - 24;
|
pos = ALIGN(pos + 24, 16) - 24;
|
||||||
obj->u.var.offset = pos;
|
obj->u.var.uid = pos;
|
||||||
pos += 16;
|
pos += 16;
|
||||||
update_in_param_align(16);
|
update_in_param_align(16);
|
||||||
Registers_GetVarInfo(obj)->flags = (Registers_GetVarInfo(obj)->flags & ~VarInfoFlag1) | VarInfoFlag1;
|
Registers_GetVarInfo(obj)->flags = (Registers_GetVarInfo(obj)->flags & ~VarInfoFlag1) | VarInfoFlag1;
|
||||||
|
@ -907,8 +902,7 @@ void assign_arguments_to_memory(Object *func, UInt8 mysteryFlag, Boolean hasVara
|
||||||
}
|
}
|
||||||
|
|
||||||
in_parameter_size = (in_parameter_size < pos) ? pos : in_parameter_size;
|
in_parameter_size = (in_parameter_size < pos) ? pos : in_parameter_size;
|
||||||
#line 2408
|
CError_ASSERT(2408, !dummyvaparam);
|
||||||
CError_ASSERT(!dummyvaparam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SInt32 set_out_param_displ(SInt32 a, Type *type, Boolean flag, SInt32 *outvar, SInt32 b) {
|
SInt32 set_out_param_displ(SInt32 a, Type *type, Boolean flag, SInt32 *outvar, SInt32 b) {
|
||||||
|
@ -991,23 +985,22 @@ SInt32 local_offset_32(Object *obj) {
|
||||||
return offset + localsbase();
|
return offset + localsbase();
|
||||||
}
|
}
|
||||||
|
|
||||||
SInt16 local_offset_lo(Object *obj, SInt32 offset) {
|
SInt32 local_offset_lo(Object *obj, SInt32 offset) {
|
||||||
SInt32 combo = offset + local_offset_32(obj);
|
SInt32 combo = offset + local_offset_32(obj);
|
||||||
return LOW_PART(combo);
|
return LOW_PART(combo);
|
||||||
//return (SInt16) (offset + local_offset_32(obj));
|
//return (SInt16) (offset + local_offset_32(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
SInt16 local_offset_ha(Object *obj, SInt32 offset) {
|
SInt32 local_offset_ha(Object *obj, SInt32 offset) {
|
||||||
SInt32 combo = offset + local_offset_32(obj);
|
SInt32 combo = offset + local_offset_32(obj);
|
||||||
return HIGH_PART(combo);
|
return HIGH_PART(combo);
|
||||||
//return (SInt16) ((combo >> 16) + ((combo & 0x8000) >> 15));
|
//return (SInt16) ((combo >> 16) + ((combo & 0x8000) >> 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
SInt16 local_offset_16(Object *obj) {
|
SInt32 local_offset_16(Object *obj) {
|
||||||
SInt32 offset32 = local_offset_32(obj);
|
SInt32 offset32 = local_offset_32(obj);
|
||||||
SInt16 offset16 = (SInt16) offset32;
|
SInt16 offset16 = (SInt16) offset32;
|
||||||
#line 2662
|
CError_ASSERT(2662, offset32 == offset16);
|
||||||
CError_ASSERT(offset32 == offset16);
|
|
||||||
return offset16;
|
return offset16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,15 +1043,13 @@ static UInt32 align_bits(UInt32 value, UInt8 bitcount) {
|
||||||
case 0x1000: return base + 19;
|
case 0x1000: return base + 19;
|
||||||
case 0x2000: return base + 18;
|
case 0x2000: return base + 18;
|
||||||
default:
|
default:
|
||||||
#line 2754
|
CError_FATAL(2754);
|
||||||
CError_FATAL();
|
|
||||||
return base + 27;
|
return base + 27;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean is_large_frame(void) {
|
Boolean is_large_frame(void) {
|
||||||
#line 2769
|
CError_ASSERT(2769, frame_size != -1);
|
||||||
CError_ASSERT(frame_size != -1);
|
|
||||||
return large_stack;
|
return large_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,12 +1073,10 @@ SInt32 get_alloca_alignment(void) {
|
||||||
if (copts.altivec_model)
|
if (copts.altivec_model)
|
||||||
align = ALIGN(align, 16);
|
align = ALIGN(align, 16);
|
||||||
|
|
||||||
if (!alloca_alignment) {
|
if (!alloca_alignment)
|
||||||
alloca_alignment = align;
|
alloca_alignment = align;
|
||||||
} else {
|
else
|
||||||
#line 2825
|
CError_ASSERT(2825, alloca_alignment == align);
|
||||||
CError_ASSERT(alloca_alignment == align);
|
|
||||||
}
|
|
||||||
|
|
||||||
return align_bits(align, 0);
|
return align_bits(align, 0);
|
||||||
}
|
}
|
||||||
|
@ -1106,8 +1095,7 @@ static Boolean use_helper_function(char rclass) {
|
||||||
case RegClass_VR:
|
case RegClass_VR:
|
||||||
return (used_nonvolatile_registers[RegClass_VR] > 3) || (copts.optimize_for_size && used_nonvolatile_registers[RegClass_VR] > 2);
|
return (used_nonvolatile_registers[RegClass_VR] > 3) || (copts.optimize_for_size && used_nonvolatile_registers[RegClass_VR] > 2);
|
||||||
default:
|
default:
|
||||||
#line 2862
|
CError_FATAL(2862);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1178,8 +1166,7 @@ static SInt32 nearest_power_of_two(SInt32 n) {
|
||||||
power <<= 1;
|
power <<= 1;
|
||||||
} while (power && power < n);
|
} while (power && power < n);
|
||||||
|
|
||||||
#line 2933
|
CError_ASSERT(2933, power != 0);
|
||||||
CError_ASSERT(power != 0);
|
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -620,12 +620,10 @@ static void combineinductionvariables(Loop *loop, BasicInductionVar *biv1, Basic
|
||||||
instr2 = NULL;
|
instr2 = NULL;
|
||||||
|
|
||||||
reg1 = biv1->reg;
|
reg1 = biv1->reg;
|
||||||
#line 930
|
CError_ASSERT(930, reg1 >= 0);
|
||||||
CError_ASSERT(reg1 >= 0);
|
|
||||||
|
|
||||||
reg2 = biv2->reg;
|
reg2 = biv2->reg;
|
||||||
#line 934
|
CError_ASSERT(934, reg2 >= 0);
|
||||||
CError_ASSERT(reg2 >= 0);
|
|
||||||
|
|
||||||
if (!FITS_IN_SHORT(difference))
|
if (!FITS_IN_SHORT(difference))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,792 @@
|
||||||
|
#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.optimize_for_size == 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);
|
||||||
|
}
|
|
@ -126,8 +126,7 @@ static void treecompare(SInt32 start, SInt32 end) {
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
count = end - start;
|
count = end - start;
|
||||||
#line 175
|
CError_ASSERT(175, selector_type->size <= 4);
|
||||||
CError_ASSERT(selector_type->size <= 4);
|
|
||||||
|
|
||||||
r29 = start + (count >> 1) + 1;
|
r29 = start + (count >> 1) + 1;
|
||||||
currange = caseranges + r29;
|
currange = caseranges + r29;
|
||||||
|
@ -398,8 +397,7 @@ static void generate_table(ENode *expr, SwitchInfo *info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
table = create_switch_table();
|
table = create_switch_table();
|
||||||
#line 553
|
CError_ASSERT(553, !TYPE_IS_8BYTES(expr->rtype));
|
||||||
CError_ASSERT(!TYPE_IS_8BYTES(expr->rtype));
|
|
||||||
|
|
||||||
GEN_NODE(expr, &op1);
|
GEN_NODE(expr, &op1);
|
||||||
if (expr->rtype->size < 4)
|
if (expr->rtype->size < 4)
|
||||||
|
@ -446,8 +444,7 @@ static void generate_table(ENode *expr, SwitchInfo *info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op2.optype != OpndType_GPR) {
|
if (op2.optype != OpndType_GPR) {
|
||||||
#line 599
|
CError_FATAL(599);
|
||||||
CError_FATAL();
|
|
||||||
} else {
|
} else {
|
||||||
if (op2.reg != reg2)
|
if (op2.reg != reg2)
|
||||||
emitpcode(PC_MR, reg2, op2.reg);
|
emitpcode(PC_MR, reg2, op2.reg);
|
||||||
|
@ -482,8 +479,7 @@ void switchstatement(ENode *expr, SwitchInfo *info) {
|
||||||
ncases++;
|
ncases++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 656
|
CError_ASSERT(656, ncases >= 0 && ncases <= 0x3333332U);
|
||||||
CError_ASSERT(ncases >= 0 && ncases <= 0x3333332U);
|
|
||||||
|
|
||||||
if (!info->defaultlabel->pclabel)
|
if (!info->defaultlabel->pclabel)
|
||||||
info->defaultlabel->pclabel = makepclabel();
|
info->defaultlabel->pclabel = makepclabel();
|
||||||
|
@ -510,8 +506,7 @@ void dumpswitchtables(Object *funcobj) {
|
||||||
|
|
||||||
for (list = switchtables; list; list = list->next) {
|
for (list = switchtables; list; list = list->next) {
|
||||||
table = list->object;
|
table = list->object;
|
||||||
#line 694
|
CError_ASSERT(694, table->otype == OT_OBJECT && table->access == ACCESSPUBLIC && table->datatype == DDATA);
|
||||||
CError_ASSERT(table->otype == OT_OBJECT && table->access == ACCESSPUBLIC && table->datatype == DDATA);
|
|
||||||
|
|
||||||
size = table->u.data.u.switchtable.size;
|
size = table->u.data.u.switchtable.size;
|
||||||
array = (UInt32 *) table->u.data.u.switchtable.data;
|
array = (UInt32 *) table->u.data.u.switchtable.data;
|
||||||
|
|
|
@ -2,16 +2,22 @@
|
||||||
#include "compiler/TOC.h"
|
#include "compiler/TOC.h"
|
||||||
#include "compiler/CDecl.h"
|
#include "compiler/CDecl.h"
|
||||||
#include "compiler/CError.h"
|
#include "compiler/CError.h"
|
||||||
|
#include "compiler/CExpr.h"
|
||||||
|
#include "compiler/CInit.h"
|
||||||
#include "compiler/CInt64.h"
|
#include "compiler/CInt64.h"
|
||||||
#include "compiler/CFunc.h"
|
#include "compiler/CFunc.h"
|
||||||
#include "compiler/CMachine.h"
|
#include "compiler/CMachine.h"
|
||||||
#include "compiler/CMangler.h"
|
#include "compiler/CMangler.h"
|
||||||
#include "compiler/CParser.h"
|
#include "compiler/CParser.h"
|
||||||
#include "compiler/CodeGen.h"
|
#include "compiler/CodeGen.h"
|
||||||
|
#include "compiler/Exceptions.h"
|
||||||
#include "compiler/InstrSelection.h"
|
#include "compiler/InstrSelection.h"
|
||||||
|
#include "compiler/ObjGenMachO.h"
|
||||||
#include "compiler/Operands.h"
|
#include "compiler/Operands.h"
|
||||||
#include "compiler/PCode.h"
|
#include "compiler/PCode.h"
|
||||||
#include "compiler/PCodeInfo.h"
|
#include "compiler/PCodeInfo.h"
|
||||||
|
#include "compiler/PPCError.h"
|
||||||
|
#include "compiler/RegisterInfo.h"
|
||||||
#include "compiler/StackFrame.h"
|
#include "compiler/StackFrame.h"
|
||||||
#include "compiler/CompilerTools.h"
|
#include "compiler/CompilerTools.h"
|
||||||
#include "compiler/enode.h"
|
#include "compiler/enode.h"
|
||||||
|
@ -142,8 +148,7 @@ void referenceIndirectPointer(Object *obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *createIndirect(Object *obj, Boolean flag1, Boolean flag2) {
|
Object *createIndirect(Object *obj, Boolean flag1, Boolean flag2) {
|
||||||
#line 622
|
CError_ASSERT(622, !copts.no_common || (obj->section != SECT_COMMON_VARS) || (obj->qual & Q_20000));
|
||||||
CError_ASSERT(!copts.no_common || (obj->section != SECT_COMMON_VARS) || (obj->qual & Q_20000));
|
|
||||||
|
|
||||||
if (CParser_HasInternalLinkage(obj))
|
if (CParser_HasInternalLinkage(obj))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -191,14 +196,12 @@ Object *createfloatconstant(Type *type, Float *data) {
|
||||||
obj->sclass = OBJECT_SCLASS_102;
|
obj->sclass = OBJECT_SCLASS_102;
|
||||||
obj->qual = Q_CONST | Q_10000;
|
obj->qual = Q_CONST | Q_10000;
|
||||||
obj->datatype = DDATA;
|
obj->datatype = DDATA;
|
||||||
if (type->size == 8) {
|
if (type->size == 8)
|
||||||
obj->section = SECT_8BYTE_LITERALS;
|
obj->section = SECT_8BYTE_LITERALS;
|
||||||
} else if (type->size == 4) {
|
else if (type->size == 4)
|
||||||
obj->section = SECT_4BYTE_LITERALS;
|
obj->section = SECT_4BYTE_LITERALS;
|
||||||
} else {
|
else
|
||||||
#line 807
|
CError_FATAL(807);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->flags |= OBJECT_FLAGS_2;
|
obj->flags |= OBJECT_FLAGS_2;
|
||||||
|
|
||||||
|
@ -238,12 +241,10 @@ Object *createvectorconstant(Type *type, MWVector128 *data) {
|
||||||
obj->sclass = OBJECT_SCLASS_102;
|
obj->sclass = OBJECT_SCLASS_102;
|
||||||
obj->qual = Q_CONST | Q_10000;
|
obj->qual = Q_CONST | Q_10000;
|
||||||
obj->datatype = DDATA;
|
obj->datatype = DDATA;
|
||||||
if (type->size == 16) {
|
if (type->size == 16)
|
||||||
obj->section = SECT_16BYTE_LITERALS;
|
obj->section = SECT_16BYTE_LITERALS;
|
||||||
} else {
|
else
|
||||||
#line 900
|
CError_FATAL(900);
|
||||||
CError_FATAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->flags |= OBJECT_FLAGS_2;
|
obj->flags |= OBJECT_FLAGS_2;
|
||||||
|
|
||||||
|
@ -542,8 +543,7 @@ static Type *common_type(Type *type1, Type *type2) {
|
||||||
if (type1 == (Type *) &stsignedlong) {
|
if (type1 == (Type *) &stsignedlong) {
|
||||||
type1 = (Type *) &stunsignedlong;
|
type1 = (Type *) &stunsignedlong;
|
||||||
} else {
|
} else {
|
||||||
#line 1789
|
CError_ASSERT(1789, type1 == (Type *) &stsignedlonglong);
|
||||||
CError_ASSERT(type1 == (Type *) &stsignedlonglong);
|
|
||||||
type1 = (Type *) &stunsignedlonglong;
|
type1 = (Type *) &stunsignedlonglong;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1016,8 +1016,7 @@ static Boolean DetectCondSideAffect(ENode *expr) {
|
||||||
case ECONDASS:
|
case ECONDASS:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
#line 2523
|
CError_FATAL(2523);
|
||||||
CError_FATAL();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1261,8 +1260,7 @@ void Optimize64bitMath(ENode *expr) {
|
||||||
SInt32 totalsize; // r22
|
SInt32 totalsize; // r22
|
||||||
int unsignedflag; // r4
|
int unsignedflag; // r4
|
||||||
|
|
||||||
#line 2886
|
CError_ASSERT(2886, TYPE_IS_8BYTES(expr->rtype));
|
||||||
CError_ASSERT(TYPE_IS_8BYTES(expr->rtype));
|
|
||||||
|
|
||||||
left = expr->data.diadic.left;
|
left = expr->data.diadic.left;
|
||||||
right = expr->data.diadic.right;
|
right = expr->data.diadic.right;
|
||||||
|
@ -1312,8 +1310,7 @@ void Optimize64bitMath(ENode *expr) {
|
||||||
case 16:
|
case 16:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#line 2975
|
CError_FATAL(2975);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1382,8 +1379,7 @@ static Boolean OptimizeNestedAssginments(ENode **pexpr, Object *check) {
|
||||||
case EANDASS:
|
case EANDASS:
|
||||||
case EXORASS:
|
case EXORASS:
|
||||||
case EORASS:
|
case EORASS:
|
||||||
#line 3033
|
CError_FATAL(3033);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (OptimizeNestedAssginments(&expr->data.diadic.right, check))
|
if (OptimizeNestedAssginments(&expr->data.diadic.right, check))
|
||||||
|
@ -1431,8 +1427,7 @@ static Boolean OptimizeNestedAssginments(ENode **pexpr, Object *check) {
|
||||||
case EASSBLK:
|
case EASSBLK:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
#line 3083
|
CError_FATAL(3083);
|
||||||
CError_FATAL();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1469,8 +1464,7 @@ static void expandTOCexpression(ENode *expr, Type *type, int ignored) {
|
||||||
break;
|
break;
|
||||||
case EOBJREF:
|
case EOBJREF:
|
||||||
obj = expr->data.objref;
|
obj = expr->data.objref;
|
||||||
#line 3203
|
CError_ASSERT(3203, obj->datatype != DALIAS);
|
||||||
CError_ASSERT(obj->datatype != DALIAS);
|
|
||||||
if (obj->datatype == DFUNC || obj->datatype == DVFUNC)
|
if (obj->datatype == DFUNC || obj->datatype == DVFUNC)
|
||||||
uses_globals = 1;
|
uses_globals = 1;
|
||||||
if (obj->datatype == DDATA) {
|
if (obj->datatype == DDATA) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -260,8 +260,7 @@ static int matchvalues(AvailableValue *av, PCode *match) {
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case PCOp_SYSREG:
|
case PCOp_SYSREG:
|
||||||
#line 572
|
CError_FATAL(572);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,13 +510,11 @@ static void functioncall(PCode *pcode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void operatefrommemory(PCode *pcode) {
|
static void operatefrommemory(PCode *pcode) {
|
||||||
#line 980
|
CError_FATAL(980);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void operatetomemory(PCode *pcode) {
|
static void operatetomemory(PCode *pcode) {
|
||||||
#line 1011
|
CError_FATAL(1011);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void propagatecopiesto(PCode *pcode) {
|
static void propagatecopiesto(PCode *pcode) {
|
||||||
|
|
|
@ -442,8 +442,7 @@ static void convert_array_to_register(LocalVectorArray *arrays, int addiID) {
|
||||||
useInstr->args[0].data.reg.reg = newReg;
|
useInstr->args[0].data.reg.reg = newReg;
|
||||||
useInstr->args[0].data.reg.effect = EffectWrite;
|
useInstr->args[0].data.reg.effect = EffectWrite;
|
||||||
} else {
|
} else {
|
||||||
#line 661
|
CError_FATAL(661);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deletepcode(addi->instr);
|
deletepcode(addi->instr);
|
||||||
|
|
|
@ -0,0 +1,639 @@
|
||||||
|
#include "compiler/uDump.h"
|
||||||
|
#include "compiler/CFunc.h"
|
||||||
|
#include "compiler/CInt64.h"
|
||||||
|
#include "compiler/CMachine.h"
|
||||||
|
#include "compiler/CMangler.h"
|
||||||
|
#include "compiler/Exceptions.h"
|
||||||
|
#include "compiler/Switch.h"
|
||||||
|
#include "compiler/enode.h"
|
||||||
|
#include "compiler/objects.h"
|
||||||
|
#include "compiler/types.h"
|
||||||
|
|
||||||
|
static FILE *outfile;
|
||||||
|
|
||||||
|
// forward decls
|
||||||
|
static void spell(Type *type, char *buf);
|
||||||
|
|
||||||
|
static void WritePString(FILE *file, char *str, int len) {
|
||||||
|
while (len--) {
|
||||||
|
switch (*str) {
|
||||||
|
case 0:
|
||||||
|
fputs("\\x00", file);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
fputs("\\a", file);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
fputs("\\b", file);
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
fputs("\\f", file);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
fputs("\\n", file);
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
fputs("\\r", file);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
fputs("\\t", file);
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
fputs("\\v", file);
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '?':
|
||||||
|
case '\\':
|
||||||
|
fputc('\\', file);
|
||||||
|
default:
|
||||||
|
fputc(*str, file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteCString(FILE *file, char *str) {
|
||||||
|
WritePString(file, str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StaticSetupDumpIR(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupDumpIR(void) {
|
||||||
|
// unknown args
|
||||||
|
StaticSetupDumpIR();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupDumpIR(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpIR(Statement *statements, Object *func) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpExpression(ENode *expr, int indent) {
|
||||||
|
static int bt;
|
||||||
|
static int i;
|
||||||
|
static char *nodenames[] = {
|
||||||
|
"EPOSTINC",
|
||||||
|
"EPOSTDEC",
|
||||||
|
"EPREINC",
|
||||||
|
"EPREDEC",
|
||||||
|
"EINDIRECT",
|
||||||
|
"EMONMIN",
|
||||||
|
"EBINNOT",
|
||||||
|
"ELOGNOT",
|
||||||
|
"EFORCELOAD",
|
||||||
|
"EMUL",
|
||||||
|
"EMULV",
|
||||||
|
"EDIV",
|
||||||
|
"EMODULO",
|
||||||
|
"EADDV",
|
||||||
|
"ESUBV",
|
||||||
|
"EADD",
|
||||||
|
"ESUB",
|
||||||
|
"ESHL",
|
||||||
|
"ESHR",
|
||||||
|
"ELESS",
|
||||||
|
"EGREATER",
|
||||||
|
"ELESSEQU",
|
||||||
|
"EGREATEREQU",
|
||||||
|
"EEQU",
|
||||||
|
"ENOTEQU",
|
||||||
|
"EAND",
|
||||||
|
"EXOR",
|
||||||
|
"EOR",
|
||||||
|
"ELAND",
|
||||||
|
"ELOR",
|
||||||
|
"EASS",
|
||||||
|
"EMULASS",
|
||||||
|
"EDIVASS",
|
||||||
|
"EMODASS",
|
||||||
|
"EADDASS",
|
||||||
|
"ESUBASS",
|
||||||
|
"ESHLASS",
|
||||||
|
"ESHRASS",
|
||||||
|
"EANDASS",
|
||||||
|
"EXORASS",
|
||||||
|
"EORASS",
|
||||||
|
"ECOMMA",
|
||||||
|
"EPMODULO",
|
||||||
|
"EROTL",
|
||||||
|
"EROTR",
|
||||||
|
"EBCLR",
|
||||||
|
"EBTST",
|
||||||
|
"EBSET",
|
||||||
|
"ETYPCON",
|
||||||
|
"EBITFIELD",
|
||||||
|
"EINTCONST",
|
||||||
|
"EFLOATCONST",
|
||||||
|
"ESTRINGCONST",
|
||||||
|
"ECOND",
|
||||||
|
"EFUNCCALL",
|
||||||
|
"EFUNCCALLP",
|
||||||
|
"EOBJREF",
|
||||||
|
"EMFPOINTER",
|
||||||
|
"ENULLCHECK",
|
||||||
|
"EPRECOMP",
|
||||||
|
"ETEMP",
|
||||||
|
"EARGOBJ",
|
||||||
|
"ELOCOBJ",
|
||||||
|
"ELABEL",
|
||||||
|
"ESETCONST",
|
||||||
|
"ENEWEXCEPTION",
|
||||||
|
"ENEWEXCEPTIONARRAY",
|
||||||
|
"EINITTRYCATCH",
|
||||||
|
"EOBJLIST",
|
||||||
|
"EMEMBER",
|
||||||
|
"ETEMPLDEP",
|
||||||
|
"EINSTRUCTION",
|
||||||
|
"EDEFINE",
|
||||||
|
"EREUSE",
|
||||||
|
"EASSBLK",
|
||||||
|
"EVECTOR128CONST",
|
||||||
|
"ECONDASS",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
char buf[64];
|
||||||
|
ENodeList *list;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
for (i = 0; i < indent; i++)
|
||||||
|
fputc('\t', outfile);
|
||||||
|
|
||||||
|
if (expr->flags)
|
||||||
|
fprintf(outfile, "%s {%02X}", nodenames[expr->type], expr->flags);
|
||||||
|
else
|
||||||
|
fprintf(outfile, "%s", nodenames[expr->type]);
|
||||||
|
|
||||||
|
switch (expr->type) {
|
||||||
|
case EINTCONST:
|
||||||
|
if (expr->rtype->size > 4)
|
||||||
|
fprintf(outfile, "[0x%.8lX%.8lX]", expr->data.intval.hi, expr->data.intval.lo);
|
||||||
|
else
|
||||||
|
fprintf(outfile, "[%ld]", expr->data.intval.lo);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EFLOATCONST:
|
||||||
|
CMach_PrintFloat(buf, expr->data.floatval);
|
||||||
|
fprintf(outfile, "[%s]", buf);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ESTRINGCONST:
|
||||||
|
if (expr->data.string.ispascal) {
|
||||||
|
fputs("[\"", outfile);
|
||||||
|
WritePString(outfile, expr->data.string.data, expr->data.string.size);
|
||||||
|
fputs("\"]", outfile);
|
||||||
|
} else {
|
||||||
|
fputs("[\"", outfile);
|
||||||
|
WriteCString(outfile, expr->data.string.data);
|
||||||
|
fputs("\"]", outfile);
|
||||||
|
}
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVECTOR128CONST:
|
||||||
|
fprintf(outfile, "[0x%.8lX%.8lX%.8lX%.8lX]",
|
||||||
|
expr->data.vector128val.ul[0],
|
||||||
|
expr->data.vector128val.ul[1],
|
||||||
|
expr->data.vector128val.ul[2],
|
||||||
|
expr->data.vector128val.ul[3]);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ECOND:
|
||||||
|
case ECONDASS:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
DumpExpression(expr->data.cond.cond, indent + 1);
|
||||||
|
DumpExpression(expr->data.cond.expr1, indent + 1);
|
||||||
|
expr = expr->data.cond.expr2;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFUNCCALL:
|
||||||
|
case EFUNCCALLP:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
DumpExpression(expr->data.funccall.funcref, indent + 1);
|
||||||
|
for (list = expr->data.funccall.args; list; list = list->next)
|
||||||
|
DumpExpression(list->node, indent + 1);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EOBJREF:
|
||||||
|
switch (expr->data.objref->datatype) {
|
||||||
|
case DFUNC:
|
||||||
|
fprintf(outfile, "[%s{PR}]", CMangler_GetLinkName(expr->data.objref)->name);
|
||||||
|
break;
|
||||||
|
case DDATA:
|
||||||
|
fprintf(outfile, "[%s{RW}]", CMangler_GetLinkName(expr->data.objref)->name);
|
||||||
|
break;
|
||||||
|
case DNONLAZYPTR:
|
||||||
|
fprintf(outfile, "[%s{NL}]", CMangler_GetLinkName(expr->data.objref)->name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(outfile, "[%s]", expr->data.objref->name->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
ENODE_CASE_DIADIC_1:
|
||||||
|
case ELAND:
|
||||||
|
case ELOR:
|
||||||
|
ENODE_CASE_ASSIGN:
|
||||||
|
case ECOMMA:
|
||||||
|
case EPMODULO:
|
||||||
|
case EROTL:
|
||||||
|
case EROTR:
|
||||||
|
case EBTST:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
DumpExpression(expr->data.diadic.left, indent + 1);
|
||||||
|
expr = expr->data.diadic.right;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
ENODE_CASE_MONADIC:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
expr = expr->data.monadic;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EMFPOINTER:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
DumpExpression(expr->data.mfpointer.accessnode, indent + 1);
|
||||||
|
expr = expr->data.mfpointer.mfpointer;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENULLCHECK:
|
||||||
|
fprintf(outfile, " unique [%ld]", expr->data.nullcheck.precompid);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
DumpExpression(expr->data.nullcheck.nullcheckexpr, indent + 1);
|
||||||
|
expr = expr->data.nullcheck.condexpr;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EPRECOMP:
|
||||||
|
fprintf(outfile, " unique [%ld]", expr->data.precompid);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ELABEL:
|
||||||
|
fprintf(outfile, "[%s]", expr->data.label->uniquename->name);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ETEMP:
|
||||||
|
DumpType(expr->data.temp.type);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EINITTRYCATCH:
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fprintf(outfile, "\r");
|
||||||
|
if (expr->data.itc.initexpr)
|
||||||
|
DumpExpression(expr->data.itc.initexpr, indent + 1);
|
||||||
|
if (expr->data.itc.tryexpr)
|
||||||
|
DumpExpression(expr->data.itc.tryexpr, indent + 1);
|
||||||
|
if (expr->data.itc.catchexpr)
|
||||||
|
DumpExpression(expr->data.itc.catchexpr, indent + 1);
|
||||||
|
if (expr->data.itc.result)
|
||||||
|
DumpExpression(expr->data.itc.result, indent + 1);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EDEFINE:
|
||||||
|
fprintf(outfile, "[%.8lX]", expr);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fputs("\r", outfile);
|
||||||
|
expr = expr->data.monadic;
|
||||||
|
indent++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EREUSE:
|
||||||
|
fprintf(outfile, "[%.8lX]", expr->data.monadic);
|
||||||
|
DumpType(expr->rtype);
|
||||||
|
fputs("\r", outfile);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpSwitch(SwitchInfo *info) {
|
||||||
|
char buf[32];
|
||||||
|
SwitchCase *cs;
|
||||||
|
|
||||||
|
for (cs = info->cases; cs; cs = cs->next) {
|
||||||
|
CInt64_PrintDec(buf, cs->min);
|
||||||
|
CInt64_PrintDec(buf, cs->min);
|
||||||
|
fprintf(outfile, "\t\t%11s: %s\r", buf, cs->label->uniquename->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(outfile, "\t\t default: %s\r", info->defaultlabel->uniquename->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpType(Type *type) {
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
spell(type, buf);
|
||||||
|
fprintf(outfile, " (%s)", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spell(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)) {
|
||||||
|
switch (TYPE_STRUCT(type)->stype) {
|
||||||
|
case STRUCT_TYPE_4:
|
||||||
|
strcpy(buf, "vector unsigned char ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_5:
|
||||||
|
strcpy(buf, "vector signed char ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_6:
|
||||||
|
strcpy(buf, "vector bool char ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_7:
|
||||||
|
strcpy(buf, "vector unsigned short ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_8:
|
||||||
|
strcpy(buf, "vector signed short ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_9:
|
||||||
|
strcpy(buf, "vector bool short ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_A:
|
||||||
|
strcpy(buf, "vector unsigned int ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_B:
|
||||||
|
strcpy(buf, "vector signed int ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_C:
|
||||||
|
strcpy(buf, "vector bool int ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_D:
|
||||||
|
strcpy(buf, "vector float ");
|
||||||
|
break;
|
||||||
|
case STRUCT_TYPE_E:
|
||||||
|
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:
|
||||||
|
spell(TYPE_FUNC(type)->functype, mybuf);
|
||||||
|
strcpy(buf, "freturns(");
|
||||||
|
strcat(buf, mybuf);
|
||||||
|
strcat(buf, ")");
|
||||||
|
break;
|
||||||
|
case TYPEBITFIELD:
|
||||||
|
spell(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
|
||||||
|
sprintf(buf,
|
||||||
|
"bitfield(%s){%d:%d}",
|
||||||
|
mybuf,
|
||||||
|
TYPE_BITFIELD(type)->unkA,
|
||||||
|
TYPE_BITFIELD(type)->unkB);
|
||||||
|
break;
|
||||||
|
case TYPELABEL:
|
||||||
|
strcpy(buf, "label");
|
||||||
|
break;
|
||||||
|
case TYPEPOINTER:
|
||||||
|
spell(TPTR_TARGET(type), mybuf);
|
||||||
|
strcpy(buf, "pointer(");
|
||||||
|
strcat(buf, mybuf);
|
||||||
|
strcat(buf, ")");
|
||||||
|
break;
|
||||||
|
case TYPEARRAY:
|
||||||
|
spell(TPTR_TARGET(type), mybuf);
|
||||||
|
strcpy(buf, "array(");
|
||||||
|
strcat(buf, mybuf);
|
||||||
|
strcat(buf, ")");
|
||||||
|
break;
|
||||||
|
case TYPEMEMBERPOINTER:
|
||||||
|
spell(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
|
||||||
|
spell(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
|
||||||
|
strcpy(buf, "memberpointer(");
|
||||||
|
strcat(buf, mybuf);
|
||||||
|
strcat(buf, ",");
|
||||||
|
strcat(buf, mybuf2);
|
||||||
|
strcat(buf, ")");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpStack(ExceptionAction *act) {
|
||||||
|
while (act) {
|
||||||
|
fprintf(outfile, "\t\t:");
|
||||||
|
switch (act->type) {
|
||||||
|
case EAT_DESTROYLOCAL:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYLOCAL %s(&%s)%s",
|
||||||
|
CMangler_GetLinkName(act->data.destroy_local.dtor)->name,
|
||||||
|
act->data.destroy_local.local->name->name,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYLOCALCOND:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYLOCALCOND%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYLOCALOFFSET:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYLOCALOFFSET %s(&%s+%ld)%s",
|
||||||
|
CMangler_GetLinkName(act->data.destroy_local_offset.dtor)->name,
|
||||||
|
act->data.destroy_local_offset.local->name->name,
|
||||||
|
act->data.destroy_local_offset.offset,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYLOCALPOINTER:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYLOCALPOINTER%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYLOCALARRAY:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYLOCALARRAY%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYBASE:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYBASE %s(this+%ld)%s",
|
||||||
|
CMangler_GetLinkName(act->data.destroy_base.dtor)->name,
|
||||||
|
act->data.destroy_base.offset,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYMEMBER:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYMEMBER %s(%s+%ld)%s",
|
||||||
|
CMangler_GetLinkName(act->data.destroy_member.dtor)->name,
|
||||||
|
act->data.destroy_member.objectptr->name->name,
|
||||||
|
act->data.destroy_member.offset,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYMEMBERCOND:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYMEMBERCOND if(%s) %s(this+%ld)%s",
|
||||||
|
act->data.destroy_member_cond.cond->name->name,
|
||||||
|
CMangler_GetLinkName(act->data.destroy_member_cond.dtor)->name,
|
||||||
|
act->data.destroy_member_cond.offset,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DESTROYMEMBERARRAY:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DESTROYMEMBERARRAY %s(this+%ld)[%ld] size: %ld%s",
|
||||||
|
CMangler_GetLinkName(act->data.destroy_member_array.dtor)->name,
|
||||||
|
act->data.destroy_member_array.offset,
|
||||||
|
act->data.destroy_member_array.elements,
|
||||||
|
act->data.destroy_member_array.element_size,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DELETEPOINTER:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DELETEPOINTER(%s)%s",
|
||||||
|
act->data.delete_pointer.pointerobject->name->name,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DELETELOCALPOINTER:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DELETELOCALPOINTER(%s)%s",
|
||||||
|
act->data.delete_pointer.pointerobject->name->name,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_DELETEPOINTERCOND:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_DELETEPOINTERCOND if (%s)(%s)%s",
|
||||||
|
act->data.delete_pointer_cond.cond->name->name,
|
||||||
|
act->data.delete_pointer_cond.pointerobject->name->name,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_CATCHBLOCK:
|
||||||
|
fprintf(outfile, "EAT_CATCHBLOCK ");
|
||||||
|
if (act->data.catch_block.catch_type) {
|
||||||
|
if (act->data.catch_block.catch_object)
|
||||||
|
fprintf(outfile, "[%s]", act->data.catch_block.catch_object->name->name);
|
||||||
|
else
|
||||||
|
fprintf(outfile, "[]");
|
||||||
|
DumpType(act->data.catch_block.catch_type);
|
||||||
|
} else {
|
||||||
|
fprintf(outfile, "[...] ");
|
||||||
|
}
|
||||||
|
fprintf(outfile,
|
||||||
|
" Label: %s%s",
|
||||||
|
act->data.catch_block.catch_label->uniquename->name,
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_SPECIFICATION:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_SPECIFICATION%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_ACTIVECATCHBLOCK:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_ACTIVECATCHBLOCK%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
case EAT_TERMINATE:
|
||||||
|
fprintf(outfile,
|
||||||
|
"EAT_TERMINATE%s",
|
||||||
|
"\r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
act = act->prev;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,8 +27,7 @@ inline void Bv_SetBit(UInt32 bit, BitVector *bv) {
|
||||||
if ((bit / 32) < bv->size) {
|
if ((bit / 32) < bv->size) {
|
||||||
bv->data[bit / 32] |= 1 << (bit & 31);
|
bv->data[bit / 32] |= 1 << (bit & 31);
|
||||||
} else {
|
} else {
|
||||||
#line 56
|
CError_FATAL(56);
|
||||||
CError_FATAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ extern void CABI_ReverseBitField(TypeBitfield *tbitfield);
|
||||||
extern void CABI_AddVTable(TypeClass *tclass);
|
extern void CABI_AddVTable(TypeClass *tclass);
|
||||||
extern SInt32 CABI_GetVTableOffset(TypeClass *tclass);
|
extern SInt32 CABI_GetVTableOffset(TypeClass *tclass);
|
||||||
extern void CABI_LayoutClass(DeclE *decle, TypeClass *tclass);
|
extern void CABI_LayoutClass(DeclE *decle, TypeClass *tclass);
|
||||||
extern void CABI_MakeDefaultArgConstructor(Object *obj, TypeClass *tclass);
|
extern void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *obj);
|
||||||
extern ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset);
|
extern ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset);
|
||||||
extern SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base);
|
extern SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base);
|
||||||
extern Object *CABI_ConstructorCallsNew(TypeClass *tclass);
|
extern Object *CABI_ConstructorCallsNew(TypeClass *tclass);
|
||||||
|
|
|
@ -3,4 +3,28 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern Boolean gUseTokenStreamSource;
|
||||||
|
extern Boolean gForceSourceLoc;
|
||||||
|
extern Boolean gUseNameTable;
|
||||||
|
|
||||||
|
extern void CBrowse_Setup(CParams *params);
|
||||||
|
extern void CBrowse_Finish(CParams *params);
|
||||||
|
extern void CBrowse_Cleanup(CParams *params);
|
||||||
|
extern void CBrowse_BeginClass(DeclInfo *di, GList *gl);
|
||||||
|
extern void CBrowse_AddClassMemberVar(ObjMemberVar *ivar, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_AddClassMemberFunction(Object *object, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_AddClassMemberData(Object *object, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_EndClass(SInt32 offset, GList *gl);
|
||||||
|
extern void CBrowse_BeginStruct(DeclInfo *di, TypeStruct *tstruct, GList *gl);
|
||||||
|
extern void CBrowse_AddStructMember(StructMember *member, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_EndStruct(SInt32 offset, GList *gl);
|
||||||
|
extern void CBrowse_NewTypedef(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewEnum(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewEnumConstant(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewFunction(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewData(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewMacro(Macro *macro, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewTemplateClass(TemplClass *tmclass, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset);
|
||||||
|
extern void CBrowse_NewTemplateFunc(TemplateFunction *tmfunc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,13 +10,19 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// named because it's 0xE bytes big (hurr)
|
// named because it's 0xE bytes big (hurr)
|
||||||
typedef struct DeclE {
|
struct DeclE {
|
||||||
ObjBase **objlist;
|
ObjBase **objlist;
|
||||||
void *x4;
|
void *x4;
|
||||||
unsigned short x8;
|
unsigned short x8; // lex_order_count?
|
||||||
unsigned short xA;
|
unsigned short xA;
|
||||||
Boolean xC;
|
Boolean xC;
|
||||||
} DeclE;
|
};
|
||||||
|
|
||||||
|
// what the fuck am I?
|
||||||
|
struct DeclFucker {
|
||||||
|
NameSpace *nspace;
|
||||||
|
void *mystery4;
|
||||||
|
};
|
||||||
|
|
||||||
struct DeclInfo {
|
struct DeclInfo {
|
||||||
Type *thetype;
|
Type *thetype;
|
||||||
|
@ -31,10 +37,10 @@ struct DeclInfo {
|
||||||
ENode *x24;
|
ENode *x24;
|
||||||
TemplClass *x28;
|
TemplClass *x28;
|
||||||
TemplArg *expltargs;
|
TemplArg *expltargs;
|
||||||
void *x30;
|
TemplParam *x30;
|
||||||
void *x34;
|
DeclFucker *fucker34;
|
||||||
void *x38;
|
TemplateFunction *x38;
|
||||||
Boolean x3C;
|
UInt8 x3C; // related to template nindex
|
||||||
Boolean x3D;
|
Boolean x3D;
|
||||||
short x3E;
|
short x3E;
|
||||||
short storageclass;
|
short storageclass;
|
||||||
|
@ -46,7 +52,7 @@ struct DeclInfo {
|
||||||
Boolean x47;
|
Boolean x47;
|
||||||
Boolean x48;
|
Boolean x48;
|
||||||
Boolean x49;
|
Boolean x49;
|
||||||
Boolean x4A;
|
Boolean x4A; // objc related
|
||||||
Boolean x4B;
|
Boolean x4B;
|
||||||
Boolean x4C;
|
Boolean x4C;
|
||||||
Boolean x4D;
|
Boolean x4D;
|
||||||
|
@ -60,7 +66,11 @@ struct DeclInfo {
|
||||||
Boolean x55;
|
Boolean x55;
|
||||||
Boolean x56;
|
Boolean x56;
|
||||||
Boolean x57;
|
Boolean x57;
|
||||||
FileOffsetInfo fileoffsetinfo;
|
//FileOffsetInfo fileoffsetinfo;
|
||||||
|
CPrepFileInfo *file;
|
||||||
|
CPrepFileInfo *file2;
|
||||||
|
SInt32 x60; // file offset?
|
||||||
|
short x64;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BigDeclInfo {
|
typedef struct BigDeclInfo {
|
||||||
|
@ -113,7 +123,7 @@ extern void CDecl_UnpackDeclInfo(DeclInfo *declinfo, PackedDeclInfo *packed);
|
||||||
extern void CDecl_AddFriend(TypeClass *tclass, Object *friendfunc, TypeClass *friendclass);
|
extern void CDecl_AddFriend(TypeClass *tclass, Object *friendfunc, TypeClass *friendclass);
|
||||||
extern void CDecl_CheckCtorIntegrity(FuncArg *args, TypeClass *tclass);
|
extern void CDecl_CheckCtorIntegrity(FuncArg *args, TypeClass *tclass);
|
||||||
extern void CDecl_MakeVBaseList(TypeClass *tclass);
|
extern void CDecl_MakeVBaseList(TypeClass *tclass);
|
||||||
extern Boolean CDecl_CheckNewBase(TypeClass *a, TypeClass *b, Boolean flag);
|
extern Boolean CDecl_CheckNewBase(TypeClass *tclass, TypeClass *baseclass, Boolean is_virtual);
|
||||||
extern TypeMethod *CDecl_MakeDefaultDtorType(TypeClass *tclass, Boolean is_virtual);
|
extern TypeMethod *CDecl_MakeDefaultDtorType(TypeClass *tclass, Boolean is_virtual);
|
||||||
extern void CDecl_CompleteClass(DeclE *decle, TypeClass *tclass);
|
extern void CDecl_CompleteClass(DeclE *decle, TypeClass *tclass);
|
||||||
extern TypeClass *CDecl_DefineClass(NameSpace *nspace, HashNameNode *name, TypeClass *tclass, short mode, Boolean flag2, Boolean flag3);
|
extern TypeClass *CDecl_DefineClass(NameSpace *nspace, HashNameNode *name, TypeClass *tclass, short mode, Boolean flag2, Boolean flag3);
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
#define CError_ASSERT(cond) if (!(cond)) { CError_Internal(__FILE__, __LINE__); }
|
#define CError_ASSERT(line, cond) if (!(cond)) { CError_Internal(__FILE__, line); }
|
||||||
#define CError_FAIL(cond) if (cond) { CError_Internal(__FILE__, __LINE__); }
|
#define CError_FAIL(line, cond) if (cond) { CError_Internal(__FILE__, line); }
|
||||||
#define CError_FATAL() do { CError_Internal(__FILE__, __LINE__); } while (0)
|
#define CError_FATAL(line) do { CError_Internal(__FILE__, line); } while (0)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CErrorStr100 = 100,
|
CErrorStr100 = 100,
|
||||||
|
|
|
@ -3,7 +3,29 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
// TODO
|
extern ExceptionAction *cexcept_dobjstack;
|
||||||
extern Boolean CExcept_CanThrowException(Object *obj, Boolean flag);
|
extern Boolean cexcept_hasdobjects;
|
||||||
|
extern Boolean cexcept_magic;
|
||||||
|
|
||||||
|
extern void CExcept_Setup(void);
|
||||||
|
extern Boolean CExcept_CanThrowException(Object *object, Boolean flag);
|
||||||
|
extern void CExcept_CheckStackRefs(ExceptionAction *actions);
|
||||||
|
extern void CExcept_CompareSpecifications(ExceptSpecList *a, ExceptSpecList *b);
|
||||||
|
extern Boolean CExcept_ActionCompare(ExceptionAction *a, ExceptionAction *b);
|
||||||
|
extern int CExcept_IsSubList(ExceptionAction *a, ExceptionAction *b);
|
||||||
|
extern Boolean CExcept_ActionNeedsDestruction(ExceptionAction *action);
|
||||||
|
extern ENode *CExcept_RegisterDestructorObject(Object *local, SInt32 offset, Object *dtor, Boolean flag);
|
||||||
|
extern void CExcept_RegisterLocalArray(Statement *stmt, Object *localarray, Object *dtor, SInt32 elements, SInt32 element_size);
|
||||||
|
extern void CExcept_RegisterDeleteObject(Statement *stmt, Object *pointerobject, Object *deletefunc);
|
||||||
|
extern void CExcept_Terminate(void);
|
||||||
|
extern void CExcept_Magic(void);
|
||||||
|
extern void CExcept_ArrayInit(void);
|
||||||
|
extern void CExcept_RegisterMember(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, Object *cond, Boolean isMember);
|
||||||
|
extern void CExcept_RegisterMemberArray(Statement *stmt, Object *objectptr, SInt32 offset, Object *dtor, SInt32 elements, SInt32 element_size);
|
||||||
|
extern Statement *CExcept_ActionCleanup(ExceptionAction *ea, Statement *stmt);
|
||||||
|
extern void CExcept_ScanExceptionSpecification(TypeFunc *tfunc);
|
||||||
|
extern ENode *CExcept_ScanThrowExpression(void);
|
||||||
|
extern void CExcept_ScanTryBlock(DeclThing *dt, Boolean flag);
|
||||||
|
extern void CExcept_ExceptionTansform(Statement *stmt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,6 +48,7 @@ typedef enum StatementType {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
StmtFlag_1 = 1,
|
StmtFlag_1 = 1,
|
||||||
|
StmtFlag_2 = 2,
|
||||||
StmtFlag_8 = 8,
|
StmtFlag_8 = 8,
|
||||||
StmtFlag_10 = 0x10
|
StmtFlag_10 = 0x10
|
||||||
};
|
};
|
||||||
|
@ -139,7 +140,7 @@ extern void CFunc_DestructorCleanup(Statement *stmt);
|
||||||
extern Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *));
|
extern Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *));
|
||||||
extern void CFunc_CompoundStatement(DeclThing *thing);
|
extern void CFunc_CompoundStatement(DeclThing *thing);
|
||||||
extern void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args);
|
extern void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args);
|
||||||
extern NameSpace *CFunc_FuncGenSetup(Statement *stmt);
|
extern NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func);
|
||||||
extern void CFunc_GetGlobalCompilerState(CFuncSave *state);
|
extern void CFunc_GetGlobalCompilerState(CFuncSave *state);
|
||||||
extern void CFunc_SetGlobalCompilerState(CFuncSave *state);
|
extern void CFunc_SetGlobalCompilerState(CFuncSave *state);
|
||||||
extern void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk);
|
extern void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk);
|
||||||
|
|
|
@ -3,4 +3,9 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern void CIRTrans_Setup(void);
|
||||||
|
extern void CIRTrans_Cleanup(void);
|
||||||
|
extern ENode *CIRTrans_TransformOpAss(ENode *expr);
|
||||||
|
extern void CIRTrans_Transform(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,12 +14,12 @@ typedef void (*InsertExprCB)(ENode *expr);
|
||||||
typedef ENode *(*RegisterObjectCB)(Type *type, Object *obj, SInt32 offset, void *);
|
typedef ENode *(*RegisterObjectCB)(Type *type, Object *obj, SInt32 offset, void *);
|
||||||
typedef ENode *(*TempNodeCB)(Type *type, Boolean flag);
|
typedef ENode *(*TempNodeCB)(Type *type, Boolean flag);
|
||||||
|
|
||||||
typedef struct OLinkList {
|
struct OLinkList {
|
||||||
struct OLinkList *next;
|
OLinkList *next;
|
||||||
Object *obj;
|
Object *obj; // the object containing a relocation
|
||||||
SInt32 offset;
|
SInt32 offset;
|
||||||
SInt32 somevalue;
|
SInt32 somevalue;
|
||||||
} OLinkList;
|
};
|
||||||
|
|
||||||
typedef struct PooledString {
|
typedef struct PooledString {
|
||||||
struct PooledString *next;
|
struct PooledString *next;
|
||||||
|
|
|
@ -14,12 +14,29 @@ typedef struct CI_Var {
|
||||||
Type *type;
|
Type *type;
|
||||||
UInt32 qual;
|
UInt32 qual;
|
||||||
UInt8 sflags;
|
UInt8 sflags;
|
||||||
UInt8 xD;
|
SInt8 xD;
|
||||||
UInt8 xE;
|
SInt8 xE;
|
||||||
} CI_Var;
|
} CI_Var;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CI_SFLAGS_NoClass = 0,
|
||||||
|
CI_SFLAGS_Register = 1,
|
||||||
|
CI_SFLAGS_Auto = 2,
|
||||||
|
CI_SFLAGS_HasObjectFlag2 = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct CI_SwitchCase {
|
||||||
|
short labelID;
|
||||||
|
CInt64 min;
|
||||||
|
CInt64 max;
|
||||||
|
} CI_SwitchCase;
|
||||||
|
|
||||||
typedef struct CI_Switch {
|
typedef struct CI_Switch {
|
||||||
int fix_me;
|
ENode *expr;
|
||||||
|
void *unkSwitch8;
|
||||||
|
short defaultlabelID;
|
||||||
|
short numcases;
|
||||||
|
CI_SwitchCase cases[0];
|
||||||
} CI_Switch;
|
} CI_Switch;
|
||||||
|
|
||||||
typedef struct CI_Statement {
|
typedef struct CI_Statement {
|
||||||
|
@ -37,10 +54,23 @@ typedef struct CI_Statement {
|
||||||
SInt16 statementnum;
|
SInt16 statementnum;
|
||||||
} ifgoto;
|
} ifgoto;
|
||||||
CI_Switch *switchdata;
|
CI_Switch *switchdata;
|
||||||
// TODO: Figure out the one for Inline ASM
|
struct {
|
||||||
|
void *data;
|
||||||
|
SInt32 size;
|
||||||
|
} asmdata;
|
||||||
} u;
|
} u;
|
||||||
} CI_Statement;
|
} CI_Statement;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CI_CanInline0,
|
||||||
|
CI_CanInline1,
|
||||||
|
CI_CanInline2,
|
||||||
|
CI_CanInline3,
|
||||||
|
CI_CanInline4,
|
||||||
|
CI_CanInline5,
|
||||||
|
CI_CanInline6
|
||||||
|
} CI_CanInline;
|
||||||
|
|
||||||
struct CI_FuncData {
|
struct CI_FuncData {
|
||||||
short numarguments;
|
short numarguments;
|
||||||
CI_Var *arguments;
|
CI_Var *arguments;
|
||||||
|
@ -53,7 +83,7 @@ struct CI_FuncData {
|
||||||
SInt32 functionbodyoffset;
|
SInt32 functionbodyoffset;
|
||||||
HashNameNode *functionbodypath;
|
HashNameNode *functionbodypath;
|
||||||
SInt32 symdeclend;
|
SInt32 symdeclend;
|
||||||
Boolean can_inline;
|
UInt8 can_inline;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -71,11 +101,10 @@ typedef struct CI_Action {
|
||||||
FileOffsetInfo fileoffset;
|
FileOffsetInfo fileoffset;
|
||||||
TStream stream;
|
TStream stream;
|
||||||
TypeClass *tclass;
|
TypeClass *tclass;
|
||||||
CI_ActionType actiontype;
|
|
||||||
} inlinefunc;
|
} inlinefunc;
|
||||||
struct {
|
struct {
|
||||||
Type *a;
|
TemplClass *templ;
|
||||||
Type *b;
|
TemplClassInst *inst;
|
||||||
TemplateMember *tmemb;
|
TemplateMember *tmemb;
|
||||||
} memberfunc;
|
} memberfunc;
|
||||||
struct {
|
struct {
|
||||||
|
@ -83,6 +112,7 @@ typedef struct CI_Action {
|
||||||
TemplFuncInstance *inst;
|
TemplFuncInstance *inst;
|
||||||
} templatefunc;
|
} templatefunc;
|
||||||
} u;
|
} u;
|
||||||
|
CI_ActionType actiontype;
|
||||||
} CI_Action;
|
} CI_Action;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -96,20 +126,20 @@ typedef enum {
|
||||||
extern CI_Action *cinline_tactionlist;
|
extern CI_Action *cinline_tactionlist;
|
||||||
|
|
||||||
extern void CInline_Init(void);
|
extern void CInline_Init(void);
|
||||||
extern SInt32 CInline_GetLocalID(Object *obj);
|
extern SInt32 CInline_GetLocalID(Object *object);
|
||||||
extern Boolean CInline_ExpressionHasSideEffect(ENode *expr);
|
extern Boolean CInline_ExpressionHasSideEffect(ENode *expr);
|
||||||
extern ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode);
|
extern ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode);
|
||||||
extern void CInline_SerializeStatement(Statement *stmt);
|
extern void CInline_SerializeStatement(Statement *stmt);
|
||||||
extern Object *CInline_GetLocalObj(SInt32 id, Boolean flag);
|
extern Object *CInline_GetLocalObj(SInt32 id, Boolean flag);
|
||||||
extern SInt16 CInline_GetStatementNumber(Statement *first, Statement *stmt);
|
extern SInt16 CInline_GetStatementNumber(Statement *first, Statement *stmt);
|
||||||
extern void CInline_PackIFunctionData(CI_FuncData *packed, Statement *stmt, Object *obj);
|
extern void CInline_PackIFunctionData(CI_FuncData *packed, Statement *stmt, Object *object);
|
||||||
extern void CInline_UnpackIFunctionData(Object *obj, CI_FuncData *packed, Statement *stmt);
|
extern void CInline_UnpackIFunctionData(Object *object, CI_FuncData *packed, Statement *firstStmt);
|
||||||
extern void CInline_AddDefaultFunctionAction(Object *obj);
|
extern void CInline_AddDefaultFunctionAction(Object *object);
|
||||||
extern void CInline_AddInlineFunctionAction(Object *obj, TypeClass *tclass, FileOffsetInfo *fileoffset, TStream *stream, Boolean flag);
|
extern void CInline_AddInlineFunctionAction(Object *object, TypeClass *tclass, FileOffsetInfo *fileoffset, TStream *stream, Boolean flag);
|
||||||
extern void CInline_AddMemberFunctionAction(Object *obj, Type *a, Type *b, TemplateMember *tmemb);
|
extern void CInline_AddMemberFunctionAction(Object *object, TemplClass *templ, TemplClassInst *inst, TemplateMember *tmemb);
|
||||||
extern void CInline_AddTemplateFunctionAction(Object *obj, TemplateFunction *func, TemplFuncInstance *inst);
|
extern void CInline_AddTemplateFunctionAction(Object *object, TemplateFunction *func, TemplFuncInstance *inst);
|
||||||
extern void CInline_ObjectAddrRef(Object *obj);
|
extern void CInline_ObjectAddrRef(Object *object);
|
||||||
extern void CInline_GenFunc(Statement *stmt, Object *obj, UInt8 unk);
|
extern void CInline_GenFunc(Statement *stmt, Object *object, UInt8 unk);
|
||||||
extern Boolean CInline_CanFreeLHeap(void);
|
extern Boolean CInline_CanFreeLHeap(void);
|
||||||
extern Boolean CInline_GenerateDeferredFuncs(void);
|
extern Boolean CInline_GenerateDeferredFuncs(void);
|
||||||
extern void CInline_Finish(void);
|
extern void CInline_Finish(void);
|
||||||
|
|
|
@ -2,5 +2,40 @@
|
||||||
#define COMPILER_COBJC_H
|
#define COMPILER_COBJC_H
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
#include "compiler/objc.h"
|
||||||
|
|
||||||
|
extern Type *cobjc_type_class;
|
||||||
|
extern Type *cobjc_type_id;
|
||||||
|
extern Type *cobjc_type_sel;
|
||||||
|
extern TypeClass *cobjc_currentclass;
|
||||||
|
extern ObjCSelector **cobjc_selhashtable;
|
||||||
|
extern BClassList *cobjc_classdefs;
|
||||||
|
extern ObjCProtocol *cobjc_protocols;
|
||||||
|
extern long cobjc_selrefcount;
|
||||||
|
extern long cobjc_classrefcount;
|
||||||
|
extern long cobjc_stringcount;
|
||||||
|
extern Boolean cobjc_encodemethod;
|
||||||
|
|
||||||
|
extern void CObjC_Setup(void);
|
||||||
|
extern void CObjC_Cleanup(void);
|
||||||
|
extern void CObjC_GenerateModule(void);
|
||||||
|
extern Type *CObjC_GetObjCType_id(Boolean flag);
|
||||||
|
extern Boolean CObjC_IsType_id(Type *type);
|
||||||
|
extern Boolean CObjC_IsCompatibleType(Type *a, Type *b);
|
||||||
|
extern void CObjC_TranslateSelectorToken(void);
|
||||||
|
extern void CObjC_ParseDefs(TypeStruct *tstruct);
|
||||||
|
extern Type *CObjC_ParseID(void);
|
||||||
|
extern Type *CObjC_ParseTypeProtocol(TypeClass *tclass);
|
||||||
|
extern void CObjC_ParseInterface(void);
|
||||||
|
extern void CObjC_ParseImplementation(void);
|
||||||
|
extern void CObjC_ParseProtocol(void);
|
||||||
|
extern void CObjC_ParseClassDeclaration(void);
|
||||||
|
extern void *CObjC_ParseIdentifier();
|
||||||
|
extern ENode *CObjC_MakeSendMsgExpr(ENode *objexpr, TypeClass *tclass, ObjCNamedArg *namedArgs, ENodeList *unnamedArgs, UInt8 calltype, Boolean isSuper);
|
||||||
|
extern ENode *CObjC_ParseMessageExpression(void);
|
||||||
|
extern ENode *CObjC_ParseEncodeExpression(void);
|
||||||
|
extern ENode *CObjC_ParseAtExpression(void);
|
||||||
|
extern ENode *CObjC_ParseProtocolExpression(void);
|
||||||
|
extern ENode *CObjC_ParseSelectorExpression(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,4 +3,8 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern ENode *CObjC_CheckModernSendMessage(TypeClass *tclass, ENode *expr);
|
||||||
|
extern ENode *CObjC_New(TypeClass *tclass);
|
||||||
|
extern ENode *CObjC_Delete(TypeClass *tclass, ENode *objexpr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,8 +59,8 @@ typedef struct COpts {
|
||||||
Boolean codegen_dynamic;
|
Boolean codegen_dynamic;
|
||||||
Boolean codegen_pic;
|
Boolean codegen_pic;
|
||||||
Boolean no_common;
|
Boolean no_common;
|
||||||
char no_implicit_templates;
|
Boolean no_implicit_templates;
|
||||||
char absolutepath; // determines the path written to debug info
|
Boolean absolutepath; // determines the path written to debug info
|
||||||
char x06; // linker/objgen related
|
char x06; // linker/objgen related
|
||||||
short cpu;
|
short cpu;
|
||||||
char schedule_cpu;
|
char schedule_cpu;
|
||||||
|
@ -80,10 +80,10 @@ typedef struct COpts {
|
||||||
char x1D;
|
char x1D;
|
||||||
UInt8 x1E; // some register used in TOC_use_isel
|
UInt8 x1E; // some register used in TOC_use_isel
|
||||||
UInt8 gen_fsel;
|
UInt8 gen_fsel;
|
||||||
char ppc_opt_bclr_bcctr;
|
Boolean ppc_opt_bclr_bcctr;
|
||||||
Boolean use_lmw_stmw;
|
Boolean use_lmw_stmw;
|
||||||
char report_heap_info;
|
char report_heap_info;
|
||||||
char misaligned_mem_access;
|
Boolean misaligned_mem_access;
|
||||||
Boolean switch_tables;
|
Boolean switch_tables;
|
||||||
char prepare_compress;
|
char prepare_compress;
|
||||||
char some_alignment; // used in CMach_AllocationAlignment
|
char some_alignment; // used in CMach_AllocationAlignment
|
||||||
|
@ -93,11 +93,11 @@ typedef struct COpts {
|
||||||
short inlinelevel;
|
short inlinelevel;
|
||||||
int inline_max_size;
|
int inline_max_size;
|
||||||
int inline_max_total_size;
|
int inline_max_total_size;
|
||||||
char inline_bottom_up;
|
Boolean inline_bottom_up;
|
||||||
Boolean cplusplus;
|
Boolean cplusplus;
|
||||||
Boolean ecplusplus;
|
Boolean ecplusplus;
|
||||||
Boolean objective_c;
|
Boolean objective_c;
|
||||||
char objc_strict;
|
Boolean objc_strict;
|
||||||
Boolean ARM_conform;
|
Boolean ARM_conform;
|
||||||
char ARM_scoping;
|
char ARM_scoping;
|
||||||
Boolean require_prototypes;
|
Boolean require_prototypes;
|
||||||
|
@ -110,17 +110,17 @@ typedef struct COpts {
|
||||||
Boolean ignore_oldstyle;
|
Boolean ignore_oldstyle;
|
||||||
Boolean cpp_extensions;
|
Boolean cpp_extensions;
|
||||||
Boolean pointercast_lvalue;
|
Boolean pointercast_lvalue;
|
||||||
char useRTTI;
|
Boolean useRTTI;
|
||||||
Boolean delete_exception;
|
Boolean delete_exception;
|
||||||
char _4B;
|
char _4B;
|
||||||
Boolean oldalignment;
|
Boolean oldalignment;
|
||||||
Boolean unsignedchars;
|
Boolean unsignedchars;
|
||||||
Boolean multibyteaware;
|
Boolean multibyteaware;
|
||||||
char autoinline;
|
Boolean autoinline;
|
||||||
char defer_codegen;
|
Boolean defer_codegen;
|
||||||
Boolean direct_to_som;
|
Boolean direct_to_som;
|
||||||
char som_env_check;
|
Boolean som_env_check;
|
||||||
char som_call_opt;
|
Boolean som_call_opt;
|
||||||
Boolean booltruefalse;
|
Boolean booltruefalse;
|
||||||
char old_enum_mangler;
|
char old_enum_mangler;
|
||||||
Boolean longlong;
|
Boolean longlong;
|
||||||
|
@ -135,7 +135,7 @@ typedef struct COpts {
|
||||||
Boolean vbase_ctor_offset;
|
Boolean vbase_ctor_offset;
|
||||||
char vbase_abi_v2;
|
char vbase_abi_v2;
|
||||||
Boolean def_inherited;
|
Boolean def_inherited;
|
||||||
char template_patch;
|
Boolean template_patch;
|
||||||
char template_friends;
|
char template_friends;
|
||||||
char faster_pch_gen;
|
char faster_pch_gen;
|
||||||
Boolean array_new_delete;
|
Boolean array_new_delete;
|
||||||
|
@ -143,8 +143,8 @@ typedef struct COpts {
|
||||||
char def_inline_tfuncs;
|
char def_inline_tfuncs;
|
||||||
Boolean arg_dep_lookup;
|
Boolean arg_dep_lookup;
|
||||||
Boolean simple_prepdump;
|
Boolean simple_prepdump;
|
||||||
char line_prepdump;
|
Boolean line_prepdump;
|
||||||
char fullpath_prepdump;
|
Boolean fullpath_prepdump;
|
||||||
char old_mtemplparser;
|
char old_mtemplparser;
|
||||||
char suppress_init_code;
|
char suppress_init_code;
|
||||||
Boolean reverse_bitfields;
|
Boolean reverse_bitfields;
|
||||||
|
@ -154,14 +154,14 @@ typedef struct COpts {
|
||||||
Boolean longlong_prepeval;
|
Boolean longlong_prepeval;
|
||||||
Boolean const_strings;
|
Boolean const_strings;
|
||||||
char dumpir;
|
char dumpir;
|
||||||
char experimental;
|
Boolean experimental;
|
||||||
Boolean gcc_extensions;
|
Boolean gcc_extensions;
|
||||||
char stdc_fp_contract;
|
char stdc_fp_contract;
|
||||||
char stdc_fenv_access;
|
char stdc_fenv_access;
|
||||||
char stdc_cx_limitedr;
|
char stdc_cx_limitedr;
|
||||||
Boolean old_argmatch;
|
Boolean old_argmatch;
|
||||||
char optEH;
|
Boolean optEH;
|
||||||
char optEH2;
|
Boolean optEH2;
|
||||||
Boolean new_mangler;
|
Boolean new_mangler;
|
||||||
char microsoft;
|
char microsoft;
|
||||||
Boolean warningerrors;
|
Boolean warningerrors;
|
||||||
|
@ -177,7 +177,7 @@ typedef struct COpts {
|
||||||
char warn_hidevirtual;
|
char warn_hidevirtual;
|
||||||
Boolean warn_largeargs;
|
Boolean warn_largeargs;
|
||||||
Boolean warn_implicitconv;
|
Boolean warn_implicitconv;
|
||||||
char warn_notinlined;
|
Boolean warn_notinlined;
|
||||||
Boolean warn_structclass;
|
Boolean warn_structclass;
|
||||||
Boolean warn_padding;
|
Boolean warn_padding;
|
||||||
Boolean warn_no_side_effect;
|
Boolean warn_no_side_effect;
|
||||||
|
@ -191,8 +191,8 @@ typedef struct COpts {
|
||||||
Boolean readonly_strings;
|
Boolean readonly_strings;
|
||||||
Boolean exceptions;
|
Boolean exceptions;
|
||||||
char _99;
|
char _99;
|
||||||
char dont_inline;
|
Boolean dont_inline;
|
||||||
char always_inline;
|
Boolean always_inline;
|
||||||
Boolean peephole;
|
Boolean peephole;
|
||||||
Boolean global_optimizer;
|
Boolean global_optimizer;
|
||||||
char side_effects;
|
char side_effects;
|
||||||
|
@ -200,7 +200,7 @@ typedef struct COpts {
|
||||||
Boolean import;
|
Boolean import;
|
||||||
Boolean export;
|
Boolean export;
|
||||||
Boolean lib_export;
|
Boolean lib_export;
|
||||||
char nosyminline;
|
Boolean nosyminline;
|
||||||
char force_active;
|
char force_active;
|
||||||
char optimizationlevel;
|
char optimizationlevel;
|
||||||
Boolean optimize_for_size;
|
Boolean optimize_for_size;
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
#pragma options align=mac68k
|
#pragma options align=mac68k
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct Macro {
|
struct Macro {
|
||||||
struct Macro *next;
|
Macro *next;
|
||||||
HashNameNode *name;
|
HashNameNode *name;
|
||||||
void *c;
|
void *c;
|
||||||
unsigned short xC;
|
unsigned short xC;
|
||||||
Boolean is_special;
|
Boolean is_special;
|
||||||
Boolean xF;
|
Boolean xF;
|
||||||
void *e;
|
void *e;
|
||||||
} Macro;
|
};
|
||||||
typedef struct TokenStack {
|
typedef struct TokenStack {
|
||||||
char *pos;
|
char *pos;
|
||||||
char *macrostart;
|
char *macrostart;
|
||||||
|
|
|
@ -3,4 +3,8 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern void CPrep_PreprocessDumpNewLine(void);
|
||||||
|
extern void CPrep_PreprocessDumpFileInfo(Boolean flag);
|
||||||
|
extern void CPrep_Preprocess(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,4 +3,11 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern OLinkList *CRTTI_ConstructVTableHeaders(TypeClass *tclass, void *data, OLinkList *links);
|
||||||
|
extern ENode *CRTTI_ParseTypeID(void);
|
||||||
|
extern ENode *CRTTI_Parse_dynamic_cast(void);
|
||||||
|
extern ENode *CRTTI_Parse_static_cast(void);
|
||||||
|
extern ENode *CRTTI_Parse_reinterpret_cast(void);
|
||||||
|
extern ENode *CRTTI_Parse_const_cast(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,5 +2,42 @@
|
||||||
#define COMPILER_CSOM_H
|
#define COMPILER_CSOM_H
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
#include "compiler/som.h"
|
||||||
|
|
||||||
|
#ifdef __MWERKS__
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#endif
|
||||||
|
typedef struct CSOMStub {
|
||||||
|
struct CSOMStub *next;
|
||||||
|
Object *object;
|
||||||
|
TypeClass *tclass;
|
||||||
|
SInt32 offset;
|
||||||
|
UInt8 x10;
|
||||||
|
} CSOMStub;
|
||||||
|
#ifdef __MWERKS__
|
||||||
|
#pragma options align=reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern CSOMStub *csom_stubs;
|
||||||
|
|
||||||
|
extern void CSOM_Setup(Boolean flag);
|
||||||
|
extern void CSOM_Cleanup(void);
|
||||||
|
extern void CSOM_CheckFuncType(TypeFunc *tfunc);
|
||||||
|
extern void CSOM_MakeSOMClass(TypeClass *tclass);
|
||||||
|
extern void CSOM_ClassComplete(TypeClass *tclass);
|
||||||
|
extern void CSOM_GenerateClassStructures(TypeClass *tclass);
|
||||||
|
extern void CSOM_PragmaReleaseOrder(void);
|
||||||
|
extern void CSOM_PragmaClassVersion(void);
|
||||||
|
extern void CSOM_PragmaMetaClass(void);
|
||||||
|
extern void CSOM_PragmaCallStyle(void);
|
||||||
|
extern void CSOM_FixNewDeleteFunctype(TypeFunc *tfunc);
|
||||||
|
extern ENode *CSOM_New(TypeClass *tclass);
|
||||||
|
extern ENode *CSOM_Delete(TypeClass *tclass, ENode *objExpr);
|
||||||
|
extern void CSOM_InitAutoClass(Object *object);
|
||||||
|
extern ENode *CSOM_SOMSelfObjectExpr(TypeClass *tclass);
|
||||||
|
extern void CSOM_InitSOMSelf(TypeClass *tclass, Statement *stmt);
|
||||||
|
extern ENode *CSOM_EnvCheck(ENode *funccall, ENodeList *checkArg);
|
||||||
|
extern ENode *CSOM_MemberVarAccess(BClassList *path, ObjMemberVar *ivar, ENode *thisExpr);
|
||||||
|
extern ENode *CSOM_MethodAccess(BClassList *path, Object *func, Boolean flag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,12 +13,12 @@ extern TypeClass *cscope_currentclass;
|
||||||
extern NameSpace *cscope_current;
|
extern NameSpace *cscope_current;
|
||||||
extern NameSpace *cscope_root;
|
extern NameSpace *cscope_root;
|
||||||
|
|
||||||
typedef struct CScopeSave {
|
struct CScopeSave {
|
||||||
NameSpace *current;
|
NameSpace *current;
|
||||||
TypeClass *currentclass;
|
TypeClass *currentclass;
|
||||||
Object *currentfunc;
|
Object *currentfunc;
|
||||||
Boolean is_member_func;
|
Boolean is_member_func;
|
||||||
} CScopeSave; // assumed name
|
}; // assumed name
|
||||||
|
|
||||||
// this might be called NameResult
|
// this might be called NameResult
|
||||||
typedef struct CScopeParseResult {
|
typedef struct CScopeParseResult {
|
||||||
|
|
|
@ -3,4 +3,21 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern TemplClass *CTemplClass_GetMasterTemplate(TemplClass *tmclass);
|
||||||
|
extern void CTemplClass_RegisterUsingDecl(TemplClass *tmclass, TypeTemplDep *type, AccessType access);
|
||||||
|
extern void CTemplClass_RegisterFriend(TemplClass *tmclass, DeclInfo *di);
|
||||||
|
extern void CTemplClass_RegisterBaseClass(TemplClass *tmclass, Type *type, AccessType access, Boolean is_virtual);
|
||||||
|
extern void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *enumtype);
|
||||||
|
extern void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *objenumconst, ENode *initexpr);
|
||||||
|
extern void CTemplClass_RegisterObjectInit(TemplClass *tmclass, Object *object, ENode *initexpr);
|
||||||
|
extern void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *refobj);
|
||||||
|
extern void CTemplClass_CompleteClass(TemplClass *templ, DeclE *de);
|
||||||
|
extern TemplClassInst *CTemplClass_GetInstance(TemplClass *tmclass, TemplArg *args1, TemplArg *args2);
|
||||||
|
extern TemplateMember *CTemplClass_DefineMember(TemplClass *tmclass, Object *object, FileOffsetInfo *foi, TStream *stream);
|
||||||
|
extern void CTemplClass_ParsePartialSpecialization(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset);
|
||||||
|
extern void CTemplClass_ParseClass(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset);
|
||||||
|
extern Boolean CTemplClass_FindPartialTemplate(TemplArg *args, TemplClass **resultTempl, TemplArg **resultArgs);
|
||||||
|
extern TemplClass *CTemplClass_DefineNestedClass(TemplClass *parent, HashNameNode *name, short mode);
|
||||||
|
extern Boolean CTempl_InstantiateTemplateClass(TypeClass *tclass);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,5 +2,18 @@
|
||||||
#define COMPILER_CTEMPLATEFUNC_H
|
#define COMPILER_CTEMPLATEFUNC_H
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
#include "compiler/CExpr.h"
|
||||||
|
|
||||||
|
extern Boolean CTempl_CanDeduceFunc(Object *object, TypeFunc *tfunc, TemplArg *args);
|
||||||
|
extern TemplFuncInstance *CTempl_CheckFuncInstance(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2);
|
||||||
|
extern TemplFuncInstance *CTempl_DeduceFunc(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2, Boolean flag);
|
||||||
|
extern Boolean CTempl_FuncIsMoreSpecialized(Object *object1, Object *object2);
|
||||||
|
extern Object *CTempl_PartialOrdering(Object *object, ObjectList *list, int count);
|
||||||
|
extern int CTempl_GetTemplateArgumentExpressionIndex(TemplArg *arg);
|
||||||
|
extern Boolean CTempl_DeduceType(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag1, Boolean flag2);
|
||||||
|
extern void CTempl_FuncMatch(NameSpaceObjectList *list, TemplArg *args, ENodeList *argexprs, Match13 *match13ptr, ENode *expr);
|
||||||
|
extern Object *CTempl_DeduceFromFunctionCall(Object *funcobj, TemplArg *templargs, ENodeList *argexprs);
|
||||||
|
extern Object *CTempl_DeduceFromConversion(Object *funcobj, Type *type, UInt32 qual);
|
||||||
|
extern Object *CTempl_TemplateFunctionCheck(DeclInfo *di, NameSpaceObjectList *nsol);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,4 +3,21 @@
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
|
||||||
|
extern TemplClass *ctempl_templates;
|
||||||
|
extern TemplateFunction *ctempl_templatefuncs;
|
||||||
|
extern TemplStack *ctempl_curinstance;
|
||||||
|
|
||||||
|
extern void CTempl_Setup(void);
|
||||||
|
extern void CTempl_Cleanup(void);
|
||||||
|
extern TemplArg *CTempl_ParseUncheckTemplArgs(TemplParam *params, Boolean is_global);
|
||||||
|
extern Type *CTempl_ParseTemplTemplParam(TypeTemplDep *type);
|
||||||
|
extern Type *CTempl_ClassGetType(TemplClass *templ);
|
||||||
|
extern Boolean CTempl_IsQualifiedMember(DeclInfo *di, Type *type, NameSpace **resultnspace);
|
||||||
|
extern void CTempl_Parse(TemplClass *templ, AccessType access);
|
||||||
|
extern void CTempl_ParseInstanceScopeFunction(Object *funcobj, TemplClassInst *inst, TypeClass *tclass);
|
||||||
|
extern Boolean CTempl_GenFuncInstance(TemplateFunction *templ, TemplFuncInstance *inst, Boolean flag);
|
||||||
|
extern void CTempl_InstantiateMember(TemplClass *templ, TemplClassInst *inst, TemplateMember *tmemb, Object *object, Boolean flag);
|
||||||
|
extern Boolean CTempl_Instantiate(void);
|
||||||
|
extern Boolean CTempl_InlineFunctionCheck(Object *funcobj);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,5 +2,45 @@
|
||||||
#define COMPILER_CTEMPLATETOOLS_H
|
#define COMPILER_CTEMPLATETOOLS_H
|
||||||
|
|
||||||
#include "compiler/common.h"
|
#include "compiler/common.h"
|
||||||
|
#include "compiler/enode.h"
|
||||||
|
|
||||||
|
extern short ctempl_instdepth;
|
||||||
|
|
||||||
|
extern void CTemplTool_PushInstance(TemplStack *stack, TypeClass *tmclass, Object *func);
|
||||||
|
extern void CTemplTool_PopInstance(TemplStack *stack);
|
||||||
|
extern ENode *CTempTool_GetPTMTemplArgExpr(ENode *expr, Type *type);
|
||||||
|
extern Boolean CTemplTool_InitDeduceInfo(DeduceInfo *info, TemplParam *params, TemplArg *args, Boolean flag);
|
||||||
|
extern void CTemplTool_InsertTemplateParameter(NameSpace *nspace, TemplParam *param);
|
||||||
|
extern TemplArg *CTemplTool_MakeTemplArgList(DeduceInfo *info);
|
||||||
|
extern Boolean CTemplTool_IsIdenticalTemplArgList(TemplArg *args, TemplParam *params);
|
||||||
|
extern Type *CTemplTool_GetSelfRefTemplate(Type *type);
|
||||||
|
extern TemplateFunction *CTemplTool_GetFuncTempl(Object *object);
|
||||||
|
extern Boolean CTemplTool_ParamHasDefaultArg(TemplParam *param);
|
||||||
|
extern void CTemplTool_MergeDefaultArgs(TemplParam *dest, TemplParam *src);
|
||||||
|
extern void CTemplTool_MergeArgNames(TypeFunc *src, TypeFunc *dest);
|
||||||
|
extern Boolean CTemplTool_EqualParams(TemplParam *a, TemplParam *b, Boolean copyNames);
|
||||||
|
extern NameSpace *CTemplTool_SetupTemplateArgumentNameSpace(TemplParam *params, TemplArg *args, Boolean is_global);
|
||||||
|
extern void CTemplTool_SetupOuterTemplateArgumentNameSpace(NameSpace *nspace);
|
||||||
|
extern NameSpace *CTemplTool_InsertTemplateArgumentNameSpace(TemplParam *params, TemplClassInst *inst, CScopeSave *save);
|
||||||
|
extern void CTemplTool_RemoveOuterTemplateArgumentNameSpace(NameSpace *nspace);
|
||||||
|
extern void CTemplTool_RemoveTemplateArgumentNameSpace(NameSpace *nspace, TemplClassInst *inst, CScopeSave *save);
|
||||||
|
extern Boolean CTemplTool_IsTemplateArgumentDependentType(Type *type);
|
||||||
|
extern Boolean CTemplTool_IsTemplateArgumentDependentExpression(ENode *expr);
|
||||||
|
extern Boolean CTemplTool_IsSameTemplate(TemplParam *params, TemplArg *args);
|
||||||
|
extern TemplClass *CTemplTool_IsTemplate(TypeTemplDep *ttd);
|
||||||
|
extern Type *CTemplTool_IsDependentTemplate(TemplClass *tmclass, TemplArg *args);
|
||||||
|
extern Boolean CTemplTool_EqualExprTypes(ENode *a, ENode *b);
|
||||||
|
extern ENode *CTempl_MakeTemplDepExpr(ENode *left, ENodeType nt, ENode *right);
|
||||||
|
extern void CTemplTool_CheckTemplArgType(Type *type);
|
||||||
|
extern Boolean CTemplTool_EqualArgs(TemplArg *a, TemplArg *b);
|
||||||
|
extern TemplArg *CTemplTool_MakeGlobalTemplArgCopy(TemplArg *args);
|
||||||
|
extern Boolean CTemplTool_TemplDepTypeCompare(TypeTemplDep *a, TypeTemplDep *b);
|
||||||
|
extern Type *CTemplTool_DeduceArgDepType(TemplArg *args, Type *type, UInt32 qual, UInt32 *resultQual);
|
||||||
|
extern ENode *CTemplTool_DeduceExpr(TypeDeduce *deduce, ENode *expr);
|
||||||
|
extern ENode *CTemplTool_DeduceDefaultArg(Object *func, ENode *expr);
|
||||||
|
extern FuncArg *CTemplTool_DeduceArgCopy(TypeDeduce *deduce, FuncArg *args);
|
||||||
|
extern Type *CTemplTool_DeduceTypeCopy(TypeDeduce *deduce, Type *type, UInt32 *resultQual);
|
||||||
|
extern Type *CTemplTool_ResolveMemberSelfRefs(TemplClass *templ, Type *type, UInt32 *resultQual);
|
||||||
|
extern Boolean CTemplTool_IsSameTemplateType(Type *a, Type *b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef void (*ArgumentProcessor)(Object *obj, short reg);
|
||||||
extern void process_arguments(ArgumentProcessor func, Boolean flag);
|
extern void process_arguments(ArgumentProcessor func, Boolean flag);
|
||||||
extern void move_assigned_argument(Object *obj, short reg);
|
extern void move_assigned_argument(Object *obj, short reg);
|
||||||
extern void assign_labels(Statement *stmt);
|
extern void assign_labels(Statement *stmt);
|
||||||
extern void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, Boolean callOnModuleBind);
|
extern void CodeGen_Generator(Statement *statements, Object *func, UInt8 mysteryFlag, Boolean callOnModuleBind);
|
||||||
extern void CodeGen_GenVDispatchThunk(Object *thunkobj, Object *obj, SInt32 a, SInt32 b, SInt32 c);
|
extern void CodeGen_GenVDispatchThunk(Object *thunkobj, Object *obj, SInt32 a, SInt32 b, SInt32 c);
|
||||||
extern void CodeGen_SetupRuntimeObjects(void);
|
extern void CodeGen_SetupRuntimeObjects(void);
|
||||||
extern Boolean CodeGen_ReInitRuntimeObjects(Boolean is_precompiler);
|
extern Boolean CodeGen_ReInitRuntimeObjects(Boolean is_precompiler);
|
||||||
|
@ -59,10 +59,10 @@ extern void CodeGen_ParseDeclSpec(HashNameNode *identifier, DeclInfo *declinfo);
|
||||||
extern void CodeGen_ParsePragma(HashNameNode *name);
|
extern void CodeGen_ParsePragma(HashNameNode *name);
|
||||||
extern void CodeGen_UpdateObject(Object *object);
|
extern void CodeGen_UpdateObject(Object *object);
|
||||||
extern void CodeGen_UpdateBackEndOptions(void);
|
extern void CodeGen_UpdateBackEndOptions(void);
|
||||||
extern void CodeGen_objc_method_self_offset();
|
extern SInt32 CodeGen_objc_method_self_offset(ObjCMethod *meth);
|
||||||
extern void CodeGen_objc_method_sel_offset();
|
extern SInt32 CodeGen_objc_method_sel_offset(ObjCMethod *meth);
|
||||||
extern void CodeGen_objc_method_arg_offset();
|
extern SInt32 CodeGen_objc_method_arg_offset(ObjCMethod *meth, ObjCMethodArg *arg);
|
||||||
extern void CodeGen_objc_method_args_size();
|
extern SInt32 CodeGen_objc_method_args_size(ObjCMethod *meth);
|
||||||
extern ENode *CodeGen_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs);
|
extern ENode *CodeGen_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs);
|
||||||
extern ENode *CodeGen_HandleTypeCast(ENode *expr, Type *type, UInt32 qual);
|
extern ENode *CodeGen_HandleTypeCast(ENode *expr, Type *type, UInt32 qual);
|
||||||
extern short CodeGen_AssignCheck(ENode *expr, Type *type, Boolean flag1, Boolean flag2);
|
extern short CodeGen_AssignCheck(ENode *expr, Type *type, Boolean flag1, Boolean flag2);
|
||||||
|
|
|
@ -40,12 +40,12 @@ typedef struct _HeapInfo {
|
||||||
SInt32 largest_free_block;
|
SInt32 largest_free_block;
|
||||||
} HeapInfo;
|
} HeapInfo;
|
||||||
|
|
||||||
typedef struct GList {
|
struct GList {
|
||||||
char **data;
|
char **data;
|
||||||
SInt32 size;
|
SInt32 size;
|
||||||
SInt32 hndlsize;
|
SInt32 hndlsize;
|
||||||
SInt32 growsize;
|
SInt32 growsize;
|
||||||
} GList;
|
};
|
||||||
|
|
||||||
extern long hash_name_id;
|
extern long hash_name_id;
|
||||||
extern HashNameNode **name_hash_nodes;
|
extern HashNameNode **name_hash_nodes;
|
||||||
|
@ -119,12 +119,17 @@ extern void memclr(void *ptr, SInt32 size);
|
||||||
extern void memclrw(void *ptr, SInt32 size);
|
extern void memclrw(void *ptr, SInt32 size);
|
||||||
extern void CToLowercase(char *a, char *b);
|
extern void CToLowercase(char *a, char *b);
|
||||||
extern short getbit(SInt32 l);
|
extern short getbit(SInt32 l);
|
||||||
extern inline SInt32 CTool_EndianReadWord32(void *value) {
|
#ifdef ENDIAN_CONVERSION
|
||||||
return *((SInt32 *) value);
|
extern UInt16 CTool_EndianConvertWord16(UInt16 theword);
|
||||||
}
|
extern UInt32 CTool_EndianConvertWord32(UInt32 theword);
|
||||||
extern inline UInt32 CTool_EndianConvertWord32(UInt32 value) {
|
extern void CTool_EndianConvertMem(UInt8 *data, short len);
|
||||||
return value;
|
extern UInt32 CTool_EndianReadWord32(void *ptr);
|
||||||
}
|
#else
|
||||||
|
#define CTool_EndianConvertWord32(value) value
|
||||||
|
#define CTool_EndianConvertWord16(value) value
|
||||||
|
#define CTool_EndianConvertMem(data, len) ((void)0)
|
||||||
|
#define CTool_EndianReadWord32(ptr) (*((UInt32 *) (ptr)))
|
||||||
|
#endif
|
||||||
extern void CTool_EndianConvertWord64(CInt64 ci, char *result);
|
extern void CTool_EndianConvertWord64(CInt64 ci, char *result);
|
||||||
extern UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x);
|
extern UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x);
|
||||||
extern UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x);
|
extern UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x);
|
||||||
|
|
|
@ -62,6 +62,11 @@ struct ExceptionAction {
|
||||||
Object *dtor;
|
Object *dtor;
|
||||||
Object *element_size;
|
Object *element_size;
|
||||||
} destroy_partial_array;
|
} destroy_partial_array;
|
||||||
|
struct { // TODO: merge me with destroy_member
|
||||||
|
Object *objectptr;
|
||||||
|
Object *dtor;
|
||||||
|
SInt32 offset;
|
||||||
|
} destroy_base;
|
||||||
struct {
|
struct {
|
||||||
Object *objectptr;
|
Object *objectptr;
|
||||||
Object *dtor;
|
Object *dtor;
|
||||||
|
@ -115,8 +120,33 @@ struct ExceptionAction {
|
||||||
ExceptionActionType type;
|
ExceptionActionType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct EANode {
|
||||||
|
struct EANode *dagListNext;
|
||||||
|
struct EANode *prev;
|
||||||
|
ExceptionAction *action;
|
||||||
|
UInt16 count;
|
||||||
|
UInt16 xE;
|
||||||
|
} EANode;
|
||||||
|
|
||||||
|
typedef struct PCAction {
|
||||||
|
struct PCAction *next;
|
||||||
|
struct PCAction *prev;
|
||||||
|
PCode *firstInstr;
|
||||||
|
PCode *lastInstr;
|
||||||
|
ExceptionAction *actions;
|
||||||
|
EANode *node;
|
||||||
|
} PCAction;
|
||||||
|
|
||||||
#ifdef __MWERKS__
|
#ifdef __MWERKS__
|
||||||
#pragma options align=reset
|
#pragma options align=reset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern EANode *DAG[EAT_NACTIONS];
|
||||||
|
|
||||||
|
extern int countexceptionactionregisters(ExceptionAction *actions);
|
||||||
|
extern void noteexceptionactionregisters(ExceptionAction *actions, PCodeArg *ops);
|
||||||
|
extern void recordexceptionactions(PCode *instr, ExceptionAction *actions);
|
||||||
|
extern void deleteexceptionaction(PCAction *pca);
|
||||||
|
extern void dumpexceptiontables(Object *function, SInt32 codesize);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue