- changed GetStore/LoadMoveOp and GetRegType to be based on a set of member variables instead of using virtual functions to return such trivial values. This not only creates significantly better code but also allows overriding these settings without having to create a new class just for changing them (as is needed for vectors.)

This commit is contained in:
Christoph Oelckers 2016-10-28 10:44:01 +02:00
parent 3b1f411dce
commit f511a9398e
3 changed files with 75 additions and 280 deletions

View File

@ -191,18 +191,6 @@ IMPLEMENT_ABSTRACT_POINTY_CLASS(PType)
DECLARE_POINTER(HashNext)
END_POINTERS
//==========================================================================
//
// PType Default Constructor
//
//==========================================================================
PType::PType()
: Size(0), Align(1), HashNext(NULL)
{
mDescriptiveName = "Type";
}
//==========================================================================
//
// PType Parameterized Constructor
@ -213,6 +201,10 @@ PType::PType(unsigned int size, unsigned int align)
: Size(size), Align(align), HashNext(NULL)
{
mDescriptiveName = "Type";
loadOp = OP_NOP;
storeOp = OP_NOP;
moveOp = OP_NOP;
RegType = REGT_NIL;
}
//==========================================================================
@ -477,54 +469,6 @@ double PType::GetValueFloat(void *addr) const
return 0;
}
//==========================================================================
//
// PType :: GetStoreOp
//
//==========================================================================
int PType::GetStoreOp() const
{
assert(0 && "Cannot store this type");
return OP_NOP;
}
//==========================================================================
//
// PType :: GetLoadOp
//
//==========================================================================
int PType::GetLoadOp() const
{
assert(0 && "Cannot load this type");
return OP_NOP;
}
//==========================================================================
//
// PType :: GetMoveOp
//
//==========================================================================
int PType::GetMoveOp() const
{
assert(0 && "Cannot move this type");
return OP_NOP;
}
//==========================================================================
//
// PType :: GetRegType
//
//==========================================================================
int PType::GetRegType() const
{
//assert(0 && "No register for this type"); // wrong place for this assert, it makes it impossible to use this function to check for bad types.
return REGT_NIL;
}
//==========================================================================
//
// PType :: IsMatch
@ -747,6 +691,7 @@ PInt::PInt()
mDescriptiveName = "SInt32";
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, -0x7FFFFFFF - 1));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, 0x7FFFFFFF));
SetOps;
}
//==========================================================================
@ -773,6 +718,33 @@ PInt::PInt(unsigned int size, bool unsign)
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, 0u));
Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, (1u << (8 * size)) - 1));
}
SetOps();
}
void PInt::SetOps()
{
moveOp = OP_MOVE;
RegType = REGT_INT;
if (Size == 4)
{
storeOp = OP_SW;
loadOp = OP_LW;
}
else if (Size == 1)
{
storeOp = OP_SB;
loadOp = Unsigned ? OP_LBU : OP_LB;
}
else if (Size == 2)
{
storeOp = OP_SH;
loadOp = Unsigned ? OP_LHU : OP_LH;
}
else
{
assert(0 && "Unhandled integer size");
storeOp = OP_NOP;
}
}
//==========================================================================
@ -942,76 +914,6 @@ double PInt::GetValueFloat(void *addr) const
//
//==========================================================================
int PInt::GetStoreOp() const
{
if (Size == 4)
{
return OP_SW;
}
else if (Size == 1)
{
return OP_SB;
}
else if (Size == 2)
{
return OP_SH;
}
else
{
assert(0 && "Unhandled integer size");
return OP_NOP;
}
}
//==========================================================================
//
// PInt :: GetLoadOp
//
//==========================================================================
int PInt::GetLoadOp() const
{
if (Size == 4)
{
return OP_LW;
}
else if (Size == 1)
{
return Unsigned ? OP_LBU : OP_LB;
}
else if (Size == 2)
{
return Unsigned ? OP_LHU : OP_LH;
}
else
{
assert(0 && "Unhandled integer size");
return OP_NOP;
}
}
//==========================================================================
//
// PInt :: GetLoadOp
//
//==========================================================================
int PInt::GetMoveOp() const
{
return OP_MOVE;
}
//==========================================================================
//
// PInt :: GetRegType
//
//==========================================================================
int PInt::GetRegType() const
{
return REGT_INT;
}
/* PBool ******************************************************************/
IMPLEMENT_CLASS(PBool)
@ -1048,6 +950,7 @@ PFloat::PFloat()
{
mDescriptiveName = "Float";
SetDoubleSymbols();
SetOps();
}
//==========================================================================
@ -1070,6 +973,7 @@ PFloat::PFloat(unsigned int size)
MemberOnly = true;
SetSingleSymbols();
}
SetOps();
}
//==========================================================================
@ -1264,60 +1168,21 @@ double PFloat::GetValueFloat(void *addr) const
//
//==========================================================================
int PFloat::GetStoreOp() const
void PFloat::SetOps()
{
if (Size == 4)
{
return OP_SSP;
storeOp = OP_SSP;
loadOp = OP_LSP;
}
else
{
assert(Size == 8);
return OP_SDP;
storeOp = OP_SDP;
loadOp = OP_LDP;
}
}
//==========================================================================
//
// PFloat :: GetLoadOp
//
//==========================================================================
int PFloat::GetLoadOp() const
{
if (Size == 4)
{
return OP_LSP;
}
else
{
assert(Size == 8);
return OP_LDP;
}
assert(0 && "Cannot load this type");
return OP_NOP;
}
//==========================================================================
//
// PFloat :: GetMoveOp
//
//==========================================================================
int PFloat::GetMoveOp() const
{
return OP_MOVEF;
}
//==========================================================================
//
// PFloat :: GetRegType
//
//==========================================================================
int PFloat::GetRegType() const
{
return REGT_FLOAT;
moveOp = OP_MOVEF;
RegType = REGT_FLOAT;
}
/* PString ****************************************************************/
@ -1554,50 +1419,10 @@ PStatePointer::PStatePointer()
: PBasicType(sizeof(FState *), __alignof(FState *))
{
mDescriptiveName = "State";
}
//==========================================================================
//
// PStatePointer :: GetStoreOp
//
//==========================================================================
int PStatePointer::GetStoreOp() const
{
return OP_SP;
}
//==========================================================================
//
// PStatePointer :: GetLoadOp
//
//==========================================================================
int PStatePointer::GetLoadOp() const
{
return OP_LP;
}
//==========================================================================
//
// PStatePointer :: GetMoveOp
//
//==========================================================================
int PStatePointer::GetMoveOp() const
{
return OP_MOVEA;
}
//==========================================================================
//
// PStatePointer :: GetRegType
//
//==========================================================================
int PStatePointer::GetRegType() const
{
return REGT_POINTER;
storeOp = OP_SP;
loadOp = OP_LP;
moveOp = OP_MOVEA;
RegType = REGT_POINTER;
}
//==========================================================================
@ -1640,6 +1465,7 @@ PPointer::PPointer()
: PBasicType(sizeof(void *), __alignof(void *)), PointedType(NULL)
{
mDescriptiveName = "NullPointer";
SetOps();
}
//==========================================================================
@ -1652,6 +1478,7 @@ PPointer::PPointer(PType *pointsat)
: PBasicType(sizeof(void *), __alignof(void *)), PointedType(pointsat)
{
mDescriptiveName.Format("Pointer<%s>", pointsat->DescriptiveName());
SetOps();
}
//==========================================================================
@ -1660,42 +1487,12 @@ PPointer::PPointer(PType *pointsat)
//
//==========================================================================
int PPointer::GetStoreOp() const
void PPointer::SetOps()
{
return OP_SP;
}
//==========================================================================
//
// PPointer :: GetLoadOp
//
//==========================================================================
int PPointer::GetLoadOp() const
{
return (PointedType && PointedType->IsKindOf(RUNTIME_CLASS(PClass))) ? OP_LO : OP_LP;
}
//==========================================================================
//
// PPointer :: GetMoveOp
//
//==========================================================================
int PPointer::GetMoveOp() const
{
return OP_MOVEA;
}
//==========================================================================
//
// PPointer :: GetRegType
//
//==========================================================================
int PPointer::GetRegType() const
{
return REGT_POINTER;
storeOp = OP_SP;
loadOp = (PointedType && PointedType->IsKindOf(RUNTIME_CLASS(PClass))) ? OP_LO : OP_LP;
moveOp = OP_MOVEA;
RegType = REGT_POINTER;
}
//==========================================================================

