This commit is contained in:
Ash Wolf
2022-11-07 03:06:21 +00:00
parent d0b9848c54
commit 9a46dd0e2e
62 changed files with 30796 additions and 1532 deletions

View 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) {}

View 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) {}

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View 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() {}

File diff suppressed because it is too large Load Diff

View 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) {}

File diff suppressed because it is too large Load Diff

View 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) {}

View File

@@ -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;
}

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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() {}

File diff suppressed because it is too large Load Diff

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}

View 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;
}
}

View 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];
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff