mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/GP-4029_ghintern_mips_powerpc_cspecs'
This commit is contained in:
commit
cd18bef25a
26 changed files with 1275 additions and 529 deletions
|
@ -431,7 +431,23 @@ int4 ParamEntry::getSlot(const Address &addr,int4 skip) const
|
|||
/// \param sz is the size of the parameter to allocated
|
||||
/// \param typeAlign is the required byte alignment for the parameter
|
||||
/// \return the address of the new parameter (or an invalid address)
|
||||
Address ParamEntry::getAddrBySlot(int4 &slotnum,int4 sz,int4 typeAlign) const
|
||||
Address ParamEntry::getAddrBySlot(int4 &slotnum, int4 sz, int4 typeAlign) const
|
||||
|
||||
{
|
||||
return getAddrBySlot(slotnum, sz, typeAlign, !isLeftJustified());
|
||||
}
|
||||
|
||||
/// \brief Calculate the storage address assigned when allocating a parameter of a given size
|
||||
///
|
||||
/// Assume \b slotnum slots have already been assigned and increment \b slotnum
|
||||
/// by the number of slots used.
|
||||
/// Return an invalid address if the size is too small or if there are not enough slots left.
|
||||
/// \param slotnum is a reference to used slots (which will be updated)
|
||||
/// \param sz is the size of the parameter to allocated
|
||||
/// \param typeAlign is the required byte alignment for the parameter
|
||||
/// \param justifyRight is true if initial bytes are padding for odd data-type sizes
|
||||
/// \return the address of the new parameter (or an invalid address)
|
||||
Address ParamEntry::getAddrBySlot(int4 &slotnum,int4 sz,int4 typeAlign, bool justifyRight) const
|
||||
|
||||
{
|
||||
Address res; // Start with an invalid result
|
||||
|
@ -471,7 +487,7 @@ Address ParamEntry::getAddrBySlot(int4 &slotnum,int4 sz,int4 typeAlign) const
|
|||
res = Address(spaceid, addressbase + index * alignment);
|
||||
slotnum += slotsused; // Inform caller of number of slots used
|
||||
}
|
||||
if (!isLeftJustified()) // Adjust for right justified (big endian)
|
||||
if (justifyRight) // Adjust for right justified (big endian)
|
||||
res = res + (spaceused - sz);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
int4 getSlot(const Address &addr,int4 skip) const;
|
||||
AddrSpace *getSpace(void) const { return spaceid; } ///< Get the address space containing \b this entry
|
||||
uintb getBase(void) const { return addressbase; } ///< Get the starting offset of \b this entry
|
||||
Address getAddrBySlot(int4 &slot, int4 sz, int4 typeAlign, bool justifyRight) const;
|
||||
Address getAddrBySlot(int4 &slot,int4 sz,int4 typeAlign) const;
|
||||
void decode(Decoder &decoder,bool normalstack,bool grouped,list<ParamEntry> &curList);
|
||||
bool isParamCheckHigh(void) const { return ((flags & extracheck_high)!=0); } ///< Return \b true if there is a high overlap
|
||||
|
|
|
@ -1254,7 +1254,8 @@ AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize",26);
|
|||
AttributeId ATTRIB_STORAGE = AttributeId("storage",149);
|
||||
AttributeId ATTRIB_STACKSPILL = AttributeId("stackspill",150);
|
||||
|
||||
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",156); // Number serves as next open index
|
||||
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",159); // Number serves as next open index
|
||||
|
||||
|
||||
ElementId ELEM_DATA = ElementId("data",1);
|
||||
ElementId ELEM_INPUT = ElementId("input",2);
|
||||
|
|
|
@ -22,6 +22,9 @@ AttributeId ATTRIB_SIZES = AttributeId("sizes",151);
|
|||
AttributeId ATTRIB_MAX_PRIMITIVES = AttributeId("maxprimitives", 153);
|
||||
AttributeId ATTRIB_REVERSESIGNIF = AttributeId("reversesignif", 154);
|
||||
AttributeId ATTRIB_MATCHSIZE = AttributeId("matchsize", 155);
|
||||
AttributeId ATTRIB_AFTER_BYTES = AttributeId("afterbytes", 156);
|
||||
AttributeId ATTRIB_AFTER_STORAGE = AttributeId("afterstorage", 157);
|
||||
AttributeId ATTRIB_FILL_ALTERNATE = AttributeId("fillalternate", 158);
|
||||
|
||||
ElementId ELEM_DATATYPE = ElementId("datatype",273);
|
||||
ElementId ELEM_CONSUME = ElementId("consume",274);
|
||||
|
@ -662,7 +665,7 @@ AssignAction *AssignAction::decodeSideeffect(Decoder &decoder,const ParamListSta
|
|||
action = new ConsumeExtra(res);
|
||||
}
|
||||
else if (elemId == ELEM_EXTRA_STACK) {
|
||||
action = new ExtraStack(res,0);
|
||||
action = new ExtraStack(res);
|
||||
}
|
||||
else if (elemId == ELEM_CONSUME_REMAINING) {
|
||||
action = new ConsumeRemaining(res);
|
||||
|
@ -850,7 +853,7 @@ uint4 MultiSlotAssign::assignAddress(Datatype *dt,const PrototypePieces &proto,i
|
|||
if (!consumeFromStack)
|
||||
return fail;
|
||||
int4 grp = stackEntry->getGroup();
|
||||
Address addr = stackEntry->getAddrBySlot(tmpStatus[grp],sizeLeft,align); // Consume all the space we need
|
||||
Address addr = stackEntry->getAddrBySlot(tmpStatus[grp],sizeLeft,align,justifyRight); // Consume all the space we need
|
||||
if (addr.isInvalid())
|
||||
return fail;
|
||||
pieces.push_back(VarnodeData());
|
||||
|
@ -1043,11 +1046,15 @@ void MultiSlotDualAssign::initializeEntries(void)
|
|||
{
|
||||
resource->extractTiles(baseTiles,baseType);
|
||||
resource->extractTiles(altTiles,altType);
|
||||
stackEntry = resource->getStackEntry();
|
||||
|
||||
if (baseTiles.size() == 0 || altTiles.size() == 0)
|
||||
throw LowlevelError("Could not find matching resources for action: join_dual_class");
|
||||
tileSize = baseTiles[0]->getSize();
|
||||
if (tileSize != altTiles[0]->getSize())
|
||||
throw LowlevelError("Storage class register sizes do not match for action: join_dual_class");
|
||||
if (consumeFromStack && stackEntry == (const ParamEntry *)0)
|
||||
throw LowlevelError("Cannot find matching stack resource for action: join_dual_class");
|
||||
}
|
||||
|
||||
/// \brief Get the index of the first unused ParamEntry in the given list
|
||||
|
@ -1084,6 +1091,8 @@ int4 MultiSlotDualAssign::getTileClass(const PrimitiveExtractor &primitives,int4
|
|||
int4 res = 1;
|
||||
int4 count = 0;
|
||||
int4 endBoundary = off + tileSize;
|
||||
if (index >= primitives.size()) return -1;
|
||||
const PrimitiveExtractor::Primitive &firstPrimitive( primitives.get(index) );
|
||||
while(index < primitives.size()) {
|
||||
const PrimitiveExtractor::Primitive &element( primitives.get(index) );
|
||||
if (element.offset < off) return -1;
|
||||
|
@ -1096,6 +1105,12 @@ int4 MultiSlotDualAssign::getTileClass(const PrimitiveExtractor &primitives,int4
|
|||
res = 0;
|
||||
}
|
||||
if (count == 0) return -1; // Must be at least one primitive in section
|
||||
if (fillAlternate) { // Only use altType if the tile contains one primitive of exactly the tile size
|
||||
if (count > 1)
|
||||
res = 0;
|
||||
if (firstPrimitive.dt->getSize() != tileSize)
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1122,7 @@ MultiSlotDualAssign::MultiSlotDualAssign(const ParamListStandard *res)
|
|||
fillinOutputActive = true;
|
||||
baseType = TYPECLASS_GENERAL; // Tile from general purpose registers
|
||||
altType = TYPECLASS_FLOAT; // Use specialized registers for floating-point components
|
||||
consumeFromStack = false;
|
||||
consumeMostSig = false;
|
||||
justifyRight = false;
|
||||
AddrSpace *spc = res->getSpacebase();
|
||||
|
@ -1114,18 +1130,23 @@ MultiSlotDualAssign::MultiSlotDualAssign(const ParamListStandard *res)
|
|||
consumeMostSig = true;
|
||||
justifyRight = true;
|
||||
}
|
||||
fillAlternate = false;
|
||||
tileSize = 0;
|
||||
stackEntry = (const ParamEntry *)0;
|
||||
}
|
||||
|
||||
MultiSlotDualAssign::MultiSlotDualAssign(type_class baseStore,type_class altStore,bool mostSig,bool justRight,
|
||||
const ParamListStandard *res)
|
||||
MultiSlotDualAssign::MultiSlotDualAssign(type_class baseStore,type_class altStore,bool stack,
|
||||
bool mostSig,bool justRight,bool fillAlt,const ParamListStandard *res)
|
||||
: AssignAction(res)
|
||||
{
|
||||
fillinOutputActive = true;
|
||||
baseType = baseStore;
|
||||
altType = altStore;
|
||||
consumeFromStack = stack;
|
||||
consumeMostSig = mostSig;
|
||||
justifyRight = justRight;
|
||||
fillAlternate = fillAlt;
|
||||
stackEntry = (const ParamEntry *)0;
|
||||
initializeEntries();
|
||||
}
|
||||
|
||||
|
@ -1139,6 +1160,7 @@ uint4 MultiSlotDualAssign::assignAddress(Datatype *dt,const PrototypePieces &pro
|
|||
vector<int4> tmpStatus = status;
|
||||
vector<VarnodeData> pieces;
|
||||
int4 typeSize = dt->getSize();
|
||||
int4 align = dt->getAlignment();
|
||||
int4 sizeLeft = typeSize;
|
||||
int4 iterBase = 0;
|
||||
int4 iterAlt = 0;
|
||||
|
@ -1149,14 +1171,20 @@ uint4 MultiSlotDualAssign::assignAddress(Datatype *dt,const PrototypePieces &pro
|
|||
return fail;
|
||||
if (iterType == 0) {
|
||||
iterBase = getFirstUnused(iterBase, baseTiles, tmpStatus);
|
||||
if (iterBase == baseTiles.size())
|
||||
return fail; // Out of general purpose registers
|
||||
if (iterBase == baseTiles.size()) {
|
||||
if (!consumeFromStack)
|
||||
return fail; // Out of general purpose registers
|
||||
break;
|
||||
}
|
||||
entry = baseTiles[iterBase];
|
||||
}
|
||||
else {
|
||||
iterAlt = getFirstUnused(iterAlt, altTiles, tmpStatus);
|
||||
if (iterAlt == altTiles.size())
|
||||
return fail; // Out of alternate registers
|
||||
if (iterAlt == altTiles.size()) {
|
||||
if (!consumeFromStack)
|
||||
return fail; // Out of alternate registers
|
||||
break;
|
||||
}
|
||||
entry = altTiles[iterAlt];
|
||||
}
|
||||
int4 trialSize = entry->getSize();
|
||||
|
@ -1168,6 +1196,18 @@ uint4 MultiSlotDualAssign::assignAddress(Datatype *dt,const PrototypePieces &pro
|
|||
pieces.back().size = trialSize;
|
||||
sizeLeft -= trialSize;
|
||||
}
|
||||
if (sizeLeft > 0) {
|
||||
if (!consumeFromStack)
|
||||
return fail;
|
||||
int4 grp = stackEntry->getGroup();
|
||||
Address addr = stackEntry->getAddrBySlot(tmpStatus[grp],sizeLeft,align,justifyRight); // Consume all the space we need
|
||||
if (addr.isInvalid())
|
||||
return fail;
|
||||
pieces.push_back(VarnodeData());
|
||||
pieces.back().space = addr.getSpace();
|
||||
pieces.back().offset = addr.getOffset();
|
||||
pieces.back().size = sizeLeft;
|
||||
}
|
||||
if (sizeLeft < 0) { // Have odd data-type size
|
||||
if (justifyRight) {
|
||||
pieces.front().offset += -sizeLeft; // Initial bytes of first entry are padding
|
||||
|
@ -1248,7 +1288,7 @@ void MultiSlotDualAssign::decode(Decoder &decoder)
|
|||
uint4 attribId = decoder.getNextAttributeId();
|
||||
if (attribId == 0) break;
|
||||
if (attribId == ATTRIB_REVERSEJUSTIFY) {
|
||||
if (decoder.readBool())
|
||||
if (decoder.readBool())
|
||||
justifyRight = !justifyRight;
|
||||
}
|
||||
else if (attribId == ATTRIB_REVERSESIGNIF) {
|
||||
|
@ -1261,6 +1301,12 @@ void MultiSlotDualAssign::decode(Decoder &decoder)
|
|||
else if (attribId == ATTRIB_B) {
|
||||
altType = string2typeclass(decoder.readString());
|
||||
}
|
||||
else if (attribId == ATTRIB_STACKSPILL) {
|
||||
consumeFromStack = decoder.readBool();
|
||||
}
|
||||
else if (attribId == ATTRIB_FILL_ALTERNATE) {
|
||||
fillAlternate = decoder.readBool();
|
||||
}
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
initializeEntries(); // Need new firstIter
|
||||
|
@ -1459,16 +1505,19 @@ void ExtraStack::initializeEntry(void)
|
|||
}
|
||||
|
||||
/// \param res is the new resource set to associate with \b this action
|
||||
/// \param val is a dummy value
|
||||
ExtraStack::ExtraStack(const ParamListStandard *res,int4 val)
|
||||
: AssignAction(res)
|
||||
{
|
||||
stackEntry = (const ParamEntry *)0;
|
||||
}
|
||||
|
||||
ExtraStack::ExtraStack(const ParamListStandard *res)
|
||||
: AssignAction(res)
|
||||
{
|
||||
afterBytes = -1;
|
||||
afterStorage = TYPECLASS_GENERAL;
|
||||
stackEntry = (const ParamEntry *)0;
|
||||
}
|
||||
|
||||
ExtraStack::ExtraStack(type_class storage, int4 offset, const ParamListStandard *res)
|
||||
: AssignAction(res)
|
||||
{
|
||||
afterStorage = storage;
|
||||
afterBytes = offset;
|
||||
stackEntry = (const ParamEntry *)0;
|
||||
initializeEntry();
|
||||
}
|
||||
|
@ -1479,6 +1528,26 @@ uint4 ExtraStack::assignAddress(Datatype *dt,const PrototypePieces &proto,int4 p
|
|||
if (res.addr.getSpace() == stackEntry->getSpace())
|
||||
return success; // Parameter was already assigned to the stack
|
||||
int4 grp = stackEntry->getGroup();
|
||||
// Check whether we have consumed enough storage to need to adjust the stack yet
|
||||
if (afterBytes > 0) {
|
||||
const list<ParamEntry>& entryList = resource->getEntry();
|
||||
int4 bytesConsumed = 0;
|
||||
list<ParamEntry>::const_iterator iter = entryList.begin();
|
||||
list<ParamEntry>::const_iterator endIter = entryList.end();
|
||||
while (iter != endIter) {
|
||||
const ParamEntry &entry(*iter);
|
||||
++iter;
|
||||
if (entry.getGroup() == grp || entry.getType() != afterStorage) {
|
||||
continue;
|
||||
}
|
||||
if (status[entry.getGroup()] != 0) {
|
||||
bytesConsumed += entry.getSize();
|
||||
}
|
||||
}
|
||||
if (bytesConsumed < afterBytes) {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
// We assign the stack address (but ignore the actual address) updating the status for the stack,
|
||||
// which consumes the stack resources.
|
||||
stackEntry->getAddrBySlot(status[grp],dt->getSize(),dt->getAlignment());
|
||||
|
@ -1489,6 +1558,14 @@ void ExtraStack::decode(Decoder &decoder)
|
|||
|
||||
{
|
||||
uint4 elemId = decoder.openElement(ELEM_EXTRA_STACK);
|
||||
for (;;) {
|
||||
uint4 attribId = decoder.getNextAttributeId();
|
||||
if (attribId == 0) break;
|
||||
else if (attribId == ATTRIB_AFTER_BYTES)
|
||||
afterBytes = decoder.readUnsignedInteger();
|
||||
else if (attribId == ATTRIB_AFTER_STORAGE)
|
||||
afterStorage = string2typeclass(decoder.readString());
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
initializeEntry();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ extern AttributeId ATTRIB_SIZES; ///< Marshaling attribute "sizes"
|
|||
extern AttributeId ATTRIB_MAX_PRIMITIVES; ///< Marshaling attribute "maxprimitives"
|
||||
extern AttributeId ATTRIB_REVERSESIGNIF; ///< Marshaling attribute "reversesignif"
|
||||
extern AttributeId ATTRIB_MATCHSIZE; ///< Marshaling attribute "matchsize"
|
||||
extern AttributeId ATTRIB_AFTER_BYTES; ///< Marshaling attribute "afterbytes"
|
||||
extern AttributeId ATTRIB_AFTER_STORAGE; ///< Marshaling attribute "afterstorage"
|
||||
extern AttributeId ATTRIB_FILL_ALTERNATE; ///< Marshalling attribute "fillalternate"
|
||||
|
||||
extern ElementId ELEM_DATATYPE; ///< Marshaling element \<datatype>
|
||||
extern ElementId ELEM_CONSUME; ///< Marshaling element \<consume>
|
||||
|
@ -396,20 +399,24 @@ public:
|
|||
class MultiSlotDualAssign : public AssignAction {
|
||||
type_class baseType; ///< Resource list from which to consume general tiles
|
||||
type_class altType; ///< Resource list from which to consume alternate tiles
|
||||
bool consumeFromStack; ///< True if resources should be consumed from the stack
|
||||
bool consumeMostSig; ///< True if resources are consumed starting with most significant bytes
|
||||
bool justifyRight; ///< True if initial bytes are padding for odd data-type sizes
|
||||
bool fillAlternate; ///< True if a single primitive needs to fill an alternate tile
|
||||
int4 tileSize; ///< Number of bytes in a tile
|
||||
vector<const ParamEntry *> baseTiles; ///< General registers to be joined
|
||||
vector<const ParamEntry *> altTiles; ///< Alternate registers to be joined
|
||||
const ParamEntry *stackEntry; ///< The stack resource
|
||||
void initializeEntries(void); ///< Cache specific ParamEntry needed by the action
|
||||
int4 getFirstUnused(int4 iter,const vector<const ParamEntry *> &tiles,vector<int4> &status) const;
|
||||
int4 getTileClass(const PrimitiveExtractor &primitives,int4 off,int4 &index) const;
|
||||
public:
|
||||
MultiSlotDualAssign(const ParamListStandard *res); ///< Constructor for use with decode
|
||||
MultiSlotDualAssign(type_class baseStore,type_class altStore,bool mostSig,bool justRight,
|
||||
const ParamListStandard *res); ///< Constructor
|
||||
MultiSlotDualAssign(type_class baseStore,type_class altStore,bool stack,bool mostSig,
|
||||
bool justRight,bool fillAlt,const ParamListStandard *res); ///< Constructor
|
||||
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
||||
return new MultiSlotDualAssign(baseType,altType,consumeMostSig,justifyRight,newResource); }
|
||||
return new MultiSlotDualAssign(baseType,altType,consumeFromStack,consumeMostSig,justifyRight,
|
||||
fillAlternate,newResource); }
|
||||
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||
vector<int4> &status,ParameterPieces &res) const;
|
||||
virtual bool fillinOutputMap(ParamActive *active) const;
|
||||
|
@ -484,13 +491,15 @@ public:
|
|||
/// stack resources as if the parameter were allocated to the stack. If the current parameter was
|
||||
/// already assigned a stack address, no additional action is taken.
|
||||
class ExtraStack : public AssignAction {
|
||||
int4 afterBytes; ///< Activate side effect after given number of bytes consumed
|
||||
type_class afterStorage; ///< Activate side effect after given amount of this storage consumed
|
||||
const ParamEntry *stackEntry; ///< Parameter Entry corresponding to the stack
|
||||
void initializeEntry(void); ///< Find stack entry in resource list
|
||||
public:
|
||||
ExtraStack(const ParamListStandard *res,int4 val); ///< Constructor for use with decode
|
||||
ExtraStack(const ParamListStandard *res); ///< Constructor
|
||||
ExtraStack(const ParamListStandard *res); ///< Constructor for use with decode
|
||||
ExtraStack(type_class storage,int4 offset,const ParamListStandard *res); ///< Constructor
|
||||
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
||||
return new ExtraStack(newResource); }
|
||||
return new ExtraStack(afterStorage,afterBytes,newResource); }
|
||||
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||
vector<int4> &status,ParameterPieces &res) const;
|
||||
virtual void decode(Decoder &decoder);
|
||||
|
|
|
@ -449,6 +449,16 @@
|
|||
<attribute name="reversesignif">
|
||||
<ref name="boolean_type"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="stackspill">
|
||||
<ref name="boolean_type"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="fillalternate">
|
||||
<ref name="boolean_type"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="storage"/>
|
||||
|
@ -461,6 +471,16 @@
|
|||
</optional>
|
||||
</element>
|
||||
</choice>
|
||||
<zeroOrMore>
|
||||
<element name="extra_stack">
|
||||
<optional>
|
||||
<attribute name="afterbytes"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="afterstorage"/>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<element name="consume_extra">
|
||||
<attribute name="storage"/>
|
||||
|
@ -474,13 +494,8 @@
|
|||
<zeroOrMore>
|
||||
<element name="consume_remaining">
|
||||
<attribute name="storage"/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<element name="extra_stack">
|
||||
<empty/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
|
||||
<define name="prototype_type">
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -338,6 +338,22 @@ public class ParamEntry {
|
|||
* @return slotnum plus the number of slots used
|
||||
*/
|
||||
public int getAddrBySlot(int slotnum, int sz, int typeAlign, ParameterPieces res) {
|
||||
return getAddrBySlot(slotnum, sz, typeAlign, res, !isLeftJustified());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the storage address when allocating something of size -sz- assuming -slotnum- slots
|
||||
* have already been assigned. Set the address to null if the -sz- is too small or if
|
||||
* there are not enough slots left
|
||||
* @param slotnum number of slots already assigned
|
||||
* @param sz number of bytes to being assigned
|
||||
* @param typeAlign required byte alignment for the parameter
|
||||
* @param res will hold the final storage address
|
||||
* @param justifyRight true if initial bytes are padding for odd data-type sizes
|
||||
* @return slotnum plus the number of slots used
|
||||
*/
|
||||
public int getAddrBySlot(int slotnum, int sz, int typeAlign, ParameterPieces res,
|
||||
boolean justifyRight) {
|
||||
int spaceused;
|
||||
long offset;
|
||||
res.address = null; // Start with an invalid result
|
||||
|
@ -387,7 +403,7 @@ public class ParamEntry {
|
|||
offset = addressbase + index * alignment;
|
||||
slotnum += slotsused; // Inform caller of number of slots used
|
||||
}
|
||||
if (!isLeftJustified()) {
|
||||
if (justifyRight) {
|
||||
offset += (spaceused - sz);
|
||||
}
|
||||
res.address = spaceid.getAddress(offset);
|
||||
|
|
|
@ -15,15 +15,19 @@
|
|||
*/
|
||||
package ghidra.program.model.lang.protorules;
|
||||
|
||||
import static ghidra.program.model.pcode.AttributeId.*;
|
||||
import static ghidra.program.model.pcode.ElementId.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.pcode.Encoder;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
import ghidra.xml.*;
|
||||
|
||||
/**
|
||||
|
@ -37,6 +41,8 @@ import ghidra.xml.*;
|
|||
public class ExtraStack extends AssignAction {
|
||||
|
||||
private ParamEntry stackEntry; // Parameter entry corresponding to the stack
|
||||
private int afterBytes; // Activate side effect after given number of bytes consumed
|
||||
private StorageClass afterStorage; // Active side effect after given amount of this storage consumed
|
||||
|
||||
/**
|
||||
* Find stack entry in resource list
|
||||
|
@ -64,17 +70,22 @@ public class ExtraStack extends AssignAction {
|
|||
public ExtraStack(ParamListStandard res, int val) {
|
||||
super(res);
|
||||
stackEntry = null;
|
||||
afterStorage = StorageClass.GENERAL;
|
||||
afterBytes = -1;
|
||||
}
|
||||
|
||||
public ExtraStack(ParamListStandard res) throws InvalidInputException {
|
||||
public ExtraStack(StorageClass storage, int offset, ParamListStandard res)
|
||||
throws InvalidInputException {
|
||||
super(res);
|
||||
stackEntry = null;
|
||||
afterStorage = storage;
|
||||
afterBytes = offset;
|
||||
initializeEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssignAction clone(ParamListStandard newResource) throws InvalidInputException {
|
||||
return new ExtraStack(newResource);
|
||||
return new ExtraStack(afterStorage, afterBytes, newResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,7 +93,13 @@ public class ExtraStack extends AssignAction {
|
|||
if (this.getClass() != op.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExtraStack otherAction = (ExtraStack) op;
|
||||
|
||||
if (afterBytes != otherAction.afterBytes || afterStorage != otherAction.afterStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stackEntry.isEquivalent(otherAction.stackEntry);
|
||||
}
|
||||
|
||||
|
@ -93,6 +110,21 @@ public class ExtraStack extends AssignAction {
|
|||
return SUCCESS; // Parameter was already assigned to the stack
|
||||
}
|
||||
int grp = stackEntry.getGroup();
|
||||
// Check whether we have consumed enough storage to need to adjust stack yet
|
||||
if (afterBytes > 0) {
|
||||
int bytesConsumed = 0;
|
||||
for (int i = 0; i < resource.getNumParamEntry(); i++) {
|
||||
if (i == grp || resource.getEntry(i).getType() != afterStorage) {
|
||||
continue;
|
||||
}
|
||||
if (status[i] != 0) {
|
||||
bytesConsumed += resource.getEntry(i).getSize();
|
||||
}
|
||||
}
|
||||
if (bytesConsumed < afterBytes) {
|
||||
return SUCCESS; // Don't yet need to consume extra stack space
|
||||
}
|
||||
}
|
||||
// We assign the stack address (but ignore the actual address) updating the status for the stack,
|
||||
// which consumes the stack resources.
|
||||
ParameterPieces unused = new ParameterPieces();
|
||||
|
@ -104,12 +136,34 @@ public class ExtraStack extends AssignAction {
|
|||
@Override
|
||||
public void encode(Encoder encoder) throws IOException {
|
||||
encoder.openElement(ELEM_EXTRA_STACK);
|
||||
if (afterBytes >= 0) {
|
||||
encoder.writeUnsignedInteger(ATTRIB_AFTER_BYTES, afterBytes);
|
||||
}
|
||||
if (afterStorage != StorageClass.GENERAL) {
|
||||
encoder.writeString(ATTRIB_STORAGE, afterStorage.toString());
|
||||
}
|
||||
encoder.closeElement(ELEM_EXTRA_STACK);
|
||||
}
|
||||
|
||||
private void restoreAttributesXml(XmlElement el) throws XmlParseException {
|
||||
Iterator<Entry<String, String>> iter = el.getAttributes().entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entry<String, String> attrib = iter.next();
|
||||
String nm = attrib.getKey();
|
||||
if (nm.equals(ATTRIB_AFTER_BYTES.name())) {
|
||||
afterBytes = SpecXmlUtils.decodeInt(attrib.getValue());
|
||||
}
|
||||
else if (nm.equals(ATTRIB_AFTER_STORAGE.name())) {
|
||||
afterStorage = StorageClass.getClass(attrib.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreXml(XmlPullParser parser) throws XmlParseException {
|
||||
XmlElement elem = parser.start(ELEM_EXTRA_STACK.name());
|
||||
restoreAttributesXml(elem);
|
||||
parser.end(elem);
|
||||
try {
|
||||
initializeEntry();
|
||||
|
|
|
@ -227,7 +227,8 @@ public class MultiSlotAssign extends AssignAction {
|
|||
return FAIL;
|
||||
}
|
||||
int grp = stackEntry.getGroup();
|
||||
tmpStatus[grp] = stackEntry.getAddrBySlot(tmpStatus[grp], sizeLeft, align, param); // Consume all the space we need
|
||||
tmpStatus[grp] =
|
||||
stackEntry.getAddrBySlot(tmpStatus[grp], sizeLeft, align, param, justifyRight); // Consume all the space we need
|
||||
if (param.address == null) {
|
||||
return FAIL;
|
||||
}
|
||||
|
|
|
@ -42,11 +42,14 @@ import ghidra.xml.*;
|
|||
public class MultiSlotDualAssign extends AssignAction {
|
||||
private StorageClass baseType; // Resource list from which to consume general tiles
|
||||
private StorageClass altType; // Resource list from which to consume alternate tiles
|
||||
private boolean consumeFromStack; // True if resources can be consumed from the stack
|
||||
private boolean consumeMostSig; // True if resources are consumed starting with most significant bytes
|
||||
private boolean justifyRight; // True if initial bytes are padding for odd data-type sizes
|
||||
private boolean fillAlternate; // True if a single primitive needs to fill an alternate tile
|
||||
private int tileSize; // Number of bytes in a tile
|
||||
private ParamEntry[] baseTiles; // General registers for joining
|
||||
private ParamEntry[] altTiles; // Alternate registers for joininig
|
||||
private ParamEntry[] altTiles; // Alternate registers for joining
|
||||
private ParamEntry stackEntry; // The stack resource
|
||||
|
||||
/**
|
||||
* Find the first ParamEntry matching the baseType, and the first matching altType.
|
||||
|
@ -55,6 +58,7 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
private void initializeEntries() throws InvalidInputException {
|
||||
baseTiles = resource.extractTiles(baseType);
|
||||
altTiles = resource.extractTiles(altType);
|
||||
stackEntry = resource.extractStack();
|
||||
if (baseTiles.length == 0 || altTiles.length == 0) {
|
||||
throw new InvalidInputException(
|
||||
"Could not find matching resources for action: join_dual_class");
|
||||
|
@ -64,6 +68,10 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
throw new InvalidInputException(
|
||||
"Storage class register sizes do not match for action: join_dual_class");
|
||||
}
|
||||
if (consumeFromStack && stackEntry == null) {
|
||||
throw new InvalidInputException(
|
||||
"Cannot find matching stack resource for action: join_dual_class");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,6 +109,10 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
int res = 1;
|
||||
int count = 0;
|
||||
int endBoundary = off + tileSize;
|
||||
if (index[0] >= primitives.size()) {
|
||||
return -1;
|
||||
}
|
||||
Primitive firstPrimitive = primitives.get(index[0]);
|
||||
while (index[0] < primitives.size()) {
|
||||
Primitive element = primitives.get(index[0]);
|
||||
if (element.offset < off) {
|
||||
|
@ -122,6 +134,14 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
if (count == 0) {
|
||||
return -1; // Must be at least one primitive in section
|
||||
}
|
||||
if (fillAlternate) { // Only use altType if the tile contains one primitive of exactly the tile size
|
||||
if (count > 1) {
|
||||
res = 0;
|
||||
}
|
||||
if (firstPrimitive.dt.getLength() != tileSize) {
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -133,29 +153,47 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
super(res);
|
||||
baseType = StorageClass.GENERAL; // Tile from general purpose registers
|
||||
altType = StorageClass.FLOAT; // Use specialized registers for floating-point components
|
||||
consumeFromStack = false;
|
||||
consumeMostSig = false;
|
||||
justifyRight = false;
|
||||
if (res.getEntry(0).isBigEndian()) {
|
||||
consumeMostSig = true;
|
||||
justifyRight = true;
|
||||
}
|
||||
fillAlternate = false;
|
||||
tileSize = 0;
|
||||
stackEntry = null;
|
||||
}
|
||||
|
||||
public MultiSlotDualAssign(StorageClass baseStore, StorageClass altStore, boolean mostSig,
|
||||
boolean justRight, ParamListStandard res) throws InvalidInputException {
|
||||
/**
|
||||
* Constructor
|
||||
* @param baseStore resource list from which to consume general tiles
|
||||
* @param altStore resource list form which to consume alternate tiles
|
||||
* @param stack true if resources can be consumed from the stack
|
||||
* @param mostSig true if resources are consumed starting with most significant bytes
|
||||
* @param justRight true if initial bytes are padding for odd data-type sizes
|
||||
* @param fillAlt true if a single primitive needs to fill an alternate tile
|
||||
* @param res is the new resource set to associate with this action
|
||||
* @throws InvalidInputException if the required elements are not available in the resource list
|
||||
*/
|
||||
public MultiSlotDualAssign(StorageClass baseStore, StorageClass altStore, boolean stack,
|
||||
boolean mostSig, boolean justRight, boolean fillAlt, ParamListStandard res)
|
||||
throws InvalidInputException {
|
||||
super(res);
|
||||
baseType = baseStore;
|
||||
altType = altStore;
|
||||
consumeFromStack = stack;
|
||||
consumeMostSig = mostSig;
|
||||
justifyRight = justRight;
|
||||
fillAlternate = fillAlt;
|
||||
stackEntry = null;
|
||||
initializeEntries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssignAction clone(ParamListStandard newResource) throws InvalidInputException {
|
||||
return new MultiSlotDualAssign(baseType, altType, consumeMostSig, justifyRight,
|
||||
newResource);
|
||||
return new MultiSlotDualAssign(baseType, altType, consumeFromStack, consumeMostSig,
|
||||
justifyRight, fillAlternate, newResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -164,8 +202,10 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
return false;
|
||||
}
|
||||
MultiSlotDualAssign otherAction = (MultiSlotDualAssign) op;
|
||||
if (consumeMostSig != otherAction.consumeMostSig ||
|
||||
justifyRight != otherAction.justifyRight) {
|
||||
if (consumeFromStack != otherAction.consumeFromStack ||
|
||||
consumeMostSig != otherAction.consumeMostSig ||
|
||||
justifyRight != otherAction.justifyRight ||
|
||||
fillAlternate != otherAction.fillAlternate) {
|
||||
return false;
|
||||
}
|
||||
if (baseType != otherAction.baseType || altType != otherAction.altType) {
|
||||
|
@ -203,6 +243,7 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
int[] tmpStatus = status.clone();
|
||||
ArrayList<Varnode> pieces = new ArrayList<>();
|
||||
int typeSize = dt.getLength();
|
||||
int align = dt.getAlignment();
|
||||
int sizeLeft = typeSize;
|
||||
int iterBase = 0;
|
||||
int iterAlt = 0;
|
||||
|
@ -215,14 +256,20 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
if (iterType == 0) {
|
||||
iterBase = getFirstUnused(iterBase, baseTiles, tmpStatus);
|
||||
if (iterBase == baseTiles.length) {
|
||||
return FAIL; // Out of general registers
|
||||
if (!consumeFromStack) {
|
||||
return FAIL; // Out of general registers
|
||||
}
|
||||
break;
|
||||
}
|
||||
entry = baseTiles[iterBase];
|
||||
}
|
||||
else {
|
||||
iterAlt = getFirstUnused(iterAlt, altTiles, tmpStatus);
|
||||
if (iterAlt == altTiles.length) {
|
||||
return FAIL; // Out of alternate registers
|
||||
if (!consumeFromStack) {
|
||||
return FAIL; // Out of alternate registers
|
||||
}
|
||||
break;
|
||||
}
|
||||
entry = altTiles[iterAlt];
|
||||
}
|
||||
|
@ -233,6 +280,19 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
pieces.add(vn);
|
||||
sizeLeft -= trialSize;
|
||||
}
|
||||
if (sizeLeft > 0) { // Have to use stack to get enough bytes
|
||||
if (!consumeFromStack) {
|
||||
return FAIL;
|
||||
}
|
||||
int grp = stackEntry.getGroup();
|
||||
tmpStatus[grp] =
|
||||
stackEntry.getAddrBySlot(tmpStatus[grp], sizeLeft, align, param, justifyRight);
|
||||
if (param.address == null) {
|
||||
return FAIL;
|
||||
}
|
||||
Varnode vn = new Varnode(param.address, sizeLeft);
|
||||
pieces.add(vn);
|
||||
}
|
||||
if (sizeLeft < 0) { // Have odd data-type size
|
||||
if (justifyRight) {
|
||||
// Initial bytes of first entry are padding
|
||||
|
@ -271,6 +331,8 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
if (altType != StorageClass.FLOAT) {
|
||||
encoder.writeString(ATTRIB_B, altType.toString());
|
||||
}
|
||||
encoder.writeBool(ATTRIB_STACKSPILL, consumeFromStack);
|
||||
encoder.writeBool(ATTRIB_FILL_ALTERNATE, fillAlternate);
|
||||
encoder.closeElement(ELEM_JOIN);
|
||||
}
|
||||
|
||||
|
@ -295,6 +357,12 @@ public class MultiSlotDualAssign extends AssignAction {
|
|||
else if (name.equals(ATTRIB_B.name())) {
|
||||
altType = StorageClass.getClass(attrib.getValue());
|
||||
}
|
||||
else if (name.equals(ATTRIB_STACKSPILL.name())) {
|
||||
consumeFromStack = SpecXmlUtils.decodeBoolean(attrib.getValue());
|
||||
}
|
||||
else if (name.equals(ATTRIB_FILL_ALTERNATE.name())) {
|
||||
fillAlternate = SpecXmlUtils.decodeBoolean(attrib.getValue());
|
||||
}
|
||||
}
|
||||
parser.end(elem);
|
||||
try {
|
||||
|
|
|
@ -247,10 +247,13 @@ public record AttributeId(String name, int id) {
|
|||
// modelrules
|
||||
public static final AttributeId ATTRIB_SIZES = new AttributeId("sizes", 151);
|
||||
public static final AttributeId ATTRIB_BACKFILL = new AttributeId("backfill", 152);
|
||||
|
||||
public static final AttributeId ATTRIB_MAX_PRIMITIVES = new AttributeId("maxprimitives", 153);
|
||||
public static final AttributeId ATTRIB_REVERSESIGNIF = new AttributeId("reversesignif", 154);
|
||||
public static final AttributeId ATTRIB_MATCHSIZE = new AttributeId("matchsize", 155);
|
||||
public static final AttributeId ATTRIB_AFTER_BYTES = new AttributeId("afterbytes", 156);
|
||||
public static final AttributeId ATTRIB_AFTER_STORAGE = new AttributeId("afterstorage", 157);
|
||||
public static final AttributeId ATTRIB_FILL_ALTERNATE = new AttributeId("fillalternate", 158);
|
||||
|
||||
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 159);
|
||||
|
||||
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 156);
|
||||
}
|
||||
|
|
|
@ -11,22 +11,22 @@ data/languages/mips32Instructions.sinc||GHIDRA||||END|
|
|||
data/languages/mips32R6.pspec||GHIDRA||||END|
|
||||
data/languages/mips32R6be.slaspec||GHIDRA||||END|
|
||||
data/languages/mips32R6le.slaspec||GHIDRA||||END|
|
||||
data/languages/mips32_eabi.cspec||GHIDRA||||END|
|
||||
data/languages/mips32_fp64.cspec||GHIDRA||||END|
|
||||
data/languages/mips32be.cspec||GHIDRA||||END|
|
||||
data/languages/mips32be.slaspec||GHIDRA||||END|
|
||||
data/languages/mips32be_eabi.cspec||GHIDRA||||END|
|
||||
data/languages/mips32le.cspec||GHIDRA||||END|
|
||||
data/languages/mips32le.slaspec||GHIDRA||||END|
|
||||
data/languages/mips32le_eabi.cspec||GHIDRA||||END|
|
||||
data/languages/mips32micro.pspec||GHIDRA||||END|
|
||||
data/languages/mips64.cspec||GHIDRA||||END|
|
||||
data/languages/mips64.pspec||GHIDRA||||END|
|
||||
data/languages/mips64Instructions.sinc||GHIDRA||||END|
|
||||
data/languages/mips64R6.pspec||GHIDRA||||END|
|
||||
data/languages/mips64_32_n32.cspec||GHIDRA||||END|
|
||||
data/languages/mips64_32_o32.cspec||GHIDRA||||END|
|
||||
data/languages/mips64_32_o64.cspec||GHIDRA||||END|
|
||||
data/languages/mips64be.cspec||GHIDRA||||END|
|
||||
data/languages/mips64be.slaspec||GHIDRA||||END|
|
||||
data/languages/mips64le.cspec||GHIDRA||||END|
|
||||
data/languages/mips64le.slaspec||GHIDRA||||END|
|
||||
data/languages/mips64micro.pspec||GHIDRA||||END|
|
||||
data/languages/mips_dsp.sinc||GHIDRA||||END|
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32be.sla"
|
||||
processorspec="mips32.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>MIPS32 32-bit addresses, big endian, with mips16e</description>
|
||||
<compiler name="default" spec="mips32be.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips32be.cspec" id="windows"/>
|
||||
<compiler name="eabi" spec="mips32be_eabi.cspec" id="eabi"/>
|
||||
<compiler name="eabi" spec="mips32_eabi.cspec" id="eabi"/>
|
||||
<external_name tool="gnu" name="mips:3000"/>
|
||||
<external_name tool="gnu" name="mips:4000"/>
|
||||
<external_name tool="IDA-PRO" name="mipsb"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32le.sla"
|
||||
processorspec="mips32.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
|
@ -32,7 +32,7 @@
|
|||
<description>MIPS32 32-bit addresses, little endian, with mips16e</description>
|
||||
<compiler name="default" spec="mips32le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips32le.cspec" id="windows"/>
|
||||
<compiler name="eabi" spec="mips32le_eabi.cspec" id="eabi"/>
|
||||
<compiler name="eabi" spec="mips32_eabi.cspec" id="eabi"/>
|
||||
<external_name tool="gnu" name="mips:3000"/>
|
||||
<external_name tool="gnu" name="mips:4000"/>
|
||||
<external_name tool="IDA-PRO" name="mipsl"/>
|
||||
|
@ -44,7 +44,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32R6be.sla"
|
||||
processorspec="mips32R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -60,7 +60,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32R6le.sla"
|
||||
processorspec="mips32R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -76,13 +76,13 @@
|
|||
endian="big"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
id="MIPS:BE:64:default">
|
||||
<description>MIPS64 64-bit addresses, big endian, with mips16e</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="default" spec="mips64be.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="mips:5000"/>
|
||||
<external_name tool="IDA-PRO" name="mipsb"/>
|
||||
<external_name tool="IDA-PRO" name="r5900r"/>
|
||||
|
@ -94,14 +94,14 @@
|
|||
endian="little"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
id="MIPS:LE:64:default">
|
||||
<description>MIPS64 64-bit addreses, little endian, with mips16e</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64.cspec" id="windows"/>
|
||||
<compiler name="default" spec="mips64le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64le.cspec" id="windows"/>
|
||||
<external_name tool="gnu" name="mips:5000"/>
|
||||
<external_name tool="IDA-PRO" name="mipsl"/>
|
||||
<external_name tool="IDA-PRO" name="r5900l"/>
|
||||
|
@ -113,13 +113,13 @@
|
|||
endian="big"
|
||||
size="64"
|
||||
variant="micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
id="MIPS:BE:64:micro">
|
||||
<description>MIPS64 64-bit addresses, big endian, with microMIPS</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="default" spec="mips64be.cspec" id="default"/>
|
||||
<external_name tool="IDA-PRO" name="mipsb"/>
|
||||
<external_name tool="IDA-PRO" name="r5900r"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="mips.dwarf"/>
|
||||
|
@ -128,14 +128,14 @@
|
|||
endian="little"
|
||||
size="64"
|
||||
variant="micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
id="MIPS:LE:64:micro">
|
||||
<description>MIPS64 64-bit addresses, little endian, with microMIPS</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64.cspec" id="windows"/>
|
||||
<compiler name="default" spec="mips64le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64le.cspec" id="windows"/>
|
||||
<external_name tool="IDA-PRO" name="mipsl"/>
|
||||
<external_name tool="IDA-PRO" name="r5900l"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="mips.dwarf"/>
|
||||
|
@ -144,13 +144,13 @@
|
|||
endian="big"
|
||||
size="64"
|
||||
variant="R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
id="MIPS:BE:64:R6">
|
||||
<description>MIPS64 Release-6 64-bit addresses, big endian, with microMIPS</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="default" spec="mips64be.cspec" id="default"/>
|
||||
<external_name tool="IDA-PRO" name="mipsb"/>
|
||||
<external_name tool="IDA-PRO" name="r5900r"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="mips.dwarf"/>
|
||||
|
@ -161,14 +161,14 @@
|
|||
endian="little"
|
||||
size="64"
|
||||
variant="R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
id="MIPS:LE:64:R6">
|
||||
<description>MIPS64 Release-6 64-bit addresses, little endian, with microMIPS</description>
|
||||
<compiler name="default" spec="mips64.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64.cspec" id="windows"/>
|
||||
<compiler name="default" spec="mips64le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="mips64le.cspec" id="windows"/>
|
||||
<external_name tool="IDA-PRO" name="mipsl"/>
|
||||
<external_name tool="IDA-PRO" name="r5900l"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="mips.dwarf"/>
|
||||
|
@ -179,7 +179,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="64-32addr"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
|
@ -201,7 +201,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="64-32addr"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64.pspec"
|
||||
manualindexfile="../manuals/mipsM16.idx"
|
||||
|
@ -224,7 +224,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="64-32addr-micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -244,7 +244,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="64-32addr-micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -263,7 +263,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="64-32addr-R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64be.sla"
|
||||
processorspec="mips64R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -284,7 +284,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="64-32addr-R6"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips64le.sla"
|
||||
processorspec="mips64R6.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -306,7 +306,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32be.sla"
|
||||
processorspec="mips32micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
@ -321,7 +321,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="micro"
|
||||
version="1.8"
|
||||
version="1.9"
|
||||
slafile="mips32le.sla"
|
||||
processorspec="mips32micro.pspec"
|
||||
manualindexfile="../manuals/mipsMic.idx"
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<char_size value="1"/>
|
||||
<short_size value="2"/>
|
||||
<integer_size value="4"/>
|
||||
<pointer_size value="4"/>
|
||||
<long_size value="4"/>
|
||||
<long_long_size value="8"/>
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="8" />
|
||||
|
@ -65,6 +70,34 @@
|
|||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate" maxprimitives="1"/>
|
||||
<join_per_primitive storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate" maxprimitives="1"/>
|
||||
<goto_stack/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<goto_stack/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct" minsize="5"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union" minsize="5"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join align="true"/>
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
|
@ -73,9 +106,21 @@
|
|||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="v0" piece2="v1"/>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v1"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate" maxprimitives="1"/>
|
||||
<join_per_primitive storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
|
@ -97,21 +142,11 @@
|
|||
<register name="f30"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="a0"/>
|
||||
<register name="a1"/>
|
||||
<register name="a2"/>
|
||||
<register name="a3"/>
|
||||
<register name="t0"/>
|
||||
<register name="t1"/>
|
||||
<register name="t2"/>
|
||||
<register name="t3"/>
|
||||
<register name="t4"/>
|
||||
<register name="t5"/>
|
||||
<register name="t6"/>
|
||||
<register name="t7"/>
|
||||
<register name="t8"/>
|
||||
<register name="t9"/>
|
||||
<register name="at"/>
|
||||
<register name="v0"/>
|
||||
<register name="v1"/>
|
||||
<register name="f0"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfff0bdc0" last="0xffffffff"/>
|
|
@ -25,6 +25,7 @@
|
|||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<!-- This is based on the System V ABI -->
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f12_13"/>
|
||||
|
@ -47,6 +48,52 @@
|
|||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="16" space="stack"/>
|
||||
</pentry>
|
||||
<!-- Parameters within the ellipses only use integer registers -->
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<varargs first="0"/>
|
||||
<consume storage="general"/>
|
||||
</rule>
|
||||
<!-- special case: first two args are float,double, which produces a 'hole' in the
|
||||
second word of the argument space, which must be explicitly consumed -->
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="4"/>
|
||||
<position index="0"/>
|
||||
<datatype_at index="1">
|
||||
<datatype name="float" minsize="5" maxsize="8"/>
|
||||
</datatype_at>
|
||||
<consume storage="float"/>
|
||||
<consume_extra storage="general"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<!-- Only leading floating-point parameters can use float registers -->
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- float parameter -->
|
||||
<position index="0"/> <!-- as first input parameter -->
|
||||
<consume storage="float"/> <!-- use f12_f13 -->
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- float parameter -->
|
||||
<position index="1"/> <!-- as second input parameter -->
|
||||
<datatype_at index="0"> <!-- if the first input -->
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- is a float parameter -->
|
||||
</datatype_at>
|
||||
<consume storage="float"/> <!-- use f14_f15 -->
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<join align="true" reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<join align="true" reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/> <!-- otherwise any parameter -->
|
||||
<join align="true"/> <!-- should split across general purpose registers -->
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
|
@ -55,9 +102,25 @@
|
|||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="v0" piece2="v1"/>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v1"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<hidden_return/> <!-- structures always passed as hidden return parameter -->
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<hidden_return/> <!-- unions always passed as hidden return parameter -->
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
|
@ -72,12 +135,24 @@
|
|||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f20"/>
|
||||
<register name="f21"/>
|
||||
<register name="f22"/>
|
||||
<register name="f23"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="v0"/>
|
||||
<register name="v1"/>
|
||||
<register name="f0"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
<internal_storage>
|
||||
<register name="gp"/> <!-- Compilers may save gp to the stack before a call and restore it afterward -->
|
||||
</internal_storage>
|
||||
|
|
|
@ -47,6 +47,44 @@
|
|||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="16" space="stack"/>
|
||||
</pentry>
|
||||
<!-- Parameters within the ellipses only use integer registers -->
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<varargs first="0"/>
|
||||
<consume storage="general"/>
|
||||
</rule>
|
||||
<!-- special case: first two args are float,double, which produces a 'hole' in the
|
||||
second word of the argument space, which must be explicitly consumed -->
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="4"/>
|
||||
<position index="0"/>
|
||||
<datatype_at index="1">
|
||||
<datatype name="float" minsize="5" maxsize="8"/>
|
||||
</datatype_at>
|
||||
<consume storage="float"/>
|
||||
<consume_extra storage="general"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<!-- Only leading floating-point parameters can use float registers -->
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- float parameter -->
|
||||
<position index="0"/> <!-- as first input parameter -->
|
||||
<consume storage="float"/> <!-- use f12_f13 -->
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- float parameter -->
|
||||
<position index="1"/> <!-- as second input parameter -->
|
||||
<datatype_at index="0"> <!-- if the first input -->
|
||||
<datatype name="float" minsize="1" maxsize="8"/> <!-- is a float parameter -->
|
||||
</datatype_at>
|
||||
<consume storage="float"/> <!-- use f14_f15 -->
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/> <!-- otherwise any parameter -->
|
||||
<join align="true"/> <!-- should split across general purpose registers -->
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
|
@ -55,9 +93,25 @@
|
|||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="v1" piece2="v0"/>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v1"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<hidden_return/> <!-- structures always passed as hidden return parameter -->
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<hidden_return/> <!-- unions always passed as hidden return parameter -->
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
|
@ -72,12 +126,24 @@
|
|||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f20"/>
|
||||
<register name="f21"/>
|
||||
<register name="f22"/>
|
||||
<register name="f23"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="v0"/>
|
||||
<register name="v1"/>
|
||||
<register name="f0"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
<internal_storage>
|
||||
<register name="gp"/> <!-- Compilers may save gp to the stack before a call and restore it afterward -->
|
||||
</internal_storage>
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<pointer_size value="4"/>
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="8" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
|
||||
<stackpointer register="sp" space="ram"/>
|
||||
<funcptr align="2"/>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
<range space="register" first="0x2000" last="0x2fff"/>
|
||||
</global>
|
||||
<returnaddress>
|
||||
<register name="ra"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f12_13"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f14_15"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f16_17"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f18_19"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="t0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="t1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="t2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="t3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f0_1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="v1" piece2="v0"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
<register name="s1"/>
|
||||
<register name="s2"/>
|
||||
<register name="s3"/>
|
||||
<register name="s4"/>
|
||||
<register name="s5"/>
|
||||
<register name="s6"/>
|
||||
<register name="s7"/>
|
||||
<register name="s8"/>
|
||||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f20"/>
|
||||
<register name="f22"/>
|
||||
<register name="f24"/>
|
||||
<register name="f26"/>
|
||||
<register name="f28"/>
|
||||
<register name="f30"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="a0"/>
|
||||
<register name="a1"/>
|
||||
<register name="a2"/>
|
||||
<register name="a3"/>
|
||||
<register name="t0"/>
|
||||
<register name="t1"/>
|
||||
<register name="t2"/>
|
||||
<register name="t3"/>
|
||||
<register name="t4"/>
|
||||
<register name="t5"/>
|
||||
<register name="t6"/>
|
||||
<register name="t7"/>
|
||||
<register name="t8"/>
|
||||
<register name="t9"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfff0bdc0" last="0xffffffff"/>
|
||||
<range space="stack" first="0" last="15"/> <!-- This is backup storage space for register params, but we treat as locals -->
|
||||
</localrange>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
</compiler_spec>
|
|
@ -1,111 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<pointer_size value="8"/>
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<stackpointer register="sp" space="ram"/>
|
||||
<funcptr align="2"/>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
<range space="register" first="0x2000" last="0x2fff"/>
|
||||
</global>
|
||||
<aggressivetrim signext="true"/> <!-- Aggressively try to eliminate sign extensions -->
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input killedbycall="true">
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f14"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f15"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f16"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f17"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f18"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f19"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="9" maxsize="16">
|
||||
<addr space="join" piece1="v0" piece2="v1"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
<register name="s1"/>
|
||||
<register name="s2"/>
|
||||
<register name="s3"/>
|
||||
<register name="s4"/>
|
||||
<register name="s5"/>
|
||||
<register name="s6"/>
|
||||
<register name="s7"/>
|
||||
<register name="s8"/>
|
||||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
</compiler_spec>
|
189
Ghidra/Processors/MIPS/data/languages/mips64be.cspec
Normal file
189
Ghidra/Processors/MIPS/data/languages/mips64be.cspec
Normal file
|
@ -0,0 +1,189 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<pointer_size value="8"/>
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<stackpointer register="sp" space="ram"/>
|
||||
<funcptr align="2"/>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
<range space="register" first="0x2000" last="0x2fff"/>
|
||||
</global>
|
||||
<aggressivetrim signext="true"/> <!-- Aggressively try to eliminate sign extensions -->
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a0"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a1"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f14"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f15"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a3"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f16"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t0"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f17"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t1"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f18"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t2"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f19"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t3"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<varargs first="0"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<varargs first="0"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<join_dual_class stackspill="true" fillalternate="true" reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f0"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="v1"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate"/>
|
||||
<join_per_primitive storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<join reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
<register name="s1"/>
|
||||
<register name="s2"/>
|
||||
<register name="s3"/>
|
||||
<register name="s4"/>
|
||||
<register name="s5"/>
|
||||
<register name="s6"/>
|
||||
<register name="s7"/>
|
||||
<register name="s8"/>
|
||||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="v0"/>
|
||||
<register name="v1"/>
|
||||
<register name="f0"/>
|
||||
<register name="f2"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
</compiler_spec>
|
173
Ghidra/Processors/MIPS/data/languages/mips64le.cspec
Normal file
173
Ghidra/Processors/MIPS/data/languages/mips64le.cspec
Normal file
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<pointer_size value="8"/>
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<stackpointer register="sp" space="ram"/>
|
||||
<funcptr align="2"/>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
<range space="register" first="0x2000" last="0x2fff"/>
|
||||
</global>
|
||||
<aggressivetrim signext="true"/> <!-- Aggressively try to eliminate sign extensions -->
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a0"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a1"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f14"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f15"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="a3"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f16"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t0"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f17"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t1"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f18"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t2"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="1" maxsize="8" metatype="float">
|
||||
<register name="f19"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="t3"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<varargs first="0"/>
|
||||
<consume storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<varargs first="0"/>
|
||||
<join/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<join_dual_class stackspill="true" fillalternate="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f0"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="f2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="v0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="v1"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate"/>
|
||||
<join_per_primitive storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="s0"/>
|
||||
<register name="s1"/>
|
||||
<register name="s2"/>
|
||||
<register name="s3"/>
|
||||
<register name="s4"/>
|
||||
<register name="s5"/>
|
||||
<register name="s6"/>
|
||||
<register name="s7"/>
|
||||
<register name="s8"/>
|
||||
<register name="sp"/>
|
||||
<register name="gp"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="at"/>
|
||||
<register name="v0"/>
|
||||
<register name="v1"/>
|
||||
<register name="f0"/>
|
||||
<register name="f2"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
</compiler_spec>
|
|
@ -20,10 +20,10 @@ data/languages/old/oldPPC.lang||GHIDRA||||END|
|
|||
data/languages/old/oldPPC.trans||GHIDRA||||END|
|
||||
data/languages/ppc.dwarf||GHIDRA||||END|
|
||||
data/languages/ppc.ldefs||GHIDRA||||END|
|
||||
data/languages/ppc_32.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_32.pspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_4xx_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_4xx_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_be.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_be_Mac.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_e500_be.cspec||GHIDRA||||END|
|
||||
|
@ -34,14 +34,13 @@ data/languages/ppc_32_e500mc_be.cspec||GHIDRA||||END|
|
|||
data/languages/ppc_32_e500mc_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_e500mc_le.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_e500mc_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_le.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_mpc8270.pspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_quicciii_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_32_quicciii_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_64.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_64.pspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_32.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_be.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_be_Mac.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_isa_altivec_be.slaspec||GHIDRA||||END|
|
||||
|
@ -50,6 +49,7 @@ data/languages/ppc_64_isa_altivec_vle_be.slaspec||GHIDRA||||END|
|
|||
data/languages/ppc_64_isa_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_isa_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_isa_vle_be.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_le.cspec||GHIDRA||||END|
|
||||
data/languages/ppc_64_le.slaspec||GHIDRA||||END|
|
||||
data/languages/ppc_a2.sinc||GHIDRA||||END|
|
||||
data/languages/ppc_common.sinc||GHIDRA||||END|
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_be.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:BE:32:default">
|
||||
<description>PowerPC 32-bit big endian w/Altivec, G2</description>
|
||||
<compiler name="default" spec="ppc_32_be.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<compiler name="Mac OS X" spec="ppc_32_be_Mac.cspec" id="macosx"/>
|
||||
<external_name tool="gnu" name="powerpc:common"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
|
@ -23,14 +23,14 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_le.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:LE:32:default">
|
||||
<description>PowerPC 32-bit little endian w/Altivec, G2</description>
|
||||
<compiler name="default" spec="ppc_32_le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32_le.cspec" id="windows"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32.cspec" id="windows"/>
|
||||
<external_name tool="gnu" name="powerpc:common"/>
|
||||
<external_name tool="IDA-PRO" name="ppcl"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -39,13 +39,13 @@
|
|||
endian="big"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:BE:64:default">
|
||||
<description>PowerPC 64-bit big endian w/Altivec, G2</description>
|
||||
<compiler name="default" spec="ppc_64.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_64_be.cspec" id="default"/>
|
||||
<compiler name="Mac OS X" spec="ppc_64_be_Mac.cspec" id="macosx"/>
|
||||
<external_name tool="gnu" name="powerpc:common64"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
|
@ -57,7 +57,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -75,7 +75,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_le.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -92,13 +92,13 @@
|
|||
endian="little"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_le.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:LE:64:default">
|
||||
<description>PowerPC 64-bit little endian w/Altivec, G2</description>
|
||||
<compiler name="default" spec="ppc_64.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_64_le.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:common64"/>
|
||||
<external_name tool="IDA-PRO" name="ppcl"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -109,13 +109,13 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="4xx"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_4xx_be.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:BE:32:4xx">
|
||||
<description>PowerPC 4xx 32-bit big endian embedded core</description>
|
||||
<compiler name="default" spec="ppc_32_be.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:403"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -126,14 +126,14 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="4xx"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_4xx_le.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:LE:32:4xx">
|
||||
<description>PowerPC 4xx 32-bit little endian embedded core</description>
|
||||
<compiler name="default" spec="ppc_32_le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32_le.cspec" id="windows"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32.cspec" id="windows"/>
|
||||
<external_name tool="gnu" name="powerpc:403"/>
|
||||
<external_name tool="IDA-PRO" name="ppcl"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -142,13 +142,13 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="MPC8270"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_quicciii_be.sla"
|
||||
processorspec="ppc_32_mpc8270.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:BE:32:MPC8270">
|
||||
<description>Freescale MPC8280 32-bit big endian family (PowerQUICC-III)</description>
|
||||
<compiler name="default" spec="ppc_32_be.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:MPC8XX"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -159,13 +159,13 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerQUICC-III"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_quicciii_be.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:BE:32:QUICC">
|
||||
<description>PowerQUICC-III 32-bit big endian family</description>
|
||||
<compiler name="default" spec="ppc_32_be.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:MPC8XX"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -176,14 +176,14 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="PowerQUICC-III"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_quicciii_le.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
id="PowerPC:LE:32:QUICC">
|
||||
<description>PowerQUICC-III 32-bit little endian family</description>
|
||||
<compiler name="default" spec="ppc_32_le.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32_le.cspec" id="windows"/>
|
||||
<compiler name="default" spec="ppc_32.cspec" id="default"/>
|
||||
<compiler name="Visual Studio" spec="ppc_32.cspec" id="windows"/>
|
||||
<external_name tool="gnu" name="powerpc:MPC8XX"/>
|
||||
<external_name tool="IDA-PRO" name="ppcl"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -192,7 +192,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerQUICC-III-e500"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_e500_be.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -210,7 +210,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="PowerQUICC-III-e500"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_e500_le.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -226,7 +226,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerQUICC-III-e500mc"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_e500mc_be.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -243,7 +243,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="PowerQUICC-III-e500mc"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_32_e500mc_le.sla"
|
||||
processorspec="ppc_32.pspec"
|
||||
manualindexfile="../manuals/PowerPC.idx"
|
||||
|
@ -258,7 +258,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerISA-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
@ -276,7 +276,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="PowerISA-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_le.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
@ -293,7 +293,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerISA-Altivec-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_altivec_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
@ -311,7 +311,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="PowerISA-Altivec-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_altivec_le.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
@ -328,13 +328,13 @@
|
|||
endian="big"
|
||||
size="64"
|
||||
variant="PowerISA-Altivec"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_altivec_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
id="PowerPC:BE:64:A2ALT">
|
||||
<description>Power ISA 3.0 Big Endian w/Altivec</description>
|
||||
<compiler name="default" spec="ppc_64.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_64_be.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:e500mc"/>
|
||||
<external_name tool="IDA-PRO" name="ppc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -345,13 +345,13 @@
|
|||
endian="little"
|
||||
size="64"
|
||||
variant="PowerISA-Altivec"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_altivec_le.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
id="PowerPC:LE:64:A2ALT">
|
||||
<description>Power ISA 3.0 Little Endian w/Altivec</description>
|
||||
<compiler name="default" spec="ppc_64.cspec" id="default"/>
|
||||
<compiler name="default" spec="ppc_64_le.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="powerpc:e500mc"/>
|
||||
<external_name tool="IDA-PRO" name="ppcl"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="ppc.dwarf"/>
|
||||
|
@ -362,7 +362,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerISA-VLE-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_vle_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
@ -377,7 +377,7 @@
|
|||
endian="big"
|
||||
size="32"
|
||||
variant="PowerISA-VLE-Altivec-64-32addr"
|
||||
version="1.6"
|
||||
version="1.7"
|
||||
slafile="ppc_64_isa_altivec_vle_be.sla"
|
||||
processorspec="ppc_64.pspec"
|
||||
manualindexfile="../manuals/PowerISA.idx"
|
||||
|
|
|
@ -32,21 +32,6 @@
|
|||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f11"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
|
@ -74,6 +59,26 @@
|
|||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<goto_stack/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join align="true"/>
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
|
@ -82,9 +87,17 @@
|
|||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="r4" piece2="r3"/>
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="r4"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<consume storage="float"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="r1"/> <!-- stack pointer -->
|
||||
|
@ -108,10 +121,33 @@
|
|||
<register name="r29"/>
|
||||
<register name="r30"/>
|
||||
<register name="r31"/>
|
||||
<register name="f14"/>
|
||||
<register name="f15"/>
|
||||
<register name="f16"/>
|
||||
<register name="f17"/>
|
||||
<register name="f18"/>
|
||||
<register name="f19"/>
|
||||
<register name="f20"/>
|
||||
<register name="f21"/>
|
||||
<register name="f22"/>
|
||||
<register name="f23"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
<register name="cr2"/>
|
||||
<register name="cr3"/>
|
||||
<register name="cr4"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="r3"/>
|
||||
<register name="r4"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="r1" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f11"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="r3" piece2="r4"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="r1"/> <!-- stack pointer -->
|
||||
<register name="r2"/> <!-- _SDA2_BASE_ -->
|
||||
<register name="r13"/> <!-- _SDA_BASE_ -->
|
||||
<register name="r14"/>
|
||||
<register name="r15"/>
|
||||
<register name="r16"/>
|
||||
<register name="r17"/>
|
||||
<register name="r18"/>
|
||||
<register name="r19"/>
|
||||
<register name="r20"/>
|
||||
<register name="r21"/>
|
||||
<register name="r22"/>
|
||||
<register name="r23"/>
|
||||
<register name="r24"/>
|
||||
<register name="r25"/>
|
||||
<register name="r26"/>
|
||||
<register name="r27"/>
|
||||
<register name="r28"/>
|
||||
<register name="r29"/>
|
||||
<register name="r30"/>
|
||||
<register name="r31"/>
|
||||
<register name="cr2"/>
|
||||
<register name="cr3"/>
|
||||
<register name="cr4"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<callfixup name="get_pc_thunk_lr">
|
||||
<target name="__get_pc_thunk_lr"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
LR = inst_dest + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
</compiler_spec>
|
203
Ghidra/Processors/PowerPC/data/languages/ppc_64_be.cspec
Normal file
203
Ghidra/Processors/PowerPC/data/languages/ppc_64_be.cspec
Normal file
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- This cspec is based upon the PowerPC 64-bit ELF ABI specification -->
|
||||
<!-- Very similar to the PowerPC 64-bit little-endian cspec, but reverses justification when
|
||||
assigning odd datatype sizes -->
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<machine_alignment value="8" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="8" />
|
||||
<pointer_size value="8" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
<entry size="16" alignment="16" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="r1" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f11"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f12"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="112" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate" maxprimitives="1"/>
|
||||
<join storage="float"/>
|
||||
<extra_stack afterstorage="general" afterbytes="64"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<join storage="float"/> <!-- The join is NOT aligned -->
|
||||
<extra_stack afterstorage="general" afterbytes="64"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<!-- Values are packed big-endian within registers, but packing registers and stack dwords
|
||||
together is done in the little-endian fashion -->
|
||||
<rule>
|
||||
<datatype name="struct" minsize="8"/>
|
||||
<join align="true" reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union" minsize="8"/>
|
||||
<join align="true" reversejustify="true"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join align="true"/> <!-- The join IS aligned -->
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="r14"/>
|
||||
<register name="r15"/>
|
||||
<register name="r16"/>
|
||||
<register name="r17"/>
|
||||
<register name="r18"/>
|
||||
<register name="r19"/>
|
||||
<register name="r20"/>
|
||||
<register name="r21"/>
|
||||
<register name="r22"/>
|
||||
<register name="r23"/>
|
||||
<register name="r24"/>
|
||||
<register name="r25"/>
|
||||
<register name="r26"/>
|
||||
<register name="r27"/>
|
||||
<register name="r28"/>
|
||||
<register name="r29"/>
|
||||
<register name="r30"/>
|
||||
<register name="r31"/>
|
||||
<register name="r1"/>
|
||||
<!-- In cases where r2 does change, we assume it will get restored -->
|
||||
<register name="r2"/>
|
||||
<register name="r2Save"/>
|
||||
<register name="f14"/>
|
||||
<register name="f15"/>
|
||||
<register name="f16"/>
|
||||
<register name="f17"/>
|
||||
<register name="f18"/>
|
||||
<register name="f19"/>
|
||||
<register name="f20"/>
|
||||
<register name="f21"/>
|
||||
<register name="f22"/>
|
||||
<register name="f23"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
<register name="cr2"/>
|
||||
<register name="cr3"/>
|
||||
<register name="cr4"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="r3"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
<pcode inject="uponreturn">
|
||||
<body>
|
||||
# Inject pcode when returning from a function call to place the r2Save
|
||||
# value into 0x28(r1) which should be restored by the "ld r2,0x28(r1)"
|
||||
# which immediately follows calls which comply with the PPC64 ABI spec.
|
||||
local saveR2ptr = r1 + 0x28;
|
||||
*:8 saveR2ptr = r2Save;
|
||||
</body>
|
||||
</pcode>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
</compiler_spec>
|
|
@ -1,8 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- This cspec is based upon the PowerPC 64-bit ELF ABI specification -->
|
||||
<!-- Very similar to the PowerPC 64-bit big-endian cspec, but does not reverse justification when
|
||||
assigning odd datatype sizes -->
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<pointer_size value="8"/>
|
||||
<machine_alignment value="8" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="8" />
|
||||
<pointer_size value="8" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
<entry size="16" alignment="16" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
|
@ -50,33 +70,49 @@
|
|||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
<register name="f13"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="112" space="stack"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="homogeneous-float-aggregate" maxprimitives="1"/>
|
||||
<join storage="float"/>
|
||||
<extra_stack afterstorage="general" afterbytes="64"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="float"/>
|
||||
<join storage="float"/> <!-- The join is NOT aligned -->
|
||||
<extra_stack afterstorage="general" afterbytes="64"/>
|
||||
<consume_extra storage="general"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="any"/>
|
||||
<join align="true"/> <!-- The join IS aligned -->
|
||||
</rule>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8" metatype="float" extension="float">
|
||||
|
@ -85,6 +121,14 @@
|
|||
<pentry minsize="1" maxsize="8" extension="inttype">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<rule>
|
||||
<datatype name="struct"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
<rule>
|
||||
<datatype name="union"/>
|
||||
<convert_to_ptr/>
|
||||
</rule>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="r14"/>
|
||||
|
@ -109,7 +153,32 @@
|
|||
<!-- In cases where r2 does change, we assume it will get restored -->
|
||||
<register name="r2"/>
|
||||
<register name="r2Save"/>
|
||||
<register name="f14"/>
|
||||
<register name="f15"/>
|
||||
<register name="f16"/>
|
||||
<register name="f17"/>
|
||||
<register name="f18"/>
|
||||
<register name="f19"/>
|
||||
<register name="f20"/>
|
||||
<register name="f21"/>
|
||||
<register name="f22"/>
|
||||
<register name="f23"/>
|
||||
<register name="f24"/>
|
||||
<register name="f25"/>
|
||||
<register name="f26"/>
|
||||
<register name="f27"/>
|
||||
<register name="f28"/>
|
||||
<register name="f29"/>
|
||||
<register name="f30"/>
|
||||
<register name="f31"/>
|
||||
<register name="cr2"/>
|
||||
<register name="cr3"/>
|
||||
<register name="cr4"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="r3"/>
|
||||
<register name="f1"/>
|
||||
</killedbycall>
|
||||
<pcode inject="uponreturn">
|
||||
<body>
|
||||
# Inject pcode when returning from a function call to place the r2Save
|
Loading…
Add table
Add a link
Reference in a new issue