View File

@ -204,6 +204,7 @@ class PType : public PTypeBase
HAS_OBJECT_POINTERS;
protected:
enum { MetaClassNum = CLASSREG_PClassType };
public:
typedef PClassType MetaClass;
MetaClass *GetClass() const;
@ -223,9 +224,9 @@ public:
PSymbolTable Symbols;
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
FString mDescriptiveName;
BYTE loadOp, storeOp, moveOp, RegType;
PType();
PType(unsigned int size, unsigned int align);
PType(unsigned int size = 1, unsigned int align = 1);
virtual ~PType();
bool AddConversion(PType *target, void (*convertconst)(ZCC_ExprConstant *, class FSharedStringArena &));
@ -267,16 +268,28 @@ public:
virtual double GetValueFloat(void *addr) const;
// Gets the opcode to store from a register to memory
virtual int GetStoreOp() const;
int GetStoreOp() const
{
return storeOp;
}
// Gets the opcode to load from memory to a register
virtual int GetLoadOp() const;
int GetLoadOp() const
{
return loadOp;
}
// Gets the opcode to move from register to another register
virtual int GetMoveOp() const;
int GetMoveOp() const
{
return moveOp;
}
// Gets the register type for this type
virtual int GetRegType() const;
int GetRegType() const
{
return RegType;
}
// Returns true if this type matches the two identifiers. Referring to the
// above table, any type is identified by at most two characteristics. Each
@ -410,14 +423,11 @@ public:
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetMoveOp() const;
virtual int GetRegType() const;
bool Unsigned;
protected:
PInt();
void SetOps();
};
class PBool : public PInt
@ -440,12 +450,9 @@ public:
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetMoveOp() const;
virtual int GetRegType() const;
protected:
PFloat();
void SetOps();
private:
struct SymbolInitF
{
@ -518,11 +525,6 @@ public:
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetMoveOp() const;
virtual int GetRegType() const;
};
class PPointer : public PBasicType
@ -535,11 +537,6 @@ public:
PType *PointedType;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
virtual int GetMoveOp() const;
virtual int GetRegType() const;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
@ -547,6 +544,7 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
protected:
void SetOps();
};
class PClassPointer : public PPointer

View File

@ -1461,7 +1461,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
}
if (retval != TypeError && retval->MemberOnly && !formember)
{
Error(field, "Invalid type %s", retval->DescriptiveName()); // fixme: Types need a descriptive name that can be output here.
Error(field, "Invalid type %s", retval->DescriptiveName());
return TypeError;
}
return retval;