mirror of
https://git.wuffs.org/MWCC
synced 2025-12-11 22:44:05 +00:00
honk
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,9 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/CMangler.h"
|
||||
#include "compiler/CParser.h"
|
||||
#include "compiler/CPrep.h"
|
||||
#include "compiler/CScope.h"
|
||||
#include "compiler/enode.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler/scopes.h"
|
||||
@@ -1016,7 +1020,7 @@ static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, Has
|
||||
if (r6->object->otype == r30->object->otype) {
|
||||
switch (r6->object->otype) {
|
||||
case OT_TYPE:
|
||||
if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6))
|
||||
if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->qual == OBJ_TYPE(r30->object)->qual))
|
||||
goto break1;
|
||||
break;
|
||||
case OT_TYPETAG:
|
||||
@@ -1196,7 +1200,7 @@ static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceO
|
||||
return 0;
|
||||
case OT_TYPE:
|
||||
result->x8 = OBJ_TYPE(list->object)->type;
|
||||
result->xC = OBJ_TYPE(list->object)->unk6;
|
||||
result->xC = OBJ_TYPE(list->object)->qual;
|
||||
result->obj_10 = list->object;
|
||||
result->name_4 = name;
|
||||
result->x20 = 1;
|
||||
@@ -1388,7 +1392,7 @@ inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) {
|
||||
}
|
||||
}
|
||||
|
||||
Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) {
|
||||
Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, UInt32 *qual) {
|
||||
CScopeParseResult result;
|
||||
CScopeNSIterator iterator;
|
||||
NameSpaceObjectList *list;
|
||||
@@ -1400,13 +1404,13 @@ Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) {
|
||||
do {
|
||||
for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) {
|
||||
if (list->object->otype == OT_TYPETAG) {
|
||||
if (unk6)
|
||||
*unk6 = NULL;
|
||||
if (qual)
|
||||
*qual = 0;
|
||||
return OBJ_TYPE_TAG(list->object)->type;
|
||||
}
|
||||
if (list->object->otype == OT_TYPE) {
|
||||
if (unk6)
|
||||
*unk6 = OBJ_TYPE(list->object)->unk6;
|
||||
if (qual)
|
||||
*qual = OBJ_TYPE(list->object)->qual;
|
||||
return OBJ_TYPE(list->object)->type;
|
||||
}
|
||||
}
|
||||
@@ -2429,7 +2433,7 @@ static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *o
|
||||
if (!nspace->theclass) {
|
||||
if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) &&
|
||||
(OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) &&
|
||||
(OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6))
|
||||
(OBJ_TYPE(obj)->qual == OBJ_TYPE(list->object)->qual))
|
||||
return;
|
||||
}
|
||||
copy = galloc(sizeof(ObjType));
|
||||
@@ -2530,7 +2534,7 @@ void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, Hash
|
||||
}
|
||||
}
|
||||
|
||||
void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) {
|
||||
void CScope_ParseUsingDeclaration(NameSpace *nspace, short access, Boolean flag) {
|
||||
// almost matches, slight bit of register weirdness
|
||||
CScopeParseResult result;
|
||||
|
||||
|
||||
93
compiler_and_linker/unsorted/CABI.c
Normal file
93
compiler_and_linker/unsorted/CABI.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "compiler/CABI.h"
|
||||
#include "compiler/CMachine.h"
|
||||
#include "compiler/types.h"
|
||||
#include "compiler/CompilerTools.h"
|
||||
|
||||
static void *trans_vtboffsets; // TODO type
|
||||
static void *cabi_pathroot; // TODO type - 8 byte struct??
|
||||
static void *cabi_pathcur; // TODO type
|
||||
static TypeClass *cabi_loop_class;
|
||||
static Boolean cabi_loop_construct;
|
||||
|
||||
short CABI_GetStructResultArgumentIndex(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Type *CABI_GetSizeTType(void) {
|
||||
return (Type *) &stunsignedlong;
|
||||
}
|
||||
|
||||
Type *CABI_GetPtrDiffTType(void) {
|
||||
return (Type *) &stsignedlong;
|
||||
}
|
||||
|
||||
SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) {}
|
||||
|
||||
void CABI_ReverseBitField(TypeBitfield *tbitfield) {}
|
||||
|
||||
// not sure about the sig for this, it's unused lmao
|
||||
static void CABI_AllocateZeroVTablePointer() {}
|
||||
|
||||
static SInt32 CABI_GetBaseSize(TypeClass *tclass) {}
|
||||
static void CABI_AllocateBases() {}
|
||||
static void CABI_AllocateVirtualBasePointers() {}
|
||||
static void CABI_GetMemberOffset() {}
|
||||
static void CABI_AllocateMembers() {}
|
||||
static void CABI_AllocateVirtualBases() {}
|
||||
static void CABI_FindZeroDeltaVPtr() {}
|
||||
static void CABI_FindZeroVirtualBaseMember() {}
|
||||
|
||||
void CABI_AddVTable(TypeClass *tclass) {
|
||||
tclass->vtable = galloc(sizeof(VTable));
|
||||
memclrw(tclass->vtable, sizeof(VTable));
|
||||
}
|
||||
|
||||
SInt32 CABI_GetVTableOffset(TypeClass *tclass) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void CABI_GetBaseVTableSize() {}
|
||||
static void CABI_ApplyClassFlags() {}
|
||||
static void CABI_AllocateVTable() {}
|
||||
void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) {}
|
||||
void CABI_MakeDefaultArgConstructor(Object *obj, TypeClass *tclass) {}
|
||||
static void CABI_ThisArg() {}
|
||||
ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {}
|
||||
static void CABI_VArg() {}
|
||||
static void CABI_MakeVArgExpr() {}
|
||||
static void CABI_MakeCopyConArgExpr() {}
|
||||
static void CABI_InitVBasePtr1() {}
|
||||
static void CABI_InitVBasePtrs() {}
|
||||
static void CABI_GetVBasePath() {}
|
||||
static void CABI_GetVBasePtr() {}
|
||||
static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *base, SInt32 offset) {}
|
||||
SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base) {}
|
||||
static void CABI_InitVBaseCtorOffsets() {}
|
||||
static void CABI_InitVTablePtrs() {}
|
||||
static Boolean CABI_IsOperatorNew(Object *obj) {}
|
||||
Object *CABI_ConstructorCallsNew(TypeClass *tclass) {}
|
||||
void CABI_TransConstructor(Object *obj, Statement *stmt, TypeClass *tclass, TransConstructorCallback callback, Boolean flag) {}
|
||||
void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *obj) {}
|
||||
static void CABI_AssignObject() {}
|
||||
static void CABI_FindIntegralSizeType() {}
|
||||
static void CABI_AppendCopyRegion() {}
|
||||
static void CABI_ClassInitLoopCallBack() {}
|
||||
static void CABI_CopyConAssignCB() {}
|
||||
void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *obj) {}
|
||||
void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *obj) {}
|
||||
static void CABI_DestroyMembers() {}
|
||||
static void CABI_DestroyBases() {}
|
||||
static void CABI_DestroyVBases() {}
|
||||
void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass) {}
|
||||
void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *obj) {}
|
||||
static void CABI_CreateLayeredDestructor() {}
|
||||
void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *obj) {}
|
||||
|
||||
Object *CABI_GetDestructorObject(Object *obj, int what) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void CABI_AddLayeredDestructor() {}
|
||||
void CABI_AddLayeredDestructors(TypeClass *tclass) {}
|
||||
|
||||
ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, UInt8 mode, Boolean flag1, Boolean flag2) {}
|
||||
122
compiler_and_linker/unsorted/CClass.c
Normal file
122
compiler_and_linker/unsorted/CClass.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "compiler/CClass.h"
|
||||
|
||||
typedef struct OVClassBase {
|
||||
struct OVClassBase *next;
|
||||
struct OVClass *ovclass;
|
||||
Boolean is_virtual;
|
||||
} OVClassBase;
|
||||
|
||||
typedef struct OVFunc {
|
||||
struct OVFunc *next;
|
||||
Object *obj;
|
||||
struct OVClass *ovc8;
|
||||
struct OVFunc *ovfC;
|
||||
struct OVFunc *ovf10;
|
||||
} OVFunc;
|
||||
|
||||
typedef struct OVClass {
|
||||
TypeClass *tclass;
|
||||
OVFunc *vfuncs;
|
||||
OVClassBase *bases;
|
||||
SInt32 offset;
|
||||
SInt32 voffset;
|
||||
Boolean alloced_vtable;
|
||||
} OVClass;
|
||||
|
||||
static TypeClass *main_class;
|
||||
static void *cclass_thunklist; // TODO type
|
||||
static TypeClass *cclass_isbase_mostderived;
|
||||
static void *cclass_isbase_foundoffset; // TODO type
|
||||
static Boolean cclass_isambigbase;
|
||||
static short cclass_founddepth;
|
||||
static void *vtable_object_data; // TODO type
|
||||
static void *vtable_data_size; // TODO type
|
||||
static VTableObjectLink *vtable_object_links;
|
||||
static TypeClass *cclass_vbase;
|
||||
static OVClass *cclass_ovbase;
|
||||
static OVClass *cclass_root;
|
||||
static Object *found_pure;
|
||||
static Boolean check_pures;
|
||||
static Object *cclass_dominator_vobject;
|
||||
static SInt32 cclass_dominator_voffset;
|
||||
static Object *cclass_dominator_oobject;
|
||||
static TypeClass *cclass_dominator_oclass;
|
||||
static SInt32 cclass_dominator_ooffset;
|
||||
static Object *cclass_dominator_eobject;
|
||||
|
||||
void CClass_Init(void) {}
|
||||
void CClass_GenThunks(void) {}
|
||||
static Object *CClass_ThunkObject(Object *obj, SInt32 a, SInt32 b, SInt32 c) {}
|
||||
static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) {}
|
||||
static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB) {}
|
||||
UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) {}
|
||||
Boolean CClass_IsEmpty(TypeClass *tclass) {}
|
||||
Boolean CClass_IsNonStaticMemberFunc(TypeMethod *tmethod) {}
|
||||
Object *CClass_DefaultConstructor(TypeClass *tclass) {}
|
||||
Object *CClass_DummyDefaultConstructor(TypeClass *tclass) {}
|
||||
ENode *CClass_DefaultConstructorCall(TypeClass *a, TypeClass *b, ENode *expr, SInt32 unkshortparam, Boolean flag1, Boolean flag2, Boolean *errorflag) {}
|
||||
Object *CClass_AssignmentOperator(TypeClass *tclass) {}
|
||||
Object *CClass_CopyConstructor(TypeClass *tclass) {}
|
||||
NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) {}
|
||||
Object *CClass_Constructor(TypeClass *tclass) {}
|
||||
Object *CClass_Destructor(TypeClass *tclass) {}
|
||||
Boolean CClass_IsConstructor(Object *obj) {}
|
||||
Boolean CClass_IsDestructor(Object *obj) {}
|
||||
Boolean CClass_IsPODClass(TypeClass *tclass) {}
|
||||
Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) {}
|
||||
Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) {}
|
||||
Boolean CClass_ReferenceArgument(TypeClass *tclass) {}
|
||||
BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) {}
|
||||
BClassList *CClass_AppendPath(BClassList *a, BClassList *b) {}
|
||||
static AccessType CClass_GetPathAccess(BClassList *path) {}
|
||||
Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) {}
|
||||
static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) {}
|
||||
BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) {}
|
||||
Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) {}
|
||||
TypeClass *CClass_GetQualifiedClass(void) {}
|
||||
ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean flag) {}
|
||||
ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) {}
|
||||
ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) {}
|
||||
SInt32 CClass_GetPathOffset(BClassList *path) {}
|
||||
Boolean CClass_ClassDominates(TypeClass *a, TypeClass *b) {}
|
||||
SInt32 CClass_VirtualBaseOffset(TypeClass *a, TypeClass *b) {}
|
||||
SInt32 CClass_VirtualBaseVTableOffset(TypeClass *a, TypeClass *b) {}
|
||||
SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **obj) {}
|
||||
Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) {}
|
||||
static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) {}
|
||||
static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) {}
|
||||
static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) {}
|
||||
static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) {}
|
||||
static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) {}
|
||||
static TypeMethod *CClass_GetCovariantType(TypeMethod *tmethod, Type *type) {}
|
||||
static Object *CClass_FindCovariantFunction(Object *func, Type *type) {}
|
||||
static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) {}
|
||||
void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) {}
|
||||
static void CClass_OverrideOVClassTree(OVClass *ovclass) {}
|
||||
static void CClass_AllocVTableRec(OVClass *ovclass) {}
|
||||
static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) {}
|
||||
static void CClass_AllocVTable(TypeClass *tclass) {}
|
||||
static Object *CClass_CheckVirtuals(TypeClass *tclass) {}
|
||||
static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) {}
|
||||
static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) {}
|
||||
void CClass_CheckOverrides(TypeClass *tclass) {}
|
||||
static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *base) {}
|
||||
static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *base) {}
|
||||
void CClass_ClassDefaultFuncAction(TypeClass *tclass) {}
|
||||
void CClass_ClassAction(TypeClass *tclass) {}
|
||||
void CClass_MakeStaticActionClass(TypeClass *tclass) {}
|
||||
Object *CClass_CheckPures(TypeClass *tclass) {}
|
||||
void CClass_MemberDef(Object *obj, TypeClass *tclass) {}
|
||||
Object *CClass_ThisSelfObject(void) {}
|
||||
ENode *CClass_CreateThisSelfExpr(void) {}
|
||||
static Boolean CClass_BaseMemberAccess(BClassList *path, AccessType access) {}
|
||||
static Boolean CClass_CanAccess(BClassList *path, AccessType access) {}
|
||||
void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) {}
|
||||
static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) {}
|
||||
void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) {}
|
||||
void CClass_CheckObjectAccess(BClassList *path, Object *obj) {}
|
||||
void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) {}
|
||||
static Type *CClass_PointerTypeCopy(Type *type) {}
|
||||
Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) {}
|
||||
static void CClass_OptimizeBitFieldAccess(Type **type, SInt32 *offset) {}
|
||||
ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) {}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "compiler/types.h"
|
||||
#include "pref_structs.h"
|
||||
#include "compiler/CompilerTools.h"
|
||||
#include "compiler/CPrep.h"
|
||||
|
||||
Boolean systemHandles;
|
||||
|
||||
@@ -11,14 +12,6 @@ Boolean crippled;
|
||||
SInt32 license_cookie;
|
||||
CParams cparams;
|
||||
|
||||
// TODO move me to CParser.c, or maybe CMachine.c?
|
||||
Type sttemplexpr = {TYPETEMPLDEPEXPR, 0};
|
||||
Type stillegal = {TYPEILLEGAL, 1};
|
||||
Type stvoid = {TYPEVOID, 0};
|
||||
TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0};
|
||||
TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0};
|
||||
// TODO move me to CParser.c
|
||||
|
||||
static void get_extension(ConstStringPtr src, char *dst) {
|
||||
int ep;
|
||||
|
||||
|
||||
4902
compiler_and_linker/unsorted/CDecl.c
Normal file
4902
compiler_and_linker/unsorted/CDecl.c
Normal file
File diff suppressed because it is too large
Load Diff
123
compiler_and_linker/unsorted/CExpr.c
Normal file
123
compiler_and_linker/unsorted/CExpr.c
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "compiler/CExpr.h"
|
||||
#include "compiler/CError.h"
|
||||
|
||||
Boolean (*name_obj_check)(void *, Object *); // TODO figure out the right type
|
||||
Boolean disallowgreaterthan;
|
||||
|
||||
void CExpr_RewriteConst() {}
|
||||
void optimizecomm() {}
|
||||
static void checkadditive() {}
|
||||
static void CExpr_CompareConvert() {}
|
||||
static void CExpr_ConstResult() {}
|
||||
static void makemultnode() {}
|
||||
static void makedivnode() {}
|
||||
static void canadd2() {}
|
||||
void canadd() {}
|
||||
static void addconst() {}
|
||||
static void integralpointerpromote() {}
|
||||
static void padd() {}
|
||||
static void psub() {}
|
||||
static void makeaddnode() {}
|
||||
static void makesubnode() {}
|
||||
void checkreference() {}
|
||||
static ENode *pointer_generation2(ENode *expr) {}
|
||||
ENode *pointer_generation(ENode *expr) {}
|
||||
void CExpr_PointerGeneration() {}
|
||||
static void CExpr_ConstPointerCheck() {}
|
||||
void oldassignmentpromotion() {}
|
||||
void argumentpromotion() {}
|
||||
void classargument() {}
|
||||
ENodeList *CExpr_ScanExpressionList(Boolean flag) {}
|
||||
static void skipcommaexpr() {}
|
||||
void CExpr_DoExplicitConversion() {}
|
||||
static void CExpr_TemplArgDepCast() {}
|
||||
static void CExpr_ParseExplicitConversion() {}
|
||||
static void CExpr_MemberVarAccess() {}
|
||||
static void CExpr_IsTemplateFunc() {}
|
||||
static void CExpr_ExplicitTemplateArgCheck() {}
|
||||
void CExpr_MakeNameLookupResultExpr() {}
|
||||
static void CExpr_NewPTMType() {}
|
||||
static void CExpr_ParseNameResultExpr() {}
|
||||
static void CExpr_ParseRotate() {}
|
||||
static void CExpr_ParseNextArg() {}
|
||||
static void CExpr_ParseVecStep() {}
|
||||
static void CExpr_BuiltInComputeAlign() {}
|
||||
static void CExpr_AtomTypeID() {}
|
||||
static void CExpr_BuiltInComputeType() {}
|
||||
static void CExpr_BuiltInClassifyType() {}
|
||||
static void CExpr_BuiltInComputeVArgType() {}
|
||||
static void CExpr_ParseTypeExpression() {}
|
||||
static void CExpr_ParseBuiltin() {}
|
||||
static void CExpr_ParseBuiltin_isintconst() {}
|
||||
static void primary_expression() {}
|
||||
static void CExpr_SimpleExplicitConversion() {}
|
||||
static void CExpr_NewPTMFCall() {}
|
||||
static void call_ptmf() {}
|
||||
static void CExpr_DummyDestr() {}
|
||||
static void postfix_expression() {}
|
||||
static void CExpr_ParseSizeof() {}
|
||||
void scansizeof() {}
|
||||
static void CExpr_ParseAlignof() {}
|
||||
void scanalignof() {}
|
||||
static void logicalexpression() {}
|
||||
void getnodeaddress() {}
|
||||
static void CExpr_MakeStaticMemberList() {}
|
||||
static void CExpr_MakePTDM() {}
|
||||
void getpointertomemberfunc() {}
|
||||
static void getpointertomember() {}
|
||||
void CExpr_New_ELOGNOT_Node() {}
|
||||
void CExpr_New_EMONMIN_Node() {}
|
||||
void CExpr_New_EBINNOT_Node() {}
|
||||
void unary_expression() {}
|
||||
void do_castnullcheck() {}
|
||||
void CExpr_SafeClassPointerCast() {}
|
||||
void PointerToMemberCast() {}
|
||||
void CExpr_MemberPointerConversion() {}
|
||||
static void CExpr_MemberPointerCast() {}
|
||||
void do_typecast() {}
|
||||
static void isvectorconst() {}
|
||||
void cast_expression() {}
|
||||
static void pm_expression() {}
|
||||
void CExpr_New_EMUL_Node() {}
|
||||
void CExpr_New_EDIV_Node() {}
|
||||
void CExpr_New_EMODULO_Node() {}
|
||||
void CExpr_New_EADD_Node() {}
|
||||
void CExpr_New_ESUB_Node() {}
|
||||
void CExpr_New_ESHL_Node() {}
|
||||
void CExpr_New_ESHR_Node() {}
|
||||
static void pointercompare() {}
|
||||
static void unsigncheck() {}
|
||||
void CExpr_New_ELESS_Node() {}
|
||||
void CExpr_New_ELESSEQU_Node() {}
|
||||
void CExpr_New_EGREATER_Node() {}
|
||||
void CExpr_New_EGREATEREQU_Node() {}
|
||||
void memberpointercompare() {}
|
||||
void CExpr_New_EEQU_Node() {}
|
||||
void CExpr_New_ENOTEQU_Node() {}
|
||||
void CExpr_New_EAND_Node() {}
|
||||
void CExpr_New_EXOR_Node() {}
|
||||
void CExpr_New_EOR_Node() {}
|
||||
void CExpr_New_ELAND_Node() {}
|
||||
void CExpr_New_ELOR_Node() {}
|
||||
void CExpr_NewDyadicNode() {}
|
||||
static void CExpr_GetDyadicInfo() {}
|
||||
static void CExpr_ParseDyadicExpression() {}
|
||||
static void CExpr_IsBlockMoveType() {}
|
||||
void CExpr_New_ECOND_Node() {}
|
||||
static void conditional_expression() {}
|
||||
static void CExpr_MakeOpAssNode() {}
|
||||
static void makeassignmentnode() {}
|
||||
static void makepassignmentnode() {}
|
||||
static void makemulassignmentnode() {}
|
||||
static void CExpr_TransformOpAssign() {}
|
||||
ENode *assignment_expression(void) {}
|
||||
ENode *conv_assignment_expression(void) {}
|
||||
static void CExpr_HasSideEffect() {}
|
||||
void CExpr_CheckUnusedExpression() {}
|
||||
void s_expression() {}
|
||||
ENode *expression(void) {}
|
||||
void CExpr_IntegralConstExprType() {}
|
||||
ENode *CExpr_IntegralConstOrDepExpr(void) {}
|
||||
void CExpr_IntegralConstExpr() {}
|
||||
void CExpr_CheckUnwantedAssignment() {}
|
||||
void CExpr_ParseAsmExpr() {}
|
||||
1934
compiler_and_linker/unsorted/CExpr2.c
Normal file
1934
compiler_and_linker/unsorted/CExpr2.c
Normal file
File diff suppressed because it is too large
Load Diff
105
compiler_and_linker/unsorted/CFunc.c
Normal file
105
compiler_and_linker/unsorted/CFunc.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "compiler/CFunc.h"
|
||||
#include "compiler/types.h"
|
||||
|
||||
FuncArg elipsis;
|
||||
FuncArg oldstyle;
|
||||
ObjectList *arguments;
|
||||
ObjectList *locals;
|
||||
short localcount;
|
||||
SInt32 curstmtvalue;
|
||||
SInt32 sourceoffset;
|
||||
HashNameNode *sourcefilepath;
|
||||
SInt32 functionbodyoffset;
|
||||
HashNameNode *functionbodypath;
|
||||
InitExpr *init_expressions;
|
||||
CLabel *Labels;
|
||||
CtorChain *ctor_chain;
|
||||
Statement *curstmt;
|
||||
static short temp_destructor_object_regmem;
|
||||
static short temp_destructor_objects;
|
||||
static short temp_expression_has_conditionals;
|
||||
static DeclBlock *firstblock;
|
||||
static DeclBlock *currentblock;
|
||||
static short blockcount;
|
||||
static Object *sinit_first_object;
|
||||
static CLabel *sinit_label;
|
||||
static Boolean ainit_only_one;
|
||||
static ENode *ainit_expr;
|
||||
static FuncArg *check_arglist;
|
||||
static Boolean cfunc_is_extern_c;
|
||||
static short cfunc_staticvarcount;
|
||||
static void *destroyobjects;
|
||||
static Boolean cfunc_hasdtortemp;
|
||||
|
||||
static void CFunc_LoopIncrement(void) {}
|
||||
static void CFunc_LoopDecrement(void) {}
|
||||
DeclBlock *CFunc_NewDeclBlock(void) {}
|
||||
void CFunc_RestoreBlock(DeclBlock *block) {}
|
||||
void CFunc_SetupLocalVarInfo(Object *obj) {}
|
||||
static void adjustargumenttype(DeclInfo *declinfo) {}
|
||||
static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) {}
|
||||
static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) {}
|
||||
static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) {}
|
||||
static void identifier_list(DeclInfo *declinfo) {}
|
||||
static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) {}
|
||||
void CFunc_DefaultArg(Type *type, short qual, FuncArg *args) {}
|
||||
static FuncArg *parameter_list(DeclInfo *declinfo) {}
|
||||
Boolean CFunc_ParseFakeArgList(Boolean flag) {}
|
||||
FuncArg *parameter_type_list(DeclInfo *declinfo) {}
|
||||
CLabel *findlabel(void) {}
|
||||
CLabel *newlabel(void) {}
|
||||
Statement *CFunc_AppendStatement(StatementType sttype) {}
|
||||
Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) {}
|
||||
Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) {}
|
||||
void CheckCLabels(void) {}
|
||||
Object *create_temp_object(Type *type) {}
|
||||
ENode *create_temp_node(Type *type) {}
|
||||
ENode *create_temp_node2(Type *type) {}
|
||||
static void CFunc_DestroyReverse() {} // not sure about type
|
||||
static void CFunc_TempTransDestroy() {} // not sure about type
|
||||
void CFunc_WarnUnused(void) {}
|
||||
void CFunc_CodeCleanup(Statement *stmt) {}
|
||||
static Boolean DestructorNeeded(ExceptionAction *a, ExceptionAction *b) {}
|
||||
static Statement *DestructLocals(Statement *stmt, ExceptionAction *exc1, ExceptionAction *exc2) {}
|
||||
static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) {}
|
||||
static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) {}
|
||||
static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) {}
|
||||
static Statement *DestructorIfTransform(Statement *stmt) {}
|
||||
static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) {}
|
||||
static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) {}
|
||||
void CFunc_DestructorCleanup(Statement *stmt) {}
|
||||
static void scancase(DeclThing *thing) {}
|
||||
static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) {}
|
||||
static void sinit_insert_expr(ENode *expr) {}
|
||||
static void ainit_insert_expr(ENode *expr) {}
|
||||
static ENode *ainit_register_object(TypeClass *tclass, Object *local, SInt32 offset, void *unk) {}
|
||||
static void CFunc_LocalDataDeclarator(DeclInfo *declinfo, TStreamElement *element, Boolean flag1, Boolean flag2) {}
|
||||
static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) {}
|
||||
static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) {}
|
||||
static void CFunc_HasDtorTempCallBack(ENode *expr) {}
|
||||
static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) {}
|
||||
Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *)) {}
|
||||
static Boolean checklabel(void) {}
|
||||
static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) {}
|
||||
static void CFunc_AutoResultCheck(ENode *expr) {}
|
||||
static void statement(DeclThing *thing) {}
|
||||
void CFunc_CompoundStatement(DeclThing *thing) {}
|
||||
static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) {}
|
||||
static void CFunc_AdjustOldStyleArgs(void) {}
|
||||
void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args) {}
|
||||
static ObjectList *CFunc_CopyObjectList(ObjectList *list) {}
|
||||
static void SetupFunctionArguments(Object *obj, DeclInfo *declinfo) {}
|
||||
NameSpace *CFunc_FuncGenSetup(Statement *stmt) {}
|
||||
void CFunc_GetGlobalCompilerState(CFuncSave *state) {}
|
||||
void CFunc_SetGlobalCompilerState(CFuncSave *state) {}
|
||||
void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk) {}
|
||||
static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) {}
|
||||
void CFunc_CheckClassCtors(TypeClass *tclass) {}
|
||||
static void CFunc_ParseCtorInitializer(void) {}
|
||||
static void CFunc_FunctionRedefinedCheck(Object *obj) {}
|
||||
static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) {}
|
||||
void CFunc_ParseFuncDef(Object *obj, DeclInfo *declinfo, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) {}
|
||||
void InitExpr_Register(ENode *expr, Object *object) {}
|
||||
void CFunc_GenerateDummyFunction(Object *a) {}
|
||||
void CFunc_GenerateSingleExprFunc(Object *a, ENode *expr) {}
|
||||
void CFunc_GenerateDummyCtorFunc(Object *a, Object *b) {}
|
||||
3107
compiler_and_linker/unsorted/CInit.c
Normal file
3107
compiler_and_linker/unsorted/CInit.c
Normal file
File diff suppressed because it is too large
Load Diff
116
compiler_and_linker/unsorted/CInline.c
Normal file
116
compiler_and_linker/unsorted/CInline.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "compiler/CInline.h"
|
||||
#include "compiler/CFunc.h"
|
||||
|
||||
static CInlineCopyMode enode_copymode;
|
||||
static Boolean enode_globalcopy;
|
||||
static void *enode_idtrans; // type?
|
||||
static void *local_dobjects; // type?
|
||||
static void *local_aobjects; // type?
|
||||
static CI_Var *loc_args;
|
||||
static CI_Var *loc_vars;
|
||||
static Boolean inline_expanded;
|
||||
static Boolean any_inline_expanded;
|
||||
static short cinline_level;
|
||||
static void *cinline_label_trans; // type?
|
||||
static Statement *cinline_first_stmt;
|
||||
static void *cinline_stmtlevelexpr[16]; // type?
|
||||
static short cinline_stmtlevelexprs;
|
||||
static Boolean cinline_unconditionalpart;
|
||||
static Boolean cinline_serialize_stmt;
|
||||
static void *cinline_exportlist; // type?
|
||||
static CI_Action *cinline_actionlist;
|
||||
CI_Action *cinline_tactionlist;
|
||||
static ObjectList *cinline_freflist;
|
||||
static Boolean cinline_gendeps;
|
||||
static Statement *cinline_serial_stmt;
|
||||
static Statement *cinline_cur_serial_stmt;
|
||||
static void *cinline_uid_temps; // type?
|
||||
static Boolean cinline_has_sideeffect;
|
||||
static SInt32 inline_max_size;
|
||||
static Boolean recursive_inline;
|
||||
static Object *expanding_function;
|
||||
static Boolean cinline_funccallfound;
|
||||
|
||||
void CInline_Init(void) {}
|
||||
static ENode *CInline_MakeNotNot(ENode *expr) {}
|
||||
static ENode *CInline_FoldConst(ENode *expr) {}
|
||||
SInt32 CInline_GetLocalID(Object *obj) {}
|
||||
static Boolean CInline_IsTrivialExpression(ENode *expr) {}
|
||||
Boolean CInline_ExpressionHasSideEffect(ENode *expr) {}
|
||||
static ENode *CInline_CopyExpressionSave(ENode *expr) {}
|
||||
static SInt32 CInline_TranslateID(SInt32 id) {}
|
||||
static SInt32 CInline_GetLabelStatementNumber(HashNameNode *name) {}
|
||||
static ENodeList *CInline_CopyNodeList(ENodeList *list) {}
|
||||
static EMemberInfo *CInline_CopyEMemberInfo(EMemberInfo *mi) {}
|
||||
static ENode *CInline_CopyNodes(ENode *node) {}
|
||||
static void CInline_CheckUsage(ENode *expr, Boolean flag) {}
|
||||
ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode) {}
|
||||
static UInt8 CInline_GetObjectSFlags(Object *obj) {}
|
||||
static void CInline_SetObjectSFlags(Object *obj, UInt8 sflags) {}
|
||||
static Object *CInline_NewLocalObject(Type *type, short qual, UInt8 sflags) {}
|
||||
static ENode *CInline_FuncArgConvert(ENode *expr) {}
|
||||
static ENode *CInline_RefArgTransform(ENode *expr, Boolean flag) {}
|
||||
static ENode *CInline_SetupArgsExpression(Object *obj, CI_FuncData *data, ENodeList *list) {}
|
||||
static void CInline_ReturnCheckCB(/* there should be args here */) {}
|
||||
static ENode *CInline_ReturnCheck(ENode *expr) {}
|
||||
static ENode *CInline_ReturnMemResult(void) {}
|
||||
static ENode *CInline_InlineFunctionExpression(ENode *expr) {}
|
||||
static Boolean CInline_CanExpand(ENode *expr) {}
|
||||
static SInt32 CInline_EstimateSizeOfExpr(ENode *expr, SInt32 a, SInt32 b) {}
|
||||
static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 a, SInt32 b) {}
|
||||
static SInt32 EstimateExpandedSizeOfExpr(ENode *expr, SInt32 b) {}
|
||||
static SInt32 EstimateExpandedSizeOfFunction(Statement *stmt) {}
|
||||
static Boolean CInline_InlineFunctionCheck(ENode *expr) {}
|
||||
static ENode *CInline_ExpandExpression(ENode *expr) {}
|
||||
static Statement *CInline_NewStatement(StatementType sttype) {}
|
||||
static ENode *CInline_LoadToTemp(ENode *expr, Object **obj) {}
|
||||
static ENode *CInline_SerializeEFORCELOAD(ENode *expr) {}
|
||||
static ENode *CInline_SerializeECOMMA(ENode *expr) {}
|
||||
static ENode *CInline_SerializeELOR(ENode *expr) {}
|
||||
static ENode *CInline_SerializeELAND(ENode *expr) {}
|
||||
static ENode *CInline_SerializeEPRECOMP(ENode *expr) {}
|
||||
static ENode *CInline_SerializeENULLCHECK(ENode *expr) {}
|
||||
static ENode *CInline_SerializeECOND(ENode *expr) {}
|
||||
static ENode *CInline_SerializeExpr(ENode *expr) {}
|
||||
void CInline_SerializeStatement(Statement *stmt) {}
|
||||
static void CInline_UnpackSwitch(Statement *stmt, CI_Statement *packed, CLabel **labels) {}
|
||||
Object *CInline_GetLocalObj(SInt32 id, Boolean flag) {}
|
||||
static ExceptionAction *CInline_UnpackActions(CI_Statement *packed, Boolean flag) {}
|
||||
static Statement *CInline_ExpandStatements(Object *obj, Statement *stmt, CI_FuncData *data, ENode *expr, CLabel *label, Object *obj2, Boolean flag) {}
|
||||
static Statement *CInline_InlineFunctionStatement(Statement *stmt, Boolean *success) {}
|
||||
static Statement *CInline_ExtractInlineFunction(Statement *stmt) {}
|
||||
static Statement *CInline_ExpandStatement(Statement *stmt) {}
|
||||
static void CInline_ForceReverseSearch(ENode *) {}
|
||||
static ENode *CInline_ForceReverseEvaluation(ENode *expr) {}
|
||||
static void CInline_ExportCheck(ENode *expr) {}
|
||||
static void CInline_Expand(Statement *stmt) {}
|
||||
SInt32 CInline_GetStatementNumber(Statement *first, Statement *stmt) {}
|
||||
static CI_Switch *CInline_PackSwitch(Statement *s1, Statement *s2) {}
|
||||
static Boolean CInline_CanInline(Object *obj, Statement *stmt) {}
|
||||
static ExceptionAction *CInline_PackActions(Statement *s1, Statement *s2) {}
|
||||
void CInline_PackIFunctionData(CI_FuncData *packed, Statement *stmt, Object *obj) {}
|
||||
void CInline_UnpackIFunctionData(Object *obj, CI_FuncData *packed, Statement *stmt) {}
|
||||
static void CInline_GenIFunctionCode(Object *obj, CI_FuncData *func, UInt8 unk) {}
|
||||
void CInline_AddDefaultFunctionAction(Object *obj) {}
|
||||
void CInline_AddInlineFunctionAction(Object *obj, TypeClass *tclass, FileOffsetInfo *fileoffset, TStream *stream, Boolean flag) {}
|
||||
void CInline_AddMemberFunctionAction(Object *obj, Type *a, Type *b, TemplateMember *tmemb) {}
|
||||
void CInline_AddTemplateFunctionAction(Object *obj, TemplateFunction *func, TemplFuncInstance *inst) {}
|
||||
static void CInline_AddFRefList_Object(Object *obj) {}
|
||||
static void CInline_AddFRefList_ExAction(ExceptionAction *exc) {}
|
||||
static void CInline_AddFRefList_ExprCB(ENode *expr) {}
|
||||
static void CInline_AddFRefList_Expr(ENode *expr) {}
|
||||
static void CInline_AddFRefList_Statement(Statement *stmt) {}
|
||||
static void CInline_AddFRefList_InlineFunc(CI_FuncData *data) {}
|
||||
static void CInline_GenerateTemplateInline(Object *obj) {}
|
||||
void CInline_ObjectAddrRef(Object *obj) {}
|
||||
static Boolean CInline_CheckDependencies(ObjectList *list) {}
|
||||
static Boolean CInline_IsSmallFunction(Object *obj, Statement *stmt) {}
|
||||
static Boolean CInline_NoFPLocals(void) {}
|
||||
void CInline_GenFunc(Statement *stmt, Object *obj, UInt8 unk) {}
|
||||
static void CInline_GenerateDefaultFunc(Object *obj) {}
|
||||
static TemplClassInst *CInline_FindNestedTemplInst(TemplClassInst *inst) {}
|
||||
static void CInline_GenerateInlineFunc(CI_Action *action) {}
|
||||
Boolean CInline_CanFreeLHeap(void) {}
|
||||
Boolean CInline_GenerateDeferredFuncs(void) {}
|
||||
static InitExpr *CInline_InitTemplateData(InitExpr *init) {}
|
||||
void CInline_Finish(void) {}
|
||||
@@ -186,6 +186,7 @@ SInt32 CMach_ArgumentAlignment(Type *type) {
|
||||
return align;
|
||||
}
|
||||
|
||||
// TODO: investigate if this returns SInt16 actually
|
||||
SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual) {
|
||||
SInt32 align;
|
||||
SInt32 qualalign;
|
||||
@@ -573,7 +574,7 @@ void CMach_InitIntMem(Type *type, CInt64 val, void *mem) {
|
||||
}
|
||||
}
|
||||
|
||||
void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem) {
|
||||
void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem, Boolean flag) {
|
||||
unsigned char uc[16];
|
||||
unsigned short us[8];
|
||||
unsigned int ul[4];
|
||||
@@ -856,7 +857,7 @@ static SInt16 CMach_GetQualifiedStructAlign(TypeStruct *tstruct, Boolean flag) {
|
||||
|
||||
switch (copts.align_mode) {
|
||||
case AlignMode3_1Byte:
|
||||
case AlignMode8:
|
||||
case AlignMode8_Packed:
|
||||
return 1;
|
||||
case AlignMode0_Mac68k:
|
||||
return 2;
|
||||
@@ -941,7 +942,7 @@ static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) {
|
||||
|
||||
switch (copts.align_mode) {
|
||||
case AlignMode3_1Byte:
|
||||
case AlignMode8:
|
||||
case AlignMode8_Packed:
|
||||
return 1;
|
||||
case AlignMode0_Mac68k:
|
||||
return 2;
|
||||
@@ -1047,7 +1048,7 @@ static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag) {
|
||||
|
||||
switch (copts.align_mode) {
|
||||
case AlignMode3_1Byte:
|
||||
case AlignMode8:
|
||||
case AlignMode8_Packed:
|
||||
return 1;
|
||||
case AlignMode4_2Byte:
|
||||
case AlignMode5_4Byte:
|
||||
@@ -1166,7 +1167,7 @@ static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 var, Boolean flag) {
|
||||
align = 16;
|
||||
|
||||
switch (copts.align_mode) {
|
||||
case AlignMode8:
|
||||
case AlignMode8_Packed:
|
||||
align = 1;
|
||||
break;
|
||||
case AlignMode0_Mac68k:
|
||||
@@ -1266,7 +1267,7 @@ SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) {
|
||||
|
||||
switch (copts.align_mode) {
|
||||
case AlignMode3_1Byte:
|
||||
case AlignMode8:
|
||||
case AlignMode8_Packed:
|
||||
required_alignment = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
719
compiler_and_linker/unsorted/CMangler.c
Normal file
719
compiler_and_linker/unsorted/CMangler.c
Normal file
@@ -0,0 +1,719 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/CInt64.h"
|
||||
#include "compiler/enode.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler/scopes.h"
|
||||
#include "compiler/templates.h"
|
||||
#include "compiler/types.h"
|
||||
#include "cos.h"
|
||||
|
||||
HashNameNode *constructor_name_node;
|
||||
HashNameNode *destructor_name_node;
|
||||
HashNameNode *asop_name_node;
|
||||
|
||||
// forward decls
|
||||
static void CMangler_MangleClassName(TypeClass *tclass);
|
||||
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual);
|
||||
static void CMangler_MangleArgs(FuncArg *args);
|
||||
|
||||
void CMangler_Setup(void) {
|
||||
constructor_name_node = GetHashNameNodeExport("__ct");
|
||||
destructor_name_node = GetHashNameNodeExport("__dt");
|
||||
asop_name_node = GetHashNameNodeExport("__as");
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_BasicDtorName(void) {
|
||||
return GetHashNameNodeExport("__dtb");
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_VBaseDtorName(void) {
|
||||
return GetHashNameNodeExport("__dtv");
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_ArrayDtorName(void) {
|
||||
return GetHashNameNodeExport("__dta");
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_SDeleteDtorName(void) {
|
||||
return GetHashNameNodeExport("__dts");
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_DeleteDtorName(void) {
|
||||
return GetHashNameNodeExport("__dt");
|
||||
}
|
||||
|
||||
char *CMangler_GetOperator(HashNameNode *opname) {
|
||||
char *name;
|
||||
|
||||
if (opname == asop_name_node)
|
||||
return "operator=";
|
||||
|
||||
name = opname->name;
|
||||
if (!strcmp(name, "__nw")) return "operator new";
|
||||
if (!strcmp(name, "__dl")) return "operator delete";
|
||||
if (!strcmp(name, "__nwa")) return "operator new[]";
|
||||
if (!strcmp(name, "__dla")) return "operator delete[]";
|
||||
if (!strcmp(name, "__pl")) return "operator+";
|
||||
if (!strcmp(name, "__mi")) return "operator-";
|
||||
if (!strcmp(name, "__ml")) return "operator*";
|
||||
if (!strcmp(name, "__dv")) return "operator/";
|
||||
if (!strcmp(name, "__md")) return "operator%";
|
||||
if (!strcmp(name, "__er")) return "operator^";
|
||||
if (!strcmp(name, "__ad")) return "operator&";
|
||||
if (!strcmp(name, "__or")) return "operator|";
|
||||
if (!strcmp(name, "__co")) return "operator~";
|
||||
if (!strcmp(name, "__nt")) return "operator!";
|
||||
if (!strcmp(name, "__lt")) return "operator<";
|
||||
if (!strcmp(name, "__gt")) return "operator>";
|
||||
if (!strcmp(name, "__apl")) return "operator+=";
|
||||
if (!strcmp(name, "__ami")) return "operator-=";
|
||||
if (!strcmp(name, "__amu")) return "operator*=";
|
||||
if (!strcmp(name, "__adv")) return "operator/=";
|
||||
if (!strcmp(name, "__amd")) return "operator%=";
|
||||
if (!strcmp(name, "__aer")) return "operator^=";
|
||||
if (!strcmp(name, "__aad")) return "operator&=";
|
||||
if (!strcmp(name, "__aor")) return "operator|=";
|
||||
if (!strcmp(name, "__ls")) return "operator<<";
|
||||
if (!strcmp(name, "__rs")) return "operator>>";
|
||||
if (!strcmp(name, "__als")) return "operator<<=";
|
||||
if (!strcmp(name, "__ars")) return "operator>>=";
|
||||
if (!strcmp(name, "__eq")) return "operator==";
|
||||
if (!strcmp(name, "__ne")) return "operator!=";
|
||||
if (!strcmp(name, "__le")) return "operator<=";
|
||||
if (!strcmp(name, "__ge")) return "operator>=";
|
||||
if (!strcmp(name, "__aa")) return "operator&&";
|
||||
if (!strcmp(name, "__oo")) return "operator||";
|
||||
if (!strcmp(name, "__pp")) return "operator++";
|
||||
if (!strcmp(name, "__mm")) return "operator--";
|
||||
if (!strcmp(name, "__cm")) return "operator,";
|
||||
if (!strcmp(name, "__rm")) return "operator->*";
|
||||
if (!strcmp(name, "__rf")) return "operator*";
|
||||
if (!strcmp(name, "__cl")) return "operator()";
|
||||
if (!strcmp(name, "__vc")) return "operator[]";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_OperatorName(short token) {
|
||||
switch (token) {
|
||||
case TK_NEW: return GetHashNameNodeExport("__nw");
|
||||
case TK_DELETE: return GetHashNameNodeExport("__dl");
|
||||
case TK_NEW_ARRAY: return GetHashNameNodeExport("__nwa");
|
||||
case TK_DELETE_ARRAY: return GetHashNameNodeExport("__dla");
|
||||
case '+': return GetHashNameNodeExport("__pl");
|
||||
case '-': return GetHashNameNodeExport("__mi");
|
||||
case '*': return GetHashNameNodeExport("__ml");
|
||||
case '/': return GetHashNameNodeExport("__dv");
|
||||
case '%': return GetHashNameNodeExport("__md");
|
||||
case '^': return GetHashNameNodeExport("__er");
|
||||
case '&': return GetHashNameNodeExport("__ad");
|
||||
case '|': return GetHashNameNodeExport("__or");
|
||||
case '~': return GetHashNameNodeExport("__co");
|
||||
case '!': return GetHashNameNodeExport("__nt");
|
||||
case '=': return asop_name_node;
|
||||
case '<': return GetHashNameNodeExport("__lt");
|
||||
case '>': return GetHashNameNodeExport("__gt");
|
||||
case TK_ADD_ASSIGN: return GetHashNameNodeExport("__apl");
|
||||
case TK_SUB_ASSIGN: return GetHashNameNodeExport("__ami");
|
||||
case TK_MULT_ASSIGN: return GetHashNameNodeExport("__amu");
|
||||
case TK_DIV_ASSIGN: return GetHashNameNodeExport("__adv");
|
||||
case TK_MOD_ASSIGN: return GetHashNameNodeExport("__amd");
|
||||
case TK_XOR_ASSIGN: return GetHashNameNodeExport("__aer");
|
||||
case TK_AND_ASSIGN: return GetHashNameNodeExport("__aad");
|
||||
case TK_OR_ASSIGN: return GetHashNameNodeExport("__aor");
|
||||
case TK_SHL: return GetHashNameNodeExport("__ls");
|
||||
case TK_SHR: return GetHashNameNodeExport("__rs");
|
||||
case TK_SHL_ASSIGN: return GetHashNameNodeExport("__als");
|
||||
case TK_SHR_ASSIGN: return GetHashNameNodeExport("__ars");
|
||||
case TK_LOGICAL_EQ: return GetHashNameNodeExport("__eq");
|
||||
case TK_LOGICAL_NE: return GetHashNameNodeExport("__ne");
|
||||
case TK_LESS_EQUAL: return GetHashNameNodeExport("__le");
|
||||
case TK_GREATER_EQUAL: return GetHashNameNodeExport("__ge");
|
||||
case TK_LOGICAL_AND: return GetHashNameNodeExport("__aa");
|
||||
case TK_LOGICAL_OR: return GetHashNameNodeExport("__oo");
|
||||
case TK_INCREMENT: return GetHashNameNodeExport("__pp");
|
||||
case TK_DECREMENT: return GetHashNameNodeExport("__mm");
|
||||
case ',': return GetHashNameNodeExport("__cm");
|
||||
case TK_ARROW_STAR: return GetHashNameNodeExport("__rm");
|
||||
case TK_ARROW: return GetHashNameNodeExport("__rf");
|
||||
case '(': return GetHashNameNodeExport("__cl");
|
||||
case '[': return GetHashNameNodeExport("__vc");
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_VTableName(TypeClass *tclass) {
|
||||
HashNameNode *name;
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListName(&name_mangle_list, "__vt__");
|
||||
CMangler_MangleClassName(tclass);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) {
|
||||
HashNameNode *name;
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListName(&name_mangle_list, "__RTTI__");
|
||||
CMangler_MangleTypeAppend(type, qual);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_ThunkName(Object *obj, int a, int b, int c) {
|
||||
HashNameNode *linkname;
|
||||
HashNameNode *name;
|
||||
char buf[64];
|
||||
|
||||
linkname = CMangler_GetLinkName(obj);
|
||||
name_mangle_list.size = 0;
|
||||
if (b == 0) {
|
||||
if (c < 0)
|
||||
sprintf(buf, "_@%ld@", -a);
|
||||
else
|
||||
sprintf(buf, "_@%ld@%ld@", -a, c);
|
||||
} else {
|
||||
sprintf(buf, "_@%ld@%ld@%ld@", -a, c, b);
|
||||
}
|
||||
AppendGListName(&name_mangle_list, buf);
|
||||
AppendGListID(&name_mangle_list, linkname->name + 1);
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
static void CMangler_CheckTemplateArguments(TemplArg *arg) {
|
||||
ENode *expr;
|
||||
|
||||
while (arg) {
|
||||
if (arg->pid.type == TPT_NONTYPE) {
|
||||
expr = arg->data.paramdecl.expr;
|
||||
#line 360
|
||||
CError_ASSERT(expr);
|
||||
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
||||
switch (expr->type) {
|
||||
case EINTCONST:
|
||||
break;
|
||||
case EOBJREF:
|
||||
CMangler_GetLinkName(expr->data.objref);
|
||||
break;
|
||||
default:
|
||||
#line 383
|
||||
CError_FATAL();
|
||||
}
|
||||
}
|
||||
}
|
||||
arg = arg->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
|
||||
ENode *expr;
|
||||
char buf[32];
|
||||
|
||||
AppendGListByte(&name_mangle_list, '<');
|
||||
|
||||
while (arg) {
|
||||
if (arg->pid.type == TPT_NONTYPE) {
|
||||
expr = arg->data.paramdecl.expr;
|
||||
#line 409
|
||||
CError_ASSERT(expr);
|
||||
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
|
||||
switch (expr->type) {
|
||||
case EINTCONST:
|
||||
CInt64_PrintDec(buf, expr->data.intval);
|
||||
AppendGListName(&name_mangle_list, buf);
|
||||
break;
|
||||
case EOBJREF:
|
||||
AppendGListByte(&name_mangle_list, '&');
|
||||
AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
|
||||
break;
|
||||
default:
|
||||
#line 452
|
||||
CError_FATAL();
|
||||
}
|
||||
} else {
|
||||
AppendGListByte(&name_mangle_list, 'T');
|
||||
}
|
||||
} else if (arg->pid.type == TPT_TYPE) {
|
||||
CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
|
||||
} else {
|
||||
#line 467
|
||||
CError_ASSERT(arg->pid.type == TPT_TEMPLATE);
|
||||
CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
|
||||
}
|
||||
|
||||
if (arg->next)
|
||||
AppendGListByte(&name_mangle_list, ',');
|
||||
arg = arg->next;
|
||||
}
|
||||
|
||||
AppendGListByte(&name_mangle_list, '>');
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args) {
|
||||
HashNameNode *name;
|
||||
|
||||
CMangler_CheckTemplateArguments(args);
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListName(&name_mangle_list, basename->name);
|
||||
CMangler_AppendTemplateArgumentList(args);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
static void CMangler_MangleTypeName(char *str) {
|
||||
char buf[16];
|
||||
|
||||
sprintf(buf, "%d", strlen(str));
|
||||
AppendGListName(&name_mangle_list, buf);
|
||||
AppendGListName(&name_mangle_list, str);
|
||||
}
|
||||
|
||||
static void CMangler_MangleNameSpaceName(NameSpace *nspace, char *str) {
|
||||
char *stack[10];
|
||||
int stackp;
|
||||
|
||||
stack[0] = str;
|
||||
stackp = 1;
|
||||
while (nspace) {
|
||||
if (nspace->name) {
|
||||
stack[stackp++] = nspace->name->name;
|
||||
if (stackp >= 9)
|
||||
break;
|
||||
}
|
||||
nspace = nspace->parent;
|
||||
}
|
||||
|
||||
if (stackp > 1) {
|
||||
AppendGListByte(&name_mangle_list, 'Q');
|
||||
AppendGListByte(&name_mangle_list, '0' + stackp);
|
||||
}
|
||||
|
||||
while (--stackp >= 0)
|
||||
CMangler_MangleTypeName(stack[stackp]);
|
||||
}
|
||||
|
||||
static void CMangler_MangleClassName(TypeClass *tclass) {
|
||||
if (!tclass->classname)
|
||||
CMangler_MangleNameSpaceName(tclass->nspace->parent, "class");
|
||||
else
|
||||
CMangler_MangleNameSpaceName(tclass->nspace->parent, tclass->nspace->name->name);
|
||||
}
|
||||
|
||||
static void CMangler_MangleQualifier(UInt32 qual) {
|
||||
if (qual & Q_CONST)
|
||||
AppendGListByte(&name_mangle_list, 'C');
|
||||
if (qual & Q_VOLATILE)
|
||||
AppendGListByte(&name_mangle_list, 'V');
|
||||
}
|
||||
|
||||
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
|
||||
char buf[16];
|
||||
|
||||
switch (type->type) {
|
||||
case TYPEVOID:
|
||||
CMangler_MangleQualifier(qual);
|
||||
AppendGListByte(&name_mangle_list, 'v');
|
||||
break;
|
||||
case TYPEINT:
|
||||
case TYPEFLOAT:
|
||||
CMangler_MangleQualifier(qual);
|
||||
switch (TYPE_INTEGRAL(type)->integral) {
|
||||
case IT_BOOL:
|
||||
AppendGListByte(&name_mangle_list, 'b');
|
||||
return;
|
||||
case IT_CHAR:
|
||||
AppendGListByte(&name_mangle_list, 'c');
|
||||
return;
|
||||
case IT_WCHAR_T:
|
||||
AppendGListByte(&name_mangle_list, 'w');
|
||||
return;
|
||||
case IT_UCHAR:
|
||||
AppendGListName(&name_mangle_list, "Uc");
|
||||
return;
|
||||
case IT_SCHAR:
|
||||
AppendGListName(&name_mangle_list, "Sc");
|
||||
return;
|
||||
case IT_SHORT:
|
||||
AppendGListByte(&name_mangle_list, 's');
|
||||
return;
|
||||
case IT_USHORT:
|
||||
AppendGListName(&name_mangle_list, "Us");
|
||||
return;
|
||||
case IT_INT:
|
||||
AppendGListByte(&name_mangle_list, 'i');
|
||||
return;
|
||||
case IT_UINT:
|
||||
AppendGListName(&name_mangle_list, "Ui");
|
||||
return;
|
||||
case IT_LONG:
|
||||
AppendGListByte(&name_mangle_list, 'l');
|
||||
return;
|
||||
case IT_ULONG:
|
||||
AppendGListName(&name_mangle_list, "Ul");
|
||||
return;
|
||||
case IT_LONGLONG:
|
||||
AppendGListByte(&name_mangle_list, 'x');
|
||||
return;
|
||||
case IT_ULONGLONG:
|
||||
AppendGListName(&name_mangle_list, "Ux");
|
||||
return;
|
||||
case IT_FLOAT:
|
||||
AppendGListByte(&name_mangle_list, 'f');
|
||||
return;
|
||||
case IT_SHORTDOUBLE:
|
||||
AppendGListByte(&name_mangle_list, 'D');
|
||||
return;
|
||||
case IT_DOUBLE:
|
||||
AppendGListByte(&name_mangle_list, 'd');
|
||||
return;
|
||||
case IT_LONGDOUBLE:
|
||||
AppendGListByte(&name_mangle_list, 'r');
|
||||
return;
|
||||
default:
|
||||
#line 619
|
||||
CError_FATAL();
|
||||
}
|
||||
case TYPEENUM:
|
||||
CMangler_MangleQualifier(qual);
|
||||
if (!TYPE_ENUM(type)->enumname)
|
||||
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, "enum");
|
||||
else
|
||||
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, TYPE_ENUM(type)->enumname->name);
|
||||
break;
|
||||
case TYPEPOINTER:
|
||||
CMangler_MangleQualifier(TYPE_POINTER(type)->qual);
|
||||
if (TYPE_POINTER(type)->qual & Q_REFERENCE)
|
||||
AppendGListByte(&name_mangle_list, 'R');
|
||||
else
|
||||
AppendGListByte(&name_mangle_list, 'P');
|
||||
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
|
||||
break;
|
||||
case TYPEMEMBERPOINTER:
|
||||
if (TYPE_MEMBER_POINTER(type)->ty2->type != TYPECLASS) {
|
||||
AppendGListName(&name_mangle_list, "3<T>");
|
||||
} else {
|
||||
CMangler_MangleQualifier(TYPE_MEMBER_POINTER(type)->qual);
|
||||
AppendGListByte(&name_mangle_list, 'M');
|
||||
CMangler_MangleClassName(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
|
||||
CMangler_MangleTypeAppend(TYPE_MEMBER_POINTER(type)->ty1, qual);
|
||||
}
|
||||
break;
|
||||
case TYPEARRAY:
|
||||
AppendGListByte(&name_mangle_list, 'A');
|
||||
if (TYPE_POINTER(type)->target->size) {
|
||||
sprintf(buf, "%ld", type->size / TYPE_POINTER(type)->target->size);
|
||||
AppendGListName(&name_mangle_list, buf);
|
||||
} else {
|
||||
AppendGListByte(&name_mangle_list, '0');
|
||||
}
|
||||
AppendGListByte(&name_mangle_list, '_');
|
||||
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
|
||||
break;
|
||||
case TYPEFUNC:
|
||||
CMangler_MangleQualifier(qual);
|
||||
AppendGListByte(&name_mangle_list, 'F');
|
||||
CMangler_MangleArgs(TYPE_FUNC(type)->args);
|
||||
AppendGListByte(&name_mangle_list, '_');
|
||||
CMangler_MangleTypeAppend(TYPE_FUNC(type)->functype, TYPE_FUNC(type)->qual);
|
||||
break;
|
||||
case TYPESTRUCT:
|
||||
CMangler_MangleQualifier(qual);
|
||||
switch (TYPE_STRUCT(type)->stype) {
|
||||
case STRUCT_TYPE_4:
|
||||
AppendGListName(&name_mangle_list, "XUc");
|
||||
return;
|
||||
case STRUCT_TYPE_5:
|
||||
AppendGListName(&name_mangle_list, "Xc");
|
||||
return;
|
||||
case STRUCT_TYPE_6:
|
||||
AppendGListName(&name_mangle_list, "XC");
|
||||
return;
|
||||
case STRUCT_TYPE_7:
|
||||
AppendGListName(&name_mangle_list, "XUs");
|
||||
return;
|
||||
case STRUCT_TYPE_8:
|
||||
AppendGListName(&name_mangle_list, "Xs");
|
||||
return;
|
||||
case STRUCT_TYPE_9:
|
||||
AppendGListName(&name_mangle_list, "XS");
|
||||
return;
|
||||
case STRUCT_TYPE_A:
|
||||
AppendGListName(&name_mangle_list, "XUi");
|
||||
return;
|
||||
case STRUCT_TYPE_B:
|
||||
AppendGListName(&name_mangle_list, "Xi");
|
||||
return;
|
||||
case STRUCT_TYPE_C:
|
||||
AppendGListName(&name_mangle_list, "XI");
|
||||
return;
|
||||
case STRUCT_TYPE_D:
|
||||
AppendGListName(&name_mangle_list, "Xf");
|
||||
return;
|
||||
case STRUCT_TYPE_E:
|
||||
AppendGListName(&name_mangle_list, "Xp");
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_STRUCT(type)->name && !IsTempName(TYPE_STRUCT(type)->name)) {
|
||||
CMangler_MangleTypeName(TYPE_STRUCT(type)->name->name);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (TYPE_STRUCT(type)->stype) {
|
||||
case STRUCT_TYPE_STRUCT:
|
||||
AppendGListName(&name_mangle_list, "struct");
|
||||
break;
|
||||
case STRUCT_TYPE_UNION:
|
||||
AppendGListName(&name_mangle_list, "union");
|
||||
break;
|
||||
case STRUCT_TYPE_CLASS:
|
||||
AppendGListName(&name_mangle_list, "class");
|
||||
break;
|
||||
default:
|
||||
#line 701
|
||||
CError_FATAL();
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPECLASS:
|
||||
CMangler_MangleQualifier(qual);
|
||||
CMangler_MangleClassName(TYPE_CLASS(type));
|
||||
break;
|
||||
|
||||
case TYPETEMPLATE:
|
||||
AppendGListName(&name_mangle_list, "1T");
|
||||
break;
|
||||
|
||||
default:
|
||||
#line 716
|
||||
CError_FATAL();
|
||||
}
|
||||
}
|
||||
|
||||
void CMangler_MangleType(Type *type, UInt32 qual) {
|
||||
name_mangle_list.size = 0;
|
||||
CMangler_MangleTypeAppend(type, qual);
|
||||
}
|
||||
|
||||
static void CMangler_MangleArgs(FuncArg *args) {
|
||||
TypePointer ptr;
|
||||
|
||||
if (args) {
|
||||
if (args->type) {
|
||||
while (args) {
|
||||
if (args != &elipsis && args != &oldstyle) {
|
||||
if (args->type->type == TYPEPOINTER) {
|
||||
ptr = *TYPE_POINTER(args->type);
|
||||
ptr.qual &= ~(Q_CONST | Q_VOLATILE);
|
||||
CMangler_MangleTypeAppend((Type *) &ptr, args->qual);
|
||||
} else {
|
||||
CMangler_MangleTypeAppend(args->type, 0);
|
||||
}
|
||||
} else {
|
||||
AppendGListByte(&name_mangle_list, 'e');
|
||||
}
|
||||
args = args->next;
|
||||
}
|
||||
} else {
|
||||
AppendGListByte(&name_mangle_list, 'e');
|
||||
}
|
||||
} else {
|
||||
AppendGListByte(&name_mangle_list, 'v');
|
||||
}
|
||||
}
|
||||
|
||||
static void CMangler_MangleFunction(Object *obj, NameSpace *nspace) {
|
||||
TypeFunc *tfunc = TYPE_FUNC(obj->type);
|
||||
FuncArg *arg = tfunc->args;
|
||||
|
||||
AppendGListName(&name_mangle_list, obj->name->name);
|
||||
if (obj->u.func.inst) {
|
||||
if (tfunc->flags & FUNC_FLAGS_40)
|
||||
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
|
||||
CMangler_AppendTemplateArgumentList(obj->u.func.inst->args);
|
||||
}
|
||||
AppendGListName(&name_mangle_list, "__");
|
||||
while (nspace && nspace->name == NULL)
|
||||
nspace = nspace->parent;
|
||||
|
||||
if (nspace) {
|
||||
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
|
||||
if (nspace->theclass) {
|
||||
if (obj->name == destructor_name_node) {
|
||||
AppendGListName(&name_mangle_list, "Fv");
|
||||
return;
|
||||
}
|
||||
if (arg) {
|
||||
if (obj->name == constructor_name_node) {
|
||||
arg = arg->next;
|
||||
if (arg && (nspace->theclass->flags & CLASS_FLAGS_20))
|
||||
arg = arg->next;
|
||||
} else {
|
||||
if ((tfunc->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) {
|
||||
CMangler_MangleQualifier(arg->qual);
|
||||
arg = arg->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppendGListByte(&name_mangle_list, 'F');
|
||||
CMangler_MangleArgs(arg);
|
||||
if (obj->u.func.inst && copts.new_mangler) {
|
||||
AppendGListByte(&name_mangle_list, '_');
|
||||
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
|
||||
}
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual) {
|
||||
HashNameNode *name;
|
||||
|
||||
if (CTemplTool_IsTemplateArgumentDependentType(type))
|
||||
return GetHashNameNodeExport("__op");
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListName(&name_mangle_list, "__op");
|
||||
CMangler_MangleTypeAppend(type, qual);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
static HashNameNode *CMangler_MangleNameToUpper(char *str) {
|
||||
HashNameNode *name;
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
while (*str) {
|
||||
AppendGListByte(&name_mangle_list, toupper(*(str++)));
|
||||
}
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
static HashNameNode *CMangler_FunctionLinkName(Object *obj) {
|
||||
HashNameNode *name;
|
||||
NameSpace *nspace;
|
||||
|
||||
if (obj->u.func.inst)
|
||||
CMangler_CheckTemplateArguments(obj->u.func.inst->args);
|
||||
|
||||
for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
|
||||
if (nspace->name)
|
||||
break;
|
||||
}
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
if (is_pascal_object(obj) && (!nspace || !nspace->theclass)) {
|
||||
AppendGListData(&name_mangle_list, "_", 1);
|
||||
AppendGListID(&name_mangle_list, obj->name->name);
|
||||
} else if ((obj->qual & Q_80000) && (strcmp("main", obj->name->name) || (obj->nspace != cscope_root))) {
|
||||
AppendGListData(&name_mangle_list, "_", 1);
|
||||
CMangler_MangleFunction(obj, nspace);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
} else {
|
||||
AppendGListData(&name_mangle_list, "_", 1);
|
||||
AppendGListID(&name_mangle_list, obj->name->name);
|
||||
}
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_GetCovariantFunctionName(Object *obj, Type *type) {
|
||||
HashNameNode *linkname;
|
||||
HashNameNode *name;
|
||||
|
||||
linkname = CMangler_GetLinkName(obj);
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListName(&name_mangle_list, linkname->name);
|
||||
AppendGListName(&name_mangle_list, "@@");
|
||||
CMangler_MangleTypeAppend(type, 0);
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
static HashNameNode *CMangler_DataLinkName(Object *obj) {
|
||||
NameSpace *nspace;
|
||||
HashNameNode *name;
|
||||
|
||||
nspace = obj->nspace;
|
||||
while (nspace && nspace->name == NULL)
|
||||
nspace = nspace->parent;
|
||||
|
||||
name_mangle_list.size = 0;
|
||||
AppendGListData(&name_mangle_list, "_", 1);
|
||||
AppendGListName(&name_mangle_list, obj->name->name);
|
||||
|
||||
while (nspace && nspace->name == NULL)
|
||||
nspace = nspace->parent;
|
||||
if (nspace && (obj->qual & Q_80000)) {
|
||||
AppendGListName(&name_mangle_list, "__");
|
||||
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
|
||||
}
|
||||
AppendGListByte(&name_mangle_list, 0);
|
||||
|
||||
COS_LockHandle(name_mangle_list.data);
|
||||
name = GetHashNameNodeExport(*name_mangle_list.data);
|
||||
COS_UnlockHandle(name_mangle_list.data);
|
||||
return name;
|
||||
}
|
||||
|
||||
HashNameNode *CMangler_GetLinkName(Object *obj) {
|
||||
while (obj->datatype == DALIAS)
|
||||
obj = obj->u.alias.object;
|
||||
|
||||
switch (obj->datatype) {
|
||||
case DFUNC:
|
||||
case DVFUNC:
|
||||
if (!obj->u.func.linkname)
|
||||
obj->u.func.linkname = CMangler_FunctionLinkName(obj);
|
||||
return obj->u.func.linkname;
|
||||
case DDATA:
|
||||
if (!obj->u.data.linkname)
|
||||
obj->u.data.linkname = CMangler_DataLinkName(obj);
|
||||
return obj->u.data.linkname;
|
||||
case DINLINEFUNC:
|
||||
return CMangler_FunctionLinkName(obj);
|
||||
case DLOCAL:
|
||||
case DABSOLUTE:
|
||||
case DLABEL:
|
||||
return obj->name;
|
||||
case DNONLAZYPTR:
|
||||
if (!obj->u.toc.linkname)
|
||||
obj->u.toc.linkname = CMangler_DataLinkName(obj);
|
||||
return obj->u.toc.linkname;
|
||||
default:
|
||||
#line 1110
|
||||
CError_FATAL();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
3520
compiler_and_linker/unsorted/CParser.c
Normal file
3520
compiler_and_linker/unsorted/CParser.c
Normal file
File diff suppressed because it is too large
Load Diff
697
compiler_and_linker/unsorted/CodeGen.c
Normal file
697
compiler_and_linker/unsorted/CodeGen.c
Normal file
@@ -0,0 +1,697 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/PCode.h"
|
||||
#include "compiler/PCodeInfo.h"
|
||||
#include "compiler/PCodeUtilities.h"
|
||||
#include "compiler/enode.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler/tokens.h"
|
||||
#include "compiler/types.h"
|
||||
|
||||
static Macro powcM;
|
||||
static Macro __powcM;
|
||||
static Macro ppc_cpu;
|
||||
static Macro profM;
|
||||
static Macro hostM;
|
||||
static Macro bendM;
|
||||
static Macro _ppc_M;
|
||||
static Macro longI;
|
||||
static Macro IEEED;
|
||||
Macro vecM;
|
||||
Macro altivecM;
|
||||
static Macro macM2;
|
||||
static Macro appleM;
|
||||
static Macro optM;
|
||||
static Macro alignM;
|
||||
static Macro _machM;
|
||||
static Macro archM;
|
||||
static Macro dynM;
|
||||
static Macro ppcM;
|
||||
Object *gFunction;
|
||||
static ObjectList *temps;
|
||||
PCodeLabel *returnlabel;
|
||||
PCodeLabel *cleanreturnlabel;
|
||||
Boolean needs_cleanup;
|
||||
Statement *current_statement;
|
||||
int has_catch_blocks;
|
||||
int disable_optimizer;
|
||||
SInt32 current_linenumber;
|
||||
Boolean has_altivec_arrays;
|
||||
short high_reg;
|
||||
short low_reg;
|
||||
short high_offset;
|
||||
short low_offset;
|
||||
short low_reg2;
|
||||
short high_reg2;
|
||||
PCodeLabel *pic_base_pcodelabel;
|
||||
Object *dyld_stub_binding_helper;
|
||||
Object *rt_cvt_fp2unsigned;
|
||||
Object *rt_profile_entry;
|
||||
Object *rt_profile_exit;
|
||||
Object *rt_div2i;
|
||||
Object *rt_div2u;
|
||||
Object *rt_mod2i;
|
||||
Object *rt_mod2u;
|
||||
Object *rt_shr2i;
|
||||
Object *rt_shr2u;
|
||||
Object *rt_shl2i;
|
||||
Object *rt_cvt_ull_dbl;
|
||||
Object *rt_cvt_sll_dbl;
|
||||
Object *rt_cvt_ull_flt;
|
||||
Object *rt_cvt_sll_flt;
|
||||
Object *rt_cvt_dbl_usll;
|
||||
static void *saveheaperror;
|
||||
|
||||
enum {
|
||||
GPRLimit = 10,
|
||||
FPRLimit = 13,
|
||||
VRLimit = 13
|
||||
};
|
||||
|
||||
VarInfo *CodeGen_GetNewVarInfo(void) {
|
||||
VarInfo *vi;
|
||||
|
||||
vi = lalloc(sizeof(VarInfo));
|
||||
memclrw(vi, sizeof(VarInfo));
|
||||
|
||||
vi->deftoken = *CPrep_CurStreamElement();
|
||||
vi->varnumber = localcount++;
|
||||
|
||||
return vi;
|
||||
}
|
||||
|
||||
Object *maketemporary(Type *type) {
|
||||
ObjectList *list;
|
||||
Object *obj;
|
||||
|
||||
for (list = temps; list; list = list->next) {
|
||||
obj = list->object;
|
||||
if (obj->u.var.uid == 0 && obj->type == type) {
|
||||
obj->u.var.uid = 1;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
obj = lalloc(sizeof(Object));
|
||||
memclrw(obj, sizeof(Object));
|
||||
obj->otype = OT_OBJECT;
|
||||
obj->access = ACCESSPUBLIC;
|
||||
obj->datatype = DLOCAL;
|
||||
obj->type = type;
|
||||
obj->name = CParser_GetUniqueName();
|
||||
obj->u.var.info = CodeGen_GetNewVarInfo();
|
||||
obj->u.var.uid = 1;
|
||||
|
||||
list = lalloc(sizeof(ObjectList));
|
||||
memclrw(list, sizeof(ObjectList));
|
||||
list->next = temps;
|
||||
list->object = obj;
|
||||
temps = list;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void free_temporaries(void) {
|
||||
ObjectList *list;
|
||||
|
||||
for (list = temps; list; list = list->next)
|
||||
list->object->u.var.uid = 0;
|
||||
}
|
||||
|
||||
static void allocate_temporaries(void) {
|
||||
ObjectList *list;
|
||||
|
||||
for (list = temps; list; list = list->next)
|
||||
assign_local_memory(list->object);
|
||||
}
|
||||
|
||||
void process_arguments(ArgumentProcessor func, Boolean flag) {
|
||||
short gpr = 3;
|
||||
short fpr = 1;
|
||||
short vr = 2;
|
||||
Type *type;
|
||||
ObjectList *list;
|
||||
|
||||
for (list = arguments; list; list = list->next) {
|
||||
type = list->object->type;
|
||||
if (IS_TYPE_FLOAT(type)) {
|
||||
func(list->object, (fpr <= FPRLimit) ? fpr : 0);
|
||||
fpr++;
|
||||
if (type->size == 4)
|
||||
gpr++;
|
||||
else
|
||||
gpr += 2;
|
||||
} else if (IS_TYPE_VECTOR(type)) {
|
||||
func(list->object, (vr <= VRLimit) ? vr : 0);
|
||||
vr++;
|
||||
if (flag) {
|
||||
if ((vr - 1) == 2)
|
||||
gpr = 9;
|
||||
else if ((vr - 1) > 2)
|
||||
gpr = 11;
|
||||
}
|
||||
} else {
|
||||
func(list->object, (gpr <= GPRLimit) ? gpr : 0);
|
||||
if (TYPE_FITS_IN_REGISTER(type)) {
|
||||
if (type->size <= 4)
|
||||
gpr += 1;
|
||||
else
|
||||
gpr += 2;
|
||||
} else {
|
||||
gpr += (type->size >> 2);
|
||||
if (type->size & 3)
|
||||
gpr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_argument_register[RegClass_GPR] = gpr - 1;
|
||||
last_argument_register[RegClass_FPR] = fpr - 1;
|
||||
last_argument_register[RegClass_VR] = vr - 1;
|
||||
if (flag)
|
||||
move_varargs_to_memory();
|
||||
}
|
||||
|
||||
static void retain_argument_register(Object *obj, short reg) {
|
||||
VarInfo *vi = Registers_GetVarInfo(obj);
|
||||
Type *type = obj->type;
|
||||
|
||||
if (reg && !vi->noregister && vi->used) {
|
||||
if (TYPE_FITS_IN_REGISTER(type)) {
|
||||
if (type->size <= 4) {
|
||||
retain_register(obj, RegClass_GPR, reg);
|
||||
} else if (reg < GPRLimit) {
|
||||
if (copts.little_endian)
|
||||
retain_GPR_pair(obj, reg, reg + 1);
|
||||
else
|
||||
retain_GPR_pair(obj, reg + 1, reg);
|
||||
}
|
||||
} else if (IS_TYPE_FLOAT(type)) {
|
||||
retain_register(obj, RegClass_FPR, reg);
|
||||
} else if (IS_TYPE_VECTOR(type)) {
|
||||
retain_register(obj, RegClass_VR, reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_local_vregs(void) {
|
||||
VarInfo *vi;
|
||||
ObjectList *list;
|
||||
Object *obj;
|
||||
|
||||
if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
|
||||
if (assignable_registers[RegClass_GPR]) {
|
||||
vi = pic_base.u.var.info;
|
||||
vi->reg = 0;
|
||||
assign_register_by_type(&pic_base);
|
||||
pic_base_reg = vi->reg;
|
||||
#line 497
|
||||
CError_ASSERT(pic_base_reg);
|
||||
} else {
|
||||
#line 500
|
||||
CError_FATAL();
|
||||
}
|
||||
} else {
|
||||
pic_base_reg = 0;
|
||||
}
|
||||
|
||||
for (list = exceptionlist; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
|
||||
if (vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
|
||||
assign_register_by_type(obj);
|
||||
}
|
||||
}
|
||||
|
||||
set_last_exception_registers();
|
||||
|
||||
for (list = arguments; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
|
||||
if (vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
|
||||
assign_register_by_type(obj);
|
||||
}
|
||||
}
|
||||
|
||||
for (list = locals; list; list = list->next) {
|
||||
obj = list->object;
|
||||
if (!IsTempName(obj->name)) {
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
|
||||
if (vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
|
||||
assign_register_by_type(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open_fe_temp_registers();
|
||||
|
||||
for (list = locals; list; list = list->next) {
|
||||
obj = list->object;
|
||||
if (IsTempName(obj->name)) {
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
|
||||
if (vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
|
||||
assign_register_by_type(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (list = toclist; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
|
||||
if (!vi->reg && vi->used && vi->usage > 1)
|
||||
assign_register_by_type(obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_local_GPRs(void) {
|
||||
ObjectList *list;
|
||||
Object *obj;
|
||||
Object *winning_obj;
|
||||
SInt32 winning_usage;
|
||||
VarInfo *vi;
|
||||
Type *type;
|
||||
|
||||
if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
|
||||
vi = pic_base.u.var.info;
|
||||
vi->reg = 0;
|
||||
assign_register_by_type(&pic_base);
|
||||
pic_base_reg = vi->reg;
|
||||
#line 605
|
||||
CError_ASSERT(pic_base_reg);
|
||||
} else {
|
||||
pic_base_reg = 0;
|
||||
}
|
||||
|
||||
while (assignable_registers[RegClass_GPR]) {
|
||||
winning_obj = NULL;
|
||||
winning_usage = -1;
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = arguments; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
type = obj->type;
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = locals; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
type = obj->type;
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (list = toclist; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used) {
|
||||
if (vi->usage >= winning_usage && vi->usage >= 3) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!winning_obj)
|
||||
break;
|
||||
|
||||
assign_register_by_type(winning_obj);
|
||||
#line 698
|
||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_local_FPRs(void) {
|
||||
ObjectList *list;
|
||||
Object *obj;
|
||||
Object *winning_obj;
|
||||
SInt32 winning_usage;
|
||||
VarInfo *vi;
|
||||
Type *type;
|
||||
|
||||
while (assignable_registers[RegClass_FPR]) {
|
||||
winning_obj = NULL;
|
||||
winning_usage = -1;
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = arguments; list; list = list->next) {
|
||||
obj = list->object;
|
||||
type = obj->type;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (IS_TYPE_FLOAT(type)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = locals; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (IS_TYPE_FLOAT(obj->type)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!winning_obj)
|
||||
break;
|
||||
|
||||
assign_register_by_type(winning_obj);
|
||||
#line 782
|
||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_local_VRs(void) {
|
||||
ObjectList *list;
|
||||
Object *obj;
|
||||
Object *winning_obj;
|
||||
SInt32 winning_usage;
|
||||
VarInfo *vi;
|
||||
|
||||
while (assignable_registers[RegClass_VR]) {
|
||||
winning_obj = NULL;
|
||||
winning_usage = -1;
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = arguments; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (IS_TYPE_VECTOR(obj->type)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(disable_optimizer & 2)) {
|
||||
for (list = locals; list; list = list->next) {
|
||||
obj = list->object;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (vi->flags & VarInfoFlag40)
|
||||
vi->usage = 100000;
|
||||
if (!vi->reg && vi->used && !vi->noregister) {
|
||||
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
|
||||
if (IS_TYPE_VECTOR(obj->type)) {
|
||||
winning_obj = obj;
|
||||
winning_usage = vi->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!winning_obj)
|
||||
break;
|
||||
|
||||
assign_register_by_type(winning_obj);
|
||||
#line 846
|
||||
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_locals(void) {
|
||||
has_altivec_arrays = 0;
|
||||
|
||||
if (!requires_frame && !optimizing)
|
||||
process_arguments(retain_argument_register, 0);
|
||||
|
||||
if (optimizing) {
|
||||
allocate_local_vregs();
|
||||
} else {
|
||||
allocate_local_GPRs();
|
||||
allocate_local_FPRs();
|
||||
allocate_local_VRs();
|
||||
}
|
||||
|
||||
assign_locals_to_memory(locals);
|
||||
}
|
||||
|
||||
void move_assigned_argument(Object *obj, short reg) {
|
||||
VarInfo *vi;
|
||||
Type *type;
|
||||
SInt32 bytesLeft;
|
||||
SInt32 offset;
|
||||
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
type = obj->type;
|
||||
#line 901
|
||||
CError_ASSERT(obj->datatype == DLOCAL);
|
||||
|
||||
if (!vi->used)
|
||||
return;
|
||||
|
||||
if (reg) {
|
||||
if (vi->reg) {
|
||||
if (TYPE_IS_8BYTES(type)) {
|
||||
if (copts.little_endian) {
|
||||
if (vi->reg != reg)
|
||||
emitpcode(PC_MR, vi->reg, reg);
|
||||
if (reg < GPRLimit) {
|
||||
#line 916
|
||||
CError_FAIL((vi->regHi == reg) || (vi->reg == (reg + 1)));
|
||||
if (vi->regHi != (reg + 1))
|
||||
emitpcode(PC_MR, vi->regHi, reg + 1);
|
||||
} else {
|
||||
load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
|
||||
}
|
||||
} else {
|
||||
if (vi->regHi != reg)
|
||||
emitpcode(PC_MR, vi->regHi, reg);
|
||||
if (reg < GPRLimit) {
|
||||
#line 931
|
||||
CError_FAIL((vi->reg == reg) || (vi->regHi == (reg + 1)));
|
||||
if (vi->reg != (reg + 1))
|
||||
emitpcode(PC_MR, vi->reg, reg + 1);
|
||||
} else {
|
||||
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
|
||||
}
|
||||
}
|
||||
} else if (vi->reg != reg) {
|
||||
if (IS_TYPE_FLOAT(type)) {
|
||||
emitpcode(PC_FMR, vi->reg, reg);
|
||||
} else if (IS_TYPE_VECTOR(type)) {
|
||||
emitpcode(PC_VMR, vi->reg, reg);
|
||||
} else {
|
||||
emitpcode(PC_MR, vi->reg, reg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
|
||||
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
|
||||
} else if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
|
||||
switch (type->size) {
|
||||
case 1:
|
||||
load_store_register(PC_STB, reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 2:
|
||||
load_store_register(PC_STH, reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 4:
|
||||
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 8:
|
||||
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
|
||||
if (reg < GPRLimit)
|
||||
load_store_register(PC_STW, reg + 1, local_base_register(obj), obj, 4);
|
||||
break;
|
||||
default:
|
||||
#line 993
|
||||
CError_FATAL();
|
||||
}
|
||||
} else if (IS_TYPE_FLOAT(type)) {
|
||||
load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, local_base_register(obj), obj, 0);
|
||||
} else if (IS_TYPE_VECTOR(type)) {
|
||||
load_store_register(PC_STVX, reg, local_base_register(obj), obj, 0);
|
||||
} else {
|
||||
bytesLeft = (11 - reg) * 4;
|
||||
if (bytesLeft > obj->type->size)
|
||||
bytesLeft = obj->type->size;
|
||||
offset = 0;
|
||||
while (bytesLeft > 0) {
|
||||
load_store_register(PC_STW, reg, local_base_register(obj), obj, offset);
|
||||
reg++;
|
||||
offset += 4;
|
||||
bytesLeft -= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (vi->reg) {
|
||||
if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
|
||||
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
|
||||
} else if (IS_TYPE_FLOAT(type)) {
|
||||
load_store_register((type->size == 4) ? PC_LFS : PC_LFD, vi->reg, local_base_register(obj), obj, 0);
|
||||
} else if (IS_TYPE_VECTOR(type)) {
|
||||
load_store_register(PC_LVX, vi->reg, local_base_register(obj), obj, 0);
|
||||
} else {
|
||||
switch (type->size) {
|
||||
case 1:
|
||||
load_store_register(PC_LBZ, vi->reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 2:
|
||||
load_store_register(is_unsigned(type) ? PC_LHZ : PC_LHA, vi->reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 4:
|
||||
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
|
||||
break;
|
||||
case 8:
|
||||
load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
|
||||
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
|
||||
break;
|
||||
default:
|
||||
#line 1095
|
||||
CError_FATAL();
|
||||
}
|
||||
}
|
||||
} else if (!optimizing) {
|
||||
local_base_register(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void load_TOC_pointers(void) {
|
||||
VarInfo *vi;
|
||||
Object *obj;
|
||||
ObjectList *list;
|
||||
PCode *pc;
|
||||
|
||||
if (uses_globals && pic_base_reg) {
|
||||
pic_base_pcodelabel = makepclabel();
|
||||
pc = makepcode(PC_BC, 20, 7, 3);
|
||||
pcsetlinkbit(pc);
|
||||
pcsetsideeffects(pc);
|
||||
appendpcode(pclastblock, pc);
|
||||
pcbranch(pclastblock, pic_base_pcodelabel);
|
||||
makepcblock();
|
||||
pclabel(pclastblock, pic_base_pcodelabel);
|
||||
emitpcode(PC_MFLR, pic_base_reg);
|
||||
}
|
||||
|
||||
// TODO: depends on Operands
|
||||
for (list = toclist; list; list = list->next) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static Boolean has_vararglist(Object *funcobj) {
|
||||
FuncArg *arg;
|
||||
|
||||
arg = TYPE_FUNC(funcobj->type)->args;
|
||||
while (arg && arg != &elipsis)
|
||||
arg = arg->next;
|
||||
|
||||
return arg == &elipsis;
|
||||
}
|
||||
|
||||
void assign_labels() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
static Boolean islaststatement(Statement *stmt) {
|
||||
for (stmt = stmt->next; stmt; stmt = stmt->next) {
|
||||
if (stmt->type > ST_LABEL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void newstatement(SInt32 sourceoffset, UInt16 value, int flag) {
|
||||
PCodeBlock *block = pclastblock;
|
||||
|
||||
pcloopweight = value;
|
||||
if (!block->pcodeCount)
|
||||
block->loopWeight = value;
|
||||
|
||||
if (block->pcodeCount > 100)
|
||||
branch_label(makepclabel());
|
||||
|
||||
if (flag)
|
||||
block->flags |= fPCBlockFlag4000;
|
||||
}
|
||||
|
||||
static void expressionstatement(ENode *expr) {
|
||||
}
|
||||
|
||||
static void labelstatement() {}
|
||||
static void gotostatement() {}
|
||||
static void gotoexpression() {}
|
||||
static void conditionalstatement() {}
|
||||
static void returnstatement() {}
|
||||
static void capturestackpointer() {}
|
||||
static void resetstackpointer() {}
|
||||
static void callprofiler() {}
|
||||
static void exitprofiler() {}
|
||||
void CodeGen_Generator() {}
|
||||
void CodeGen_GenVDispatchThunk() {}
|
||||
void CodeGen_SetupRuntimeObjects() {}
|
||||
Boolean CodeGen_ReInitRuntimeObjects(Boolean is_precompiler) {}
|
||||
Boolean CodeGen_IsPublicRuntimeObject(Object *obj) {}
|
||||
void CodeGen_SOMStub() {}
|
||||
void CodeGen_ParseDeclSpec() {}
|
||||
static void CodeGen_EOLCheck() {}
|
||||
static void schedule_for() {}
|
||||
static void pragma_scheduling() {}
|
||||
static void CodeGen_ParseLongIntegerORonORoff() {}
|
||||
void CodeGen_ParsePragma(HashNameNode *name) {}
|
||||
void CodeGen_UpdateObject(Object *object) {}
|
||||
void CodeGen_UpdateBackEndOptions() {}
|
||||
void CodeGen_objc_method_self_offset() {}
|
||||
void CodeGen_objc_method_sel_offset() {}
|
||||
void CodeGen_objc_method_arg_offset() {}
|
||||
void CodeGen_objc_method_args_size() {}
|
||||
void CodeGen_HandleIntrinsicCall() {}
|
||||
void CodeGen_HandleTypeCast() {}
|
||||
void CodeGen_AssignCheck() {}
|
||||
void CodeGen_CollapseVectorExpression() {}
|
||||
void CodeGen_InsertSpecialMacros() {}
|
||||
char *CodeGen_ExpandSpecialMacro(Macro *macro) {}
|
||||
void CodeGen_reportheapinfo() {}
|
||||
static void CodeGen_heaperror() {}
|
||||
void CodeGen_InitialSanityCheck() {}
|
||||
1044
compiler_and_linker/unsorted/Operands.c
Normal file
1044
compiler_and_linker/unsorted/Operands.c
Normal file
File diff suppressed because it is too large
Load Diff
299
compiler_and_linker/unsorted/PCode.c
Normal file
299
compiler_and_linker/unsorted/PCode.c
Normal file
@@ -0,0 +1,299 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/CompilerTools.h"
|
||||
#include "compiler/PCode.h"
|
||||
#include "compiler/PCodeInfo.h"
|
||||
|
||||
PCodeBlock *pcbasicblocks;
|
||||
PCodeBlock *pclastblock;
|
||||
void *prologue;
|
||||
void *epilogue;
|
||||
PCodeBlock **depthfirstordering;
|
||||
int pcblockcount;
|
||||
int pcloopweight;
|
||||
static unsigned short pclabelcount;
|
||||
|
||||
void initpcode() {
|
||||
pclastblock = 0;
|
||||
pcbasicblocks = 0;
|
||||
pcblockcount = 0;
|
||||
pclabelcount = 0;
|
||||
pcloopweight = 1;
|
||||
initialize_aliases();
|
||||
}
|
||||
|
||||
PCode *makepcode(short op, ...) {
|
||||
PCode *pcode;
|
||||
va_list list;
|
||||
|
||||
va_start(list, op);
|
||||
pcode = vformatpcode(op, list);
|
||||
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
|
||||
return pcode;
|
||||
}
|
||||
|
||||
void emitpcode(short op, ...) {
|
||||
PCode *pcode;
|
||||
va_list list;
|
||||
|
||||
va_start(list, op);
|
||||
pcode = vformatpcode(op, list);
|
||||
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
|
||||
appendpcode(pclastblock, pcode);
|
||||
}
|
||||
|
||||
PCode *copypcode(PCode *pcode) {
|
||||
PCode *newpc;
|
||||
int extra_arg;
|
||||
int i;
|
||||
|
||||
extra_arg = 0;
|
||||
if ((PCODE_FLAG_SET_F(pcode) & fPCodeFlag8000000) && !(PCODE_FLAG_SET_F(pcode) & fPCodeFlag20000000))
|
||||
extra_arg = 1;
|
||||
|
||||
newpc = lalloc(sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
|
||||
memclrw(newpc, sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
|
||||
|
||||
newpc->op = pcode->op;
|
||||
newpc->flags = pcode->flags;
|
||||
newpc->argCount = pcode->argCount;
|
||||
newpc->_18 = pcode->_18;
|
||||
for (i = 0; i < pcode->argCount; i++) {
|
||||
newpc->args[i] = pcode->args[i];
|
||||
}
|
||||
|
||||
if (extra_arg)
|
||||
newpc->args[pcode->argCount].kind = PCOp_PLACEHOLDEROPERAND;
|
||||
|
||||
return newpc;
|
||||
}
|
||||
|
||||
PCodeLabel *makepclabel() {
|
||||
PCodeLabel *label;
|
||||
|
||||
label = (PCodeLabel *) lalloc(sizeof(PCodeLabel));
|
||||
memclrw(label, sizeof(PCodeLabel));
|
||||
label->index = pclabelcount++;
|
||||
return label;
|
||||
}
|
||||
|
||||
PCodeBlock *makepcblock() {
|
||||
PCodeBlock *block;
|
||||
|
||||
block = (PCodeBlock *) lalloc(sizeof(PCodeBlock));
|
||||
memclrw(block, sizeof(PCodeBlock));
|
||||
block->loopWeight = pcloopweight;
|
||||
block->blockIndex = pcblockcount++;
|
||||
if (pclastblock) {
|
||||
pclastblock->nextBlock = block;
|
||||
block->prevBlock = pclastblock;
|
||||
} else {
|
||||
pcbasicblocks = block;
|
||||
}
|
||||
pclastblock = block;
|
||||
return block;
|
||||
}
|
||||
|
||||
void pclabel(PCodeBlock *block, PCodeLabel *label) {
|
||||
PCLink *iter;
|
||||
PCLink *next;
|
||||
|
||||
iter = (PCLink *) label->block;
|
||||
while (iter) {
|
||||
next = (PCLink *) iter->block;
|
||||
iter->block = block;
|
||||
iter = next;
|
||||
}
|
||||
|
||||
label->block = block;
|
||||
label->resolved = 1;
|
||||
label->nextLabel = block->labels;
|
||||
block->labels = label;
|
||||
}
|
||||
|
||||
void pcbranch(PCodeBlock *block, PCodeLabel *label) {
|
||||
PCLink *link;
|
||||
|
||||
link = (PCLink *) lalloc(sizeof(PCLink));
|
||||
memclrw(link, sizeof(PCLink));
|
||||
|
||||
link->block = label->block;
|
||||
if (!label->resolved)
|
||||
label->block = (PCodeBlock *) link;
|
||||
link->nextLink = block->successors;
|
||||
block->successors = link;
|
||||
}
|
||||
|
||||
void pccomputepredecessors() {
|
||||
PCodeBlock *block;
|
||||
PCLink *succ;
|
||||
PCLink *pred;
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
for (succ = block->successors; succ; succ = succ->nextLink) {
|
||||
pred = (PCLink *) lalloc(sizeof(PCLink));
|
||||
memclrw(pred, sizeof(PCLink));
|
||||
|
||||
pred->block = block;
|
||||
pred->nextLink = succ->block->predecessors;
|
||||
succ->block->predecessors = pred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deleteblock(PCodeBlock *block) {
|
||||
block->prevBlock->nextBlock = block->nextBlock;
|
||||
if (block->nextBlock)
|
||||
block->nextBlock->prevBlock = block->prevBlock;
|
||||
block->flags |= fPCBlockFlag20;
|
||||
}
|
||||
|
||||
void deleteunreachableblocks() {
|
||||
PCodeBlock *block;
|
||||
|
||||
computedepthfirstordering();
|
||||
|
||||
for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
|
||||
if (!(block->flags & fPCBlockFlag4))
|
||||
deleteblock(block);
|
||||
}
|
||||
}
|
||||
|
||||
void appendpcode(PCodeBlock *block, PCode *pcode) {
|
||||
if (block->firstPCode) {
|
||||
pcode->nextPCode = 0;
|
||||
pcode->prevPCode = block->lastPCode;
|
||||
block->lastPCode->nextPCode = pcode;
|
||||
block->lastPCode = pcode;
|
||||
} else {
|
||||
block->lastPCode = pcode;
|
||||
block->firstPCode = pcode;
|
||||
pcode->prevPCode = 0;
|
||||
pcode->nextPCode = 0;
|
||||
}
|
||||
pcode->block = block;
|
||||
block->pcodeCount++;
|
||||
}
|
||||
|
||||
void deletepcode(PCode *pcode) {
|
||||
PCodeBlock *block;
|
||||
|
||||
block = pcode->block;
|
||||
if (pcode->prevPCode)
|
||||
pcode->prevPCode->nextPCode = pcode->nextPCode;
|
||||
else
|
||||
block->firstPCode = pcode->nextPCode;
|
||||
if (pcode->nextPCode)
|
||||
pcode->nextPCode->prevPCode = pcode->prevPCode;
|
||||
else
|
||||
block->lastPCode = pcode->prevPCode;
|
||||
|
||||
pcode->block = 0;
|
||||
block->pcodeCount--;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void insertpcodebefore(PCode *anchor, PCode *newpcode) {
|
||||
PCodeBlock *block;
|
||||
|
||||
block = anchor->block;
|
||||
if (anchor->prevPCode)
|
||||
anchor->prevPCode->nextPCode = newpcode;
|
||||
else
|
||||
block->firstPCode = newpcode;
|
||||
newpcode->nextPCode = anchor;
|
||||
newpcode->prevPCode = anchor->prevPCode;
|
||||
anchor->prevPCode = newpcode;
|
||||
newpcode->sourceoffset = anchor->sourceoffset;
|
||||
|
||||
newpcode->block = block;
|
||||
block->pcodeCount++;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void insertpcodeafter(PCode *anchor, PCode *newpcode) {
|
||||
PCodeBlock *block;
|
||||
|
||||
block = anchor->block;
|
||||
if (anchor->nextPCode)
|
||||
anchor->nextPCode->prevPCode = newpcode;
|
||||
else
|
||||
block->lastPCode = newpcode;
|
||||
newpcode->prevPCode = anchor;
|
||||
newpcode->nextPCode = anchor->nextPCode;
|
||||
anchor->nextPCode = newpcode;
|
||||
newpcode->sourceoffset = anchor->sourceoffset;
|
||||
|
||||
newpcode->block = block;
|
||||
block->pcodeCount++;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void setpcodeflags(int flags) {
|
||||
pclastblock->lastPCode->flags |= flags;
|
||||
if (flags & fSideEffects)
|
||||
pclastblock->lastPCode->flags &= ~(fIsCSE | fCommutative | fPCodeFlag10);
|
||||
}
|
||||
|
||||
void clearpcodeflags(int flags) {
|
||||
pclastblock->lastPCode->flags &= ~flags;
|
||||
}
|
||||
|
||||
int pccomputeoffsets() {
|
||||
int offset;
|
||||
PCodeBlock *block;
|
||||
|
||||
offset = 0;
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
block->codeOffset = offset;
|
||||
offset += block->pcodeCount * 4;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
typedef struct _DFO {
|
||||
PCodeBlock *block;
|
||||
PCLink *link;
|
||||
} DFO;
|
||||
|
||||
static int depthfirstorder;
|
||||
|
||||
void computedepthfirstordering() {
|
||||
PCodeBlock *block;
|
||||
PCLink *link;
|
||||
DFO *dfo;
|
||||
int index;
|
||||
|
||||
depthfirstordering = (PCodeBlock **) lalloc(sizeof(PCodeBlock *) * pcblockcount);
|
||||
memclrw(depthfirstordering, sizeof(PCodeBlock *) * pcblockcount);
|
||||
depthfirstorder = pcblockcount;
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
block->flags &= ~fPCBlockFlag4;
|
||||
}
|
||||
|
||||
dfo = (DFO *) oalloc(sizeof(DFO) * pcblockcount);
|
||||
pcbasicblocks->flags |= fPCBlockFlag4;
|
||||
|
||||
dfo->block = pcbasicblocks;
|
||||
dfo->link = pcbasicblocks->successors;
|
||||
index = 1;
|
||||
while (index) {
|
||||
if ((link = dfo[index - 1].link)) {
|
||||
dfo[index - 1].link = link->nextLink;
|
||||
block = link->block;
|
||||
if (!(block->flags & fPCBlockFlag4)) {
|
||||
block->flags |= fPCBlockFlag4;
|
||||
dfo[index].block = block;
|
||||
dfo[index].link = block->successors;
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
depthfirstordering[--depthfirstorder] = dfo[--index].block;
|
||||
}
|
||||
}
|
||||
|
||||
while (depthfirstorder) {
|
||||
depthfirstordering[--depthfirstorder] = 0;
|
||||
}
|
||||
}
|
||||
1308
compiler_and_linker/unsorted/PCodeInfo.c
Normal file
1308
compiler_and_linker/unsorted/PCodeInfo.c
Normal file
File diff suppressed because it is too large
Load Diff
348
compiler_and_linker/unsorted/PCodeUtilities.c
Normal file
348
compiler_and_linker/unsorted/PCodeUtilities.c
Normal file
@@ -0,0 +1,348 @@
|
||||
#include "compiler/PCodeUtilities.h"
|
||||
#include "compiler/PCode.h"
|
||||
#include "compiler/PCodeInfo.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/enode.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler.h"
|
||||
|
||||
void pcsetrecordbit(PCode *pc) {
|
||||
int reg;
|
||||
PCodeArg *arg;
|
||||
short argCount;
|
||||
int argIdx;
|
||||
|
||||
pc->flags &= ~(fPCodeFlag10 | fCommutative | fIsCSE);
|
||||
if ((pc->flags & (fPCodeFlag80000000 | fPCodeFlag40000000)) == fPCodeFlag40000000) {
|
||||
reg = 1;
|
||||
} else if ((pc->flags & (fPCodeFlag80000000 | fPCodeFlag40000000)) == (fPCodeFlag80000000 | fPCodeFlag40000000)) {
|
||||
reg = 6;
|
||||
} else {
|
||||
reg = 0;
|
||||
}
|
||||
|
||||
if (pc->op == PC_ANDI || pc->op == PC_ANDIS) {
|
||||
pc->flags |= fPCodeFlag20000000;
|
||||
} else if (pc->op == PC_ADDI || pc->op == PC_ADDIC) {
|
||||
pc->flags |= fPCodeFlag10000000;
|
||||
pc->flags |= fPCodeFlag20000000;
|
||||
change_num_operands(pc, 5);
|
||||
pc->op = PC_ADDICR;
|
||||
|
||||
#line 76
|
||||
CError_ASSERT(pc->args[3].kind == PCOp_PLACEHOLDEROPERAND);
|
||||
pc->args[3].kind = PCOp_REGISTER;
|
||||
pc->args[3].arg = RegClass_SPR;
|
||||
pc->args[3].data.reg.reg = 0;
|
||||
pc->args[3].data.reg.effect = EffectWrite;
|
||||
#line 80
|
||||
CError_ASSERT(pc->args[4].kind == PCOp_PLACEHOLDEROPERAND);
|
||||
pc->args[4].kind = PCOp_REGISTER;
|
||||
pc->args[4].arg = RegClass_CRFIELD;
|
||||
pc->args[4].data.reg.reg = reg;
|
||||
pc->args[4].data.reg.effect = EffectWrite;
|
||||
} else {
|
||||
arg = pc->args;
|
||||
argIdx = argCount = pc->argCount;
|
||||
while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
|
||||
if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_CRFIELD && arg->data.reg.reg == reg) {
|
||||
arg->data.reg.effect |= EffectWrite;
|
||||
pc->flags |= fPCodeFlag20000000;
|
||||
return;
|
||||
}
|
||||
arg++;
|
||||
argIdx--;
|
||||
}
|
||||
|
||||
if (argIdx <= 0) {
|
||||
arg = &pc->args[argCount];
|
||||
pc->argCount++;
|
||||
}
|
||||
|
||||
#line 105
|
||||
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
|
||||
arg->kind = PCOp_REGISTER;
|
||||
arg->arg = RegClass_CRFIELD;
|
||||
arg->data.reg.reg = reg;
|
||||
arg->data.reg.effect = EffectWrite;
|
||||
if (pc->op != PC_ADDICR)
|
||||
pc->flags |= fPCodeFlag20000000;
|
||||
}
|
||||
}
|
||||
|
||||
void pcsetsideeffects(PCode *pc) {
|
||||
pc->flags &= ~(fPCodeFlag10 | fCommutative | fIsCSE);
|
||||
pc->flags |= fSideEffects;
|
||||
}
|
||||
|
||||
void pcsetlinkbit(PCode *pc) {
|
||||
PCodeArg *arg;
|
||||
int argIdx;
|
||||
|
||||
switch (pc->op) {
|
||||
case PC_B:
|
||||
pc->op = PC_BL;
|
||||
break;
|
||||
case PC_BCTR:
|
||||
pc->op = PC_BCTRL;
|
||||
break;
|
||||
case PC_BLR:
|
||||
pc->op = PC_BLRL;
|
||||
break;
|
||||
}
|
||||
|
||||
arg = pc->args;
|
||||
argIdx = pc->argCount;
|
||||
while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
|
||||
if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_SPR && arg->data.reg.reg == 1) {
|
||||
arg->data.reg.effect |= EffectWrite;
|
||||
pc->flags |= fLink;
|
||||
return;
|
||||
}
|
||||
arg++;
|
||||
argIdx--;
|
||||
}
|
||||
|
||||
#line 169
|
||||
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
|
||||
arg->kind = PCOp_REGISTER;
|
||||
arg->arg = RegClass_SPR;
|
||||
arg->data.reg.reg = 1;
|
||||
arg->data.reg.effect = EffectWrite;
|
||||
|
||||
if (opcodeinfo[pc->op].flags & fPCodeFlag8) {
|
||||
pc->flags &= ~fPCodeFlag1;
|
||||
pc->flags |= fPCodeFlag8;
|
||||
}
|
||||
pc->flags |= fLink;
|
||||
}
|
||||
|
||||
void branch_label(PCodeLabel *label) {
|
||||
if (pclastblock->pcodeCount) {
|
||||
pcbranch(pclastblock, label);
|
||||
makepcblock();
|
||||
}
|
||||
pclabel(pclastblock, label);
|
||||
}
|
||||
|
||||
void branch_conditional(short a, short compareop, short c, PCodeLabel *label) {
|
||||
PCodeBlock *tmpblock;
|
||||
PCodeLabel *tmplabel;
|
||||
int r28;
|
||||
|
||||
tmpblock = pclastblock;
|
||||
tmplabel = makepclabel();
|
||||
|
||||
switch (compareop) {
|
||||
case ENOTEQU:
|
||||
c = !c;
|
||||
case EEQU:
|
||||
r28 = 2;
|
||||
break;
|
||||
case EGREATEREQU:
|
||||
c = !c;
|
||||
case ELESS:
|
||||
r28 = 0;
|
||||
break;
|
||||
case ELESSEQU:
|
||||
c = !c;
|
||||
case EGREATER:
|
||||
r28 = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
emitpcode(c ? PC_BT : PC_BF, a, r28, label);
|
||||
pcbranch(pclastblock, label);
|
||||
pcbranch(pclastblock, tmplabel);
|
||||
makepcblock();
|
||||
pclabel(pclastblock, tmplabel);
|
||||
}
|
||||
|
||||
void branch_always(PCodeLabel *label) {
|
||||
emitpcode(PC_B, label);
|
||||
pcbranch(pclastblock, label);
|
||||
makepcblock();
|
||||
}
|
||||
|
||||
void branch_decrement_always(short opcode, PCodeLabel *label) {
|
||||
PCodeLabel *tmplabel = makepclabel();
|
||||
emitpcode(opcode, label);
|
||||
pcbranch(pclastblock, label);
|
||||
pcbranch(pclastblock, tmplabel);
|
||||
makepcblock();
|
||||
pclabel(pclastblock, tmplabel);
|
||||
}
|
||||
|
||||
void branch_indirect(Object *obj) {
|
||||
emitpcode(PC_BCTR, obj, 0);
|
||||
makepcblock();
|
||||
}
|
||||
|
||||
int branch_count_volatiles(void) {
|
||||
int count = 0;
|
||||
int i;
|
||||
char rclass;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
PCodeArg *branch_record_volatiles(PCodeArg *arglist, UInt32 *masks) {
|
||||
int i;
|
||||
char rclass;
|
||||
|
||||
for (rclass = RegClassMax - 1; rclass >= 0; rclass--) {
|
||||
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
|
||||
arglist->kind = PCOp_REGISTER;
|
||||
arglist->arg = rclass;
|
||||
arglist->data.reg.reg = scratch_registers[(char)rclass][i];
|
||||
arglist->data.reg.effect = EffectWrite;
|
||||
if (masks[(char)rclass] & (1 << scratch_registers[(char)rclass][i]))
|
||||
arglist->data.reg.effect |= EffectRead;
|
||||
arglist++;
|
||||
}
|
||||
}
|
||||
|
||||
return arglist;
|
||||
}
|
||||
|
||||
void branch_subroutine(Object *obj, short add_nop, UInt32 *masks) {
|
||||
int count;
|
||||
PCode *pc;
|
||||
PCodeArg *arg;
|
||||
|
||||
count = branch_count_volatiles();
|
||||
if (copts.exceptions && current_statement)
|
||||
count += countexceptionactionregisters(current_statement->dobjstack);
|
||||
|
||||
pc = makepcode(PC_BL, count, obj, 0);
|
||||
arg = branch_record_volatiles(pc->args + 1, masks);
|
||||
if (copts.exceptions && current_statement)
|
||||
noteexceptionactionregisters(current_statement->dobjstack, arg);
|
||||
appendpcode(pclastblock, pc);
|
||||
|
||||
if (add_nop)
|
||||
emitpcode(PC_NOP);
|
||||
|
||||
branch_label(makepclabel());
|
||||
if (copts.exceptions && current_statement)
|
||||
recordexceptionactions(pc, current_statement->dobjstack);
|
||||
}
|
||||
|
||||
void branch_subroutine_ctr(UInt32 *masks) {
|
||||
int count;
|
||||
PCode *pc;
|
||||
PCodeArg *arg;
|
||||
|
||||
count = branch_count_volatiles();
|
||||
if (copts.exceptions && current_statement)
|
||||
count += countexceptionactionregisters(current_statement->dobjstack);
|
||||
|
||||
pc = makepcode(PC_BCTRL, count);
|
||||
arg = branch_record_volatiles(pc->args + 1, masks);
|
||||
if (copts.exceptions && current_statement)
|
||||
noteexceptionactionregisters(current_statement->dobjstack, arg);
|
||||
appendpcode(pclastblock, pc);
|
||||
|
||||
branch_label(makepclabel());
|
||||
if (copts.exceptions && current_statement)
|
||||
recordexceptionactions(pc, current_statement->dobjstack);
|
||||
}
|
||||
|
||||
void add_immediate(short dest_reg, short base_reg, Object *obj, short offset) {
|
||||
short tmp_reg = base_reg;
|
||||
|
||||
if (obj && offset && obj->datatype != DLOCAL) {
|
||||
tmp_reg = used_virtual_registers[RegClass_GPR]++;
|
||||
add_immediate_lo(tmp_reg, base_reg, obj, 0, 1);
|
||||
obj = NULL;
|
||||
}
|
||||
|
||||
if (!obj && !offset)
|
||||
emitpcode(PC_MR, dest_reg, tmp_reg);
|
||||
else
|
||||
emitpcode(PC_ADDI, dest_reg, tmp_reg, obj, offset);
|
||||
}
|
||||
|
||||
PCode *add_immediate_lo(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
|
||||
PCode *pc;
|
||||
|
||||
#line 577
|
||||
CError_ASSERT(obj);
|
||||
|
||||
pc = makepcode(PC_ADDI, dest_reg, base_reg, obj, offset);
|
||||
if (add_to_block)
|
||||
appendpcode(pclastblock, pc);
|
||||
return pc;
|
||||
}
|
||||
|
||||
PCode *op_absolute_ha(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
|
||||
PCode *pc;
|
||||
int tmp_reg;
|
||||
|
||||
if (obj->datatype == DLOCAL) {
|
||||
pc = makepcode(PC_ADDIS, dest_reg, base_reg, obj, offset);
|
||||
} else if (copts.codegen_pic) {
|
||||
tmp_reg = base_reg;
|
||||
#line 601
|
||||
CError_ASSERT(tmp_reg);
|
||||
pc = makepcode(PC_ADDIS, dest_reg, tmp_reg, obj, offset);
|
||||
} else {
|
||||
#line 606
|
||||
CError_ASSERT(base_reg == 0);
|
||||
pc = makepcode(PC_LIS, dest_reg, obj, offset);
|
||||
}
|
||||
|
||||
if (add_to_block)
|
||||
appendpcode(pclastblock, pc);
|
||||
return pc;
|
||||
}
|
||||
|
||||
void load_store_register(short opcode, short dest_reg, short base_reg, Object *obj, SInt32 offset) {
|
||||
short addi_tmp;
|
||||
short offset_reg1;
|
||||
short offset_reg2;
|
||||
|
||||
offset_reg1 = base_reg;
|
||||
if (obj && offset && obj->datatype != DLOCAL) {
|
||||
offset_reg1 = used_virtual_registers[RegClass_GPR]++;
|
||||
add_immediate_lo(offset_reg1, base_reg, obj, 0, 1);
|
||||
obj = NULL;
|
||||
}
|
||||
|
||||
if (offset != (short)offset) {
|
||||
if (opcode == PC_LWZ && dest_reg == 12)
|
||||
offset_reg2 = 12;
|
||||
else if (opcode == PC_LWZ && dest_reg == 11)
|
||||
offset_reg2 = 11;
|
||||
else
|
||||
offset_reg2 = used_virtual_registers[RegClass_GPR]++;
|
||||
|
||||
emitpcode(PC_ADDIS, offset_reg2, offset_reg1, 0, (short) ((offset >> 16) + ((offset & 0x8000) >> 15)));
|
||||
offset = (short) offset;
|
||||
offset_reg1 = offset_reg2;
|
||||
}
|
||||
|
||||
if (opcode == PC_STVX || opcode == PC_LVX) {
|
||||
offset_reg2 = 0;
|
||||
if (obj) {
|
||||
addi_tmp = used_virtual_registers[RegClass_GPR]++;
|
||||
emitpcode(PC_ADDI, addi_tmp, offset_reg1, obj, offset);
|
||||
offset_reg1 = addi_tmp;
|
||||
} else if (offset) {
|
||||
offset_reg2 = used_virtual_registers[RegClass_GPR]++;
|
||||
emitpcode(PC_LI, offset_reg2, offset);
|
||||
}
|
||||
if (!offset_reg2)
|
||||
emitpcode(opcode, dest_reg, 0, offset_reg1);
|
||||
else
|
||||
emitpcode(opcode, dest_reg, offset_reg1, offset_reg2);
|
||||
} else {
|
||||
emitpcode(opcode, dest_reg, offset_reg1, obj, offset);
|
||||
}
|
||||
}
|
||||
392
compiler_and_linker/unsorted/RegisterInfo.c
Normal file
392
compiler_and_linker/unsorted/RegisterInfo.c
Normal file
@@ -0,0 +1,392 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler/PCode.h"
|
||||
|
||||
short last_exception_register[RegClassMax];
|
||||
short first_fe_temporary_register[RegClassMax];
|
||||
short last_argument_register[RegClassMax];
|
||||
short _FP_;
|
||||
short _CALLER_SP_;
|
||||
char *special_register_names[RegClassMax][RegisterMax];
|
||||
static short used_regs_before_coloring;
|
||||
static UInt8 save_state[RegisterMax];
|
||||
|
||||
char *XXspecial_register_names[RegClassMax * RegisterMax];
|
||||
|
||||
short spr_to_sysreg[4] = {1, 8, 9, 0x100};
|
||||
|
||||
void asm_used_register(char rclass, short reg) {
|
||||
int i;
|
||||
|
||||
if ((reg < n_real_registers[rclass]) && (reg_state[rclass][reg] == RegState0)) {
|
||||
if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]]) {
|
||||
if (assignable_registers[rclass] > 0)
|
||||
assignable_registers[rclass]--;
|
||||
reg_state[rclass][reg] = RegState1;
|
||||
used_nonvolatile_registers[rclass]++;
|
||||
} else {
|
||||
for (i = used_nonvolatile_registers[rclass]; i < n_nonvolatile_registers[rclass]; i++) {
|
||||
if (reg == nonvolatile_registers[rclass][i]) {
|
||||
reg_state[rclass][reg] = RegState1;
|
||||
if (assignable_registers[rclass] > 0)
|
||||
assignable_registers[rclass]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void retain_register(Object *obj, char rclass, short reg) {
|
||||
VarInfo *vi;
|
||||
|
||||
#line 95
|
||||
CError_ASSERT((short) reg < RegisterMax);
|
||||
|
||||
if (reg_state[rclass][reg] == RegState0) {
|
||||
assignable_registers[rclass]--;
|
||||
reg_state[rclass][reg] = RegState1;
|
||||
if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]])
|
||||
used_nonvolatile_registers[rclass]++;
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
vi->rclass = rclass;
|
||||
vi->flags |= VarInfoFlag2;
|
||||
vi->reg = reg;
|
||||
}
|
||||
}
|
||||
|
||||
void retain_GPR_pair(Object *obj, short reg, short regHi) {
|
||||
VarInfo *vi;
|
||||
|
||||
retain_register(NULL, RegClass_GPR, reg);
|
||||
retain_register(NULL, RegClass_GPR, regHi);
|
||||
|
||||
if (obj) {
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
vi->rclass = RegClass_GPR;
|
||||
vi->flags |= VarInfoFlag2 | VarInfoFlag4;
|
||||
vi->reg = reg;
|
||||
vi->regHi = regHi;
|
||||
}
|
||||
}
|
||||
|
||||
int is_register_object(Object *obj) {
|
||||
return obj->sclass == OBJECT_SCLASS_101;
|
||||
}
|
||||
|
||||
int GetABIFirstNonVolatile(char rclass) {
|
||||
switch (rclass) {
|
||||
case RegClass_SPR: return 3;
|
||||
case RegClass_CRFIELD: return 2;
|
||||
case RegClass_VR: return 20;
|
||||
case RegClass_GPR: return 13;
|
||||
case RegClass_FPR: return 14;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
char GetRegisterClassName(char rclass) {
|
||||
switch (rclass) {
|
||||
case RegClass_VR: return 'v';
|
||||
case RegClass_GPR: return 'r';
|
||||
case RegClass_FPR: return 'f';
|
||||
default:
|
||||
#line 242
|
||||
CError_FATAL();
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
static int first_nonvolatile_reg(char rclass) {
|
||||
return GetABIFirstNonVolatile(rclass);
|
||||
}
|
||||
|
||||
void setup_diagnostic_reg_strings() {
|
||||
register_class_name[RegClass_SPR] = "SPR";
|
||||
register_class_format[RegClass_SPR] = "spr%ld";
|
||||
register_class_name[RegClass_CRFIELD] = "CRFIELD";
|
||||
register_class_format[RegClass_CRFIELD] = "cr%ld";
|
||||
register_class_name[RegClass_VR] = "VR";
|
||||
register_class_format[RegClass_VR] = "vr%ld";
|
||||
register_class_name[RegClass_FPR] = "FPR";
|
||||
register_class_format[RegClass_FPR] = "f%ld";
|
||||
register_class_name[RegClass_GPR] = "GPR";
|
||||
register_class_format[RegClass_GPR] = "r%ld";
|
||||
}
|
||||
|
||||
void init_target_registers() {
|
||||
char rclass;
|
||||
int reg;
|
||||
int end;
|
||||
int tmp;
|
||||
|
||||
static int last_nonvolatile_reg[] = {3, 5, 31, 31, 31};
|
||||
static int nonvol_reserve[] = {0, 0, 0, 4, 3};
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
for (reg = 0; reg < RegisterMax; reg++)
|
||||
special_register_names[(char)rclass][reg] = NULL;
|
||||
}
|
||||
|
||||
special_register_names[RegClass_SPR][0] = "XER";
|
||||
special_register_names[RegClass_SPR][1] = "LR";
|
||||
special_register_names[RegClass_SPR][2] = "CTR";
|
||||
special_register_names[RegClass_SPR][3] = "VRSAVE";
|
||||
special_register_names[RegClass_GPR][1] = "SP";
|
||||
|
||||
setup_diagnostic_reg_strings();
|
||||
n_real_registers[RegClass_SPR] = 4;
|
||||
n_real_registers[RegClass_CRFIELD] = 8;
|
||||
n_real_registers[RegClass_VR] = 32;
|
||||
n_real_registers[RegClass_FPR] = 32;
|
||||
n_real_registers[RegClass_GPR] = 32;
|
||||
reg_state[RegClass_GPR][1] = RegState2;
|
||||
reg_state[RegClass_GPR][2] = RegState2;
|
||||
reg_state[RegClass_CRFIELD][5] = RegState2;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
n_nonvolatile_registers[(char)rclass] = 0;
|
||||
if (last_nonvolatile_reg[(char)rclass] >= 0) {
|
||||
end = first_nonvolatile_reg(rclass);
|
||||
for (reg = last_nonvolatile_reg[(char)rclass]; reg >= end; reg--) {
|
||||
if (reg_state[(char)rclass][reg] == RegState0) {
|
||||
tmp = n_nonvolatile_registers[(char)rclass]++;
|
||||
nonvolatile_registers[(char)rclass][tmp] = reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assignable_registers[(char)rclass] = n_nonvolatile_registers[(char)rclass] - nonvol_reserve[(char)rclass];
|
||||
if (assignable_registers[(char)rclass] < 0)
|
||||
assignable_registers[(char)rclass] = 0;
|
||||
|
||||
n_scratch_registers[(char)rclass] = 0;
|
||||
for (reg = 0; reg < n_real_registers[(char)rclass]; reg++) {
|
||||
if (reg < GetABIFirstNonVolatile(rclass) || reg > last_nonvolatile_reg[(char)rclass]) {
|
||||
if (reg_state[(char)rclass][reg] == RegState0) {
|
||||
tmp = n_scratch_registers[(char)rclass]++;
|
||||
scratch_registers[(char)rclass][tmp] = reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_FP_ = -1;
|
||||
_CALLER_SP_ = -1;
|
||||
optimizing = (copts.optimizationlevel > 0) && !disable_optimizer;
|
||||
}
|
||||
|
||||
void assign_register_by_type(Object *obj) {
|
||||
VarInfo *vi;
|
||||
Type *ty;
|
||||
Boolean flag;
|
||||
|
||||
ty = obj->type;
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
flag = 0;
|
||||
vi->rclass = RegClassMax;
|
||||
vi->reg = 0;
|
||||
vi->regHi = 0;
|
||||
|
||||
if ((ty->type == TYPEINT) || (ty->type == TYPEENUM) || ((ty->type == TYPEPOINTER || ty->type == TYPEARRAY) && (ty->type != TYPEARRAY)) || ((ty->type == TYPEMEMBERPOINTER) && (ty->size == 4U))) {
|
||||
if (((ty->type == TYPEINT) || (ty->type == TYPEENUM)) && (ty->size == 8))
|
||||
flag = 1;
|
||||
vi->rclass = RegClass_GPR;
|
||||
} else if (ty->type == TYPEFLOAT) {
|
||||
vi->rclass = RegClass_FPR;
|
||||
} else if ((ty->type == TYPESTRUCT) && (TYPE_STRUCT(ty)->stype >= STRUCT_TYPE_4) && (TYPE_STRUCT(ty)->stype <= STRUCT_TYPE_E)) {
|
||||
vi->rclass = RegClass_VR;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vi->rclass < RegClassMax) {
|
||||
if (flag) {
|
||||
#line 520
|
||||
CError_ASSERT(vi->rclass == RegClass_GPR);
|
||||
if (assignable_registers[vi->rclass] > 1)
|
||||
assign_GPR_pair(obj);
|
||||
} else {
|
||||
if (assignable_registers[vi->rclass] > 0)
|
||||
assign_register_to_variable(obj, vi->rclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assign_GPR_pair(Object *obj) {
|
||||
VarInfo *vi;
|
||||
short reg;
|
||||
short regHi;
|
||||
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (optimizing) {
|
||||
reg = used_virtual_registers[RegClass_GPR]++;
|
||||
regHi = used_virtual_registers[RegClass_GPR]++;
|
||||
} else {
|
||||
#line 554
|
||||
CError_ASSERT(assignable_registers[RegClass_GPR] >= 2);
|
||||
reg = obtain_nonvolatile_register(RegClass_GPR);
|
||||
regHi = obtain_nonvolatile_register(RegClass_GPR);
|
||||
retain_GPR_pair(obj, reg, regHi);
|
||||
}
|
||||
|
||||
vi->rclass = RegClass_GPR;
|
||||
if (reg > 0 && regHi > 0) {
|
||||
vi->flags |= VarInfoFlag2 | VarInfoFlag4;
|
||||
vi->reg = reg;
|
||||
vi->regHi = regHi;
|
||||
} else {
|
||||
#line 567
|
||||
CError_FATAL();
|
||||
}
|
||||
}
|
||||
|
||||
void open_fe_temp_registers() {
|
||||
int r;
|
||||
|
||||
r = used_virtual_registers[RegClass_GPR];
|
||||
first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = r;
|
||||
r = used_virtual_registers[RegClass_FPR];
|
||||
first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = r;
|
||||
r = used_virtual_registers[RegClass_VR];
|
||||
first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = r;
|
||||
//first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR];
|
||||
//first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR];
|
||||
//first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = used_virtual_registers[RegClass_VR];
|
||||
}
|
||||
|
||||
void set_last_exception_registers() {
|
||||
last_exception_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR] - 1;
|
||||
last_exception_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR] - 1;
|
||||
last_exception_register[RegClass_VR] = used_virtual_registers[RegClass_VR] - 1;
|
||||
}
|
||||
|
||||
static VarInfo *Registers_GetNewVarInfo() {
|
||||
VarInfo *vi = galloc(sizeof(VarInfo));
|
||||
memclrw(vi, sizeof(VarInfo));
|
||||
return vi;
|
||||
}
|
||||
|
||||
VarInfo *Registers_GetVarInfo(Object *obj) {
|
||||
switch (obj->datatype) {
|
||||
case DDATA:
|
||||
if (!obj->u.data.info)
|
||||
obj->u.data.info = Registers_GetNewVarInfo();
|
||||
return obj->u.data.info;
|
||||
case DNONLAZYPTR:
|
||||
// not sure if this is the right union
|
||||
if (!obj->u.toc.info) {
|
||||
#line 639
|
||||
CError_FATAL();
|
||||
obj->u.toc.info = CodeGen_GetNewVarInfo();
|
||||
}
|
||||
return obj->u.toc.info;
|
||||
case DLOCAL:
|
||||
if (!obj->u.var.info) {
|
||||
#line 647
|
||||
CError_FATAL();
|
||||
}
|
||||
return obj->u.var.info;
|
||||
case DABSOLUTE:
|
||||
// not sure if this is the right union
|
||||
if (!obj->u.data.info)
|
||||
obj->u.data.info = Registers_GetNewVarInfo();
|
||||
return obj->u.data.info;
|
||||
default:
|
||||
#line 660
|
||||
CError_FATAL();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int used_vrstate_VRs() {
|
||||
int count = 0;
|
||||
int i;
|
||||
for (i = 0; i < RegisterMax; i++) {
|
||||
if (reg_state[RegClass_VR][i])
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
UInt32 colored_vrs_as_vrsave(PCodeBlock *block) {
|
||||
PCode *pc;
|
||||
UInt32 mask;
|
||||
int i;
|
||||
|
||||
mask = 0;
|
||||
if (copts.x1B == 2)
|
||||
return 0xFFFFFFFF;
|
||||
if (copts.x1B == 0)
|
||||
return 0;
|
||||
|
||||
while (block) {
|
||||
for (pc = block->firstPCode; pc; pc = pc->nextPCode) {
|
||||
if (pc->flags & (fPCodeFlag40000000 | fPCodeFlag80000000)) {
|
||||
for (i = 0; i < pc->argCount; i++) {
|
||||
if (pc->args[i].kind == PCOp_REGISTER && pc->args[i].arg == RegClass_VR)
|
||||
mask |= 1 << (31 - pc->args[i].data.reg.reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
block = block->nextBlock;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void save_before_coloring_nonvolatile_registers(char rclass) {
|
||||
used_regs_before_coloring = used_nonvolatile_registers[rclass];
|
||||
memcpy(save_state, reg_state[rclass], sizeof(save_state));
|
||||
}
|
||||
|
||||
void reset_nonvolatile_registers(char rclass) {
|
||||
used_nonvolatile_registers[rclass] = used_regs_before_coloring;
|
||||
memcpy(reg_state[rclass], save_state, sizeof(save_state));
|
||||
}
|
||||
|
||||
int is_nonvolatile_register(char rclass, int reg) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_nonvolatile_registers[rclass]; i++) {
|
||||
if (reg == nonvolatile_registers[rclass][i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_endian() {
|
||||
if (copts.little_endian) {
|
||||
high_offset = 4;
|
||||
low_offset = 0;
|
||||
high_reg = 4;
|
||||
low_reg = 3;
|
||||
high_reg2 = 6;
|
||||
low_reg2 = 5;
|
||||
} else {
|
||||
high_offset = 0;
|
||||
low_offset = 4;
|
||||
high_reg = 3;
|
||||
low_reg = 4;
|
||||
high_reg2 = 5;
|
||||
low_reg2 = 6;
|
||||
}
|
||||
}
|
||||
|
||||
void update_asm_nonvolatile_registers() {
|
||||
char rclass;
|
||||
int r31;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
for (r31 = n_nonvolatile_registers[rclass] - 1; r31 >= 0; r31--) {
|
||||
if (reg_state[rclass][nonvolatile_registers[rclass][r31]] == RegState1)
|
||||
break;
|
||||
}
|
||||
if (r31 > used_nonvolatile_registers[rclass])
|
||||
used_nonvolatile_registers[rclass] = r31;
|
||||
}
|
||||
}
|
||||
225
compiler_and_linker/unsorted/Registers.c
Normal file
225
compiler_and_linker/unsorted/Registers.c
Normal file
@@ -0,0 +1,225 @@
|
||||
#include "compiler.h"
|
||||
#include "compiler/objects.h"
|
||||
#include "compiler/PCode.h"
|
||||
|
||||
// haven't checked this object file for .data stuff yet
|
||||
|
||||
// ONLY FOR TESTING
|
||||
// this file gets kinda fucked up by the loop unroller
|
||||
//#pragma opt_unroll_loops off
|
||||
|
||||
int used_virtual_registers[RegClassMax];
|
||||
int used_nonvolatile_registers[RegClassMax];
|
||||
int assignable_registers[RegClassMax];
|
||||
int n_real_registers[RegClassMax];
|
||||
int n_scratch_registers[RegClassMax];
|
||||
int scratch_registers[RegClassMax][RegisterMax];
|
||||
int n_nonvolatile_registers[RegClassMax];
|
||||
int nonvolatile_registers[RegClassMax][RegisterMax];
|
||||
UInt8 reg_state[RegClassMax][RegisterMax];
|
||||
int first_temporary_register[RegClassMax];
|
||||
int last_temporary_register[RegClassMax];
|
||||
char *register_class_name[RegClassMax];
|
||||
char *register_class_format[RegClassMax];
|
||||
int coloring;
|
||||
int optimizing;
|
||||
typedef struct ModifiedRegisters {
|
||||
struct ModifiedRegisters *next;
|
||||
Object *obj;
|
||||
UInt32 mask[RegClassMax];
|
||||
} ModifiedRegisters;
|
||||
static ModifiedRegisters *mod_regs_table[128];
|
||||
|
||||
void init_registers() {
|
||||
char rclass;
|
||||
int j;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
for (j = 0; j < RegisterMax; j++) {
|
||||
reg_state[(char)rclass][j] = RegState0;
|
||||
}
|
||||
}
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++)
|
||||
used_nonvolatile_registers[(char)rclass] = 0;
|
||||
|
||||
optimizing = 1;
|
||||
|
||||
init_target_registers();
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++)
|
||||
used_virtual_registers[(char)rclass] = n_real_registers[(char)rclass];
|
||||
|
||||
coloring = 1;
|
||||
}
|
||||
|
||||
void assign_register_to_variable(Object *obj, char rclass) {
|
||||
VarInfo *vi;
|
||||
short reg;
|
||||
|
||||
vi = Registers_GetVarInfo(obj);
|
||||
if (optimizing) {
|
||||
reg = used_virtual_registers[rclass]++;
|
||||
} else {
|
||||
reg = obtain_nonvolatile_register(rclass);
|
||||
retain_register(obj, rclass, reg);
|
||||
}
|
||||
|
||||
vi->flags |= VarInfoFlag2;
|
||||
vi->rclass = rclass;
|
||||
vi->reg = reg;
|
||||
}
|
||||
|
||||
void retain_register_for_argument(Object *obj, char rclass, short reg) {
|
||||
VarInfo *vi = obj->u.var.info;
|
||||
reg_state[rclass][reg] = RegState1;
|
||||
vi->flags |= VarInfoFlag2;
|
||||
vi->rclass = rclass;
|
||||
vi->reg = reg;
|
||||
}
|
||||
|
||||
int available_registers(char rclass) {
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
for (i = 0; i < n_real_registers[rclass]; i++) {
|
||||
if (reg_state[rclass][i] == RegState0)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
UInt32 volatile_registers(char rclass) {
|
||||
UInt32 mask = 0;
|
||||
int i;
|
||||
int reg;
|
||||
|
||||
for (i = 0; i < n_scratch_registers[rclass]; i++) {
|
||||
reg = scratch_registers[rclass][i];
|
||||
if (reg_state[rclass][reg] == RegState0)
|
||||
mask |= 1 << reg;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
short obtain_nonvolatile_register(char rclass) {
|
||||
int best = -1;
|
||||
|
||||
while (used_nonvolatile_registers[rclass] < n_nonvolatile_registers[rclass]) {
|
||||
int tmp = nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]++];
|
||||
if (reg_state[rclass][tmp] == RegState0) {
|
||||
best = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
void open_temp_registers() {
|
||||
int rclass;
|
||||
|
||||
for (rclass = 0; (char)rclass < RegClassMax; rclass++) {
|
||||
int r = used_virtual_registers[(char)rclass];
|
||||
//last_temporary_register[rclass] = r;
|
||||
//first_temporary_register[rclass] = r;
|
||||
first_temporary_register[(char)rclass] = last_temporary_register[(char)rclass] = r;
|
||||
}
|
||||
/*rclass = 0;
|
||||
while (rclass < RegClassMax) {
|
||||
r = used_virtual_registers[(char)rclass];
|
||||
last_temporary_register[(char)rclass] = r;
|
||||
first_temporary_register[(char)rclass] = r;
|
||||
rclass = rclass + 1;
|
||||
}*/
|
||||
}
|
||||
|
||||
void check_temp_registers() {
|
||||
char rclass;
|
||||
|
||||
if (!optimizing) {
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
if (used_virtual_registers[(char)rclass] > last_temporary_register[(char)rclass])
|
||||
last_temporary_register[(char)rclass] = used_virtual_registers[(char)rclass];
|
||||
if (used_virtual_registers[(char)rclass] > 256)
|
||||
used_virtual_registers[(char)rclass] = first_temporary_register[(char)rclass];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void close_temp_registers() {
|
||||
char rclass;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++) {
|
||||
if (used_virtual_registers[(char)rclass] < last_temporary_register[(char)rclass])
|
||||
used_virtual_registers[(char)rclass] = last_temporary_register[(char)rclass];
|
||||
else
|
||||
last_temporary_register[(char)rclass] = used_virtual_registers[(char)rclass];
|
||||
}
|
||||
}
|
||||
|
||||
int count_scratch_registers() {
|
||||
int rclass;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
for (rclass = 0; (char)rclass < RegClassMax; rclass++)
|
||||
count += n_scratch_registers[(char)rclass];
|
||||
return count;
|
||||
}
|
||||
|
||||
void init_modified_registers() {
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
mod_regs_table[i] = NULL;
|
||||
}
|
||||
|
||||
static void compute_modified_registers(UInt32 *masks) {
|
||||
int rclass;
|
||||
PCodeBlock *block;
|
||||
PCode *pcode;
|
||||
int i;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++)
|
||||
masks[(char)rclass] = 0;
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
|
||||
for (i = 0; i < pcode->argCount; i++) {
|
||||
if (pcode->args[i].kind == PCOp_REGISTER && pcode->args[i].data.reg.effect & EffectWrite)
|
||||
masks[pcode->args[i].arg] |= 1 << pcode->args[i].data.reg.reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void note_modified_registers(Object *obj) {
|
||||
ModifiedRegisters *mr;
|
||||
|
||||
mr = galloc(sizeof(ModifiedRegisters));
|
||||
mr->obj = obj;
|
||||
compute_modified_registers(mr->mask);
|
||||
mr->next = mod_regs_table[obj->name->hashval];
|
||||
mod_regs_table[obj->name->hashval] = mr;
|
||||
}
|
||||
|
||||
void find_modified_registers(Object *obj, UInt32 *masks) {
|
||||
char rclass;
|
||||
ModifiedRegisters *scan;
|
||||
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++)
|
||||
masks[(char)rclass] = 0xFFFFFFFF;
|
||||
|
||||
if (CParser_HasInternalLinkage(obj)) {
|
||||
for (scan = mod_regs_table[obj->name->hashval]; scan; scan = scan->next) {
|
||||
if (scan->obj == obj)
|
||||
break;
|
||||
}
|
||||
if (scan) {
|
||||
for (rclass = 0; rclass < RegClassMax; rclass++)
|
||||
masks[(char)rclass] = scan->mask[(char)rclass];
|
||||
}
|
||||
}
|
||||
}
|
||||
1265
compiler_and_linker/unsorted/StackFrame.c
Normal file
1265
compiler_and_linker/unsorted/StackFrame.c
Normal file
File diff suppressed because it is too large
Load Diff
2041
compiler_and_linker/unsorted/TOC.c
Normal file
2041
compiler_and_linker/unsorted/TOC.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user