class Arg {
constructor()
{ this._kind = Arg.Invalid;
}
static isAnyUse(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseDef: case Arg.UseZDef: case Arg.LateUse: case Arg.LateColdUse: case Arg.Scratch:
return true; case Arg.Def: case Arg.ZDef: case Arg.UseAddr: case Arg.EarlyDef:
return false; default: thrownew Error("Bad role");
}
}
static isColdUse(role)
{ switch (role) { case Arg.ColdUse: case Arg.LateColdUse:
return true; case Arg.Use: case Arg.UseDef: case Arg.UseZDef: case Arg.LateUse: case Arg.Def: case Arg.ZDef: case Arg.UseAddr: case Arg.Scratch: case Arg.EarlyDef:
return false; default: thrownew Error("Bad role");
}
}
static cooled(role)
{ switch (role) { case Arg.ColdUse: case Arg.LateColdUse: case Arg.UseDef: case Arg.UseZDef: case Arg.Def: case Arg.ZDef: case Arg.UseAddr: case Arg.Scratch: case Arg.EarlyDef:
return role; case Arg.Use:
return Arg.ColdUse; case Arg.LateUse:
return Arg.LateColdUse; default: thrownew Error("Bad role");
}
}
static isEarlyUse(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseDef: case Arg.UseZDef:
return true; case Arg.Def: case Arg.ZDef: case Arg.UseAddr: case Arg.LateUse: case Arg.LateColdUse: case Arg.Scratch: case Arg.EarlyDef:
return false; default: thrownew Error("Bad role");
}
}
static isLateUse(role)
{ switch (role) { case Arg.LateUse: case Arg.LateColdUse: case Arg.Scratch:
return true; case Arg.ColdUse: case Arg.Use: case Arg.UseDef: case Arg.UseZDef: case Arg.Def: case Arg.ZDef: case Arg.UseAddr: case Arg.EarlyDef:
return false; default: thrownew Error("Bad role");
}
}
static isAnyDef(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseAddr: case Arg.LateUse: case Arg.LateColdUse:
return false; case Arg.Def: case Arg.UseDef: case Arg.ZDef: case Arg.UseZDef: case Arg.EarlyDef: case Arg.Scratch:
return true; default: thrownew Error("Bad role");
}
}
static isEarlyDef(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseAddr: case Arg.LateUse: case Arg.Def: case Arg.UseDef: case Arg.ZDef: case Arg.UseZDef: case Arg.LateColdUse:
return false; case Arg.EarlyDef: case Arg.Scratch:
return true; default: thrownew Error("Bad role");
}
}
static isLateDef(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseAddr: case Arg.LateUse: case Arg.EarlyDef: case Arg.Scratch: case Arg.LateColdUse:
return false; case Arg.Def: case Arg.UseDef: case Arg.ZDef: case Arg.UseZDef:
return true; default: thrownew Error("Bad role");
}
}
static isZDef(role)
{ switch (role) { case Arg.Use: case Arg.ColdUse: case Arg.UseAddr: case Arg.LateUse: case Arg.Def: case Arg.UseDef: case Arg.EarlyDef: case Arg.Scratch: case Arg.LateColdUse:
return false; case Arg.ZDef: case Arg.UseZDef:
return true; default: thrownew Error("Bad role");
}
}
static createRelCond(condition)
{
let result = new Arg();
result._kind = Arg.RelCond;
result._condition = condition;
return result;
}
static createResCond(condition)
{
let result = new Arg();
result._kind = Arg.ResCond;
result._condition = condition;
return result;
}
static createDoubleCond(condition)
{
let result = new Arg();
result._kind = Arg.DoubleCond;
result._condition = condition;
return result;
}
static createWidth(width)
{
let result = new Arg();
result._kind = Arg.Width;
result._width = width;
return result;
}
static createSpecial()
{
let result = new Arg();
result._kind = Arg.Special;
return result;
}
get kind() { return this._kind; }
get isTmp() { return this._kind == Arg.Tmp; }
get isImm() { return this._kind == Arg.Imm; }
get isBigImm() { return this._kind == Arg.BigImm; }
get isBitImm() { return this._kind == Arg.BitImm; }
get isBitImm64() { return this._kind == Arg.BitImm64; }
get isSomeImm()
{ switch (this._kind) { case Arg.Imm: case Arg.BitImm:
return true; default:
return false;
}
}
get isSomeBigImm()
{ switch (this._kind) { case Arg.BigImm: case Arg.BitImm64:
return true; default:
return false;
}
}
get isAddr() { return this._kind == Arg.Addr; }
get isStack() { return this._kind == Arg.Stack; }
get isCallArg() { return this._kind == Arg.CallArg; }
get isIndex() { return this._kind == Arg.Index; }
get isMemory()
{ switch (this._kind) { case Arg.Addr: case Arg.Stack: case Arg.CallArg: case Arg.Index:
return true; default:
return false;
}
}
get isStackMemory()
{ switch (this._kind) { case Arg.Addr:
return this._base == Reg.callFrameRegister
|| this._base == Reg.stackPointerRegister; case Arg.Stack: case Arg.CallArg:
return true; default:
return false;
}
}
get isRelCond() { return this._kind == Arg.RelCond; }
get isResCond() { return this._kind == Arg.ResCond; }
get isDoubleCond() { return this._kind == Arg.DoubleCond; }
get isCondition()
{ switch (this._kind) { case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond:
return true; default:
return false;
}
}
get isWidth() { return this._kind == Arg.Width; }
get isSpecial() { return this._kind == Arg.Special; }
get isAlive() { return this.isTmp || this.isStack; }
get tmp()
{ if (this._kind != Arg.Tmp) thrownew Error("Called .tmp for non-tmp");
return this._tmp;
}
get value()
{ if (!this.isSomeImm) thrownew Error("Called .value for non-imm");
return this._value;
}
get lowValue()
{ if (!this.isSomeBigImm) thrownew Error("Called .lowValue for non-big-imm");
return this._lowValue;
}
get highValue()
{ if (!this.isSomeBigImm) thrownew Error("Called .highValue for non-big-imm");
return this._highValue;
}
get base()
{ switch (this._kind) { case Arg.Addr: case Arg.Index:
return this._base; default: thrownew Error("Called .base for non-address");
}
}
get hasOffset() { return this.isMemory; }
get offset()
{ switch (this._kind) { case Arg.Addr: case Arg.Index: case Arg.Stack: case Arg.CallArg:
return this._offset; default: thrownew Error("Called .offset for non-address");
}
}
get stackSlot()
{ if (this._kind != Arg.Stack) thrownew Error("Called .stackSlot for non-address");
return this._slot;
}
get index()
{ if (this._kind != Arg.Index) thrownew Error("Called .index for non-Index");
return this._index;
}
get scale()
{ if (this._kind != Arg.Index) thrownew Error("Called .scale for non-Index");
return this._scale;
}
get logScale()
{
return Arg.logScale(this.scale);
}
get width()
{ if (this._kind != Arg.Width) thrownew Error("Called .width for non-Width");
return this._width;
}
get isGPTmp() { return this.isTmp && this.tmp.isGP; }
get isFPTmp() { return this.isTmp && this.tmp.isFP; }
get isGP()
{ switch (this._kind) { case Arg.Imm: case Arg.BigImm: case Arg.BitImm: case Arg.BitImm64: case Arg.Addr: case Arg.Index: case Arg.Stack: case Arg.CallArg: case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond: case Arg.Width: case Arg.Special:
return true; case Arg.Tmp:
return this.isGPTmp; case Arg.Invalid:
return false; default: thrownew Error("Bad kind");
}
}
get isFP()
{ switch (this._kind) { case Arg.Imm: case Arg.BitImm: case Arg.BitImm64: case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond: case Arg.Width: case Arg.Special: case Arg.Invalid:
return false; case Arg.Addr: case Arg.Index: case Arg.Stack: case Arg.CallArg: case Arg.BigImm:
return true; case Arg.Tmp:
return this.isFPTmp; default: thrownew Error("Bad kind");
}
}
get hasType()
{ switch (this._kind) { case Arg.Imm: case Arg.BitImm: case Arg.BitImm64: case Arg.Tmp:
return true; default:
return false;
}
}
get type()
{
return this.isGP ? GP : FP;
}
isType(type)
{ switch (type) { case Arg.GP:
return this.isGP; case Arg.FP:
return this.isFP; default: thrownew Error("Bad type");
}
}
isCompatibleType(other)
{ if (this.hasType)
return other.isType(this.type); if (other.hasType)
return this.isType(other.type);
return true;
}
get isGPR() { return this.isTmp && this.tmp.isGPR; }
get gpr() { return this.tmp.gpr; }
get isFPR() { return this.isTmp && this.tmp.isFPR; }
get fpr() { return this.tmp.fpr; }
get isReg() { return this.isTmp && this.tmp.isReg; }
get reg() { return this.tmp.reg; }
isValidForm(width)
{ switch (this._kind) { case Arg.Invalid:
return false; case Arg.Tmp:
return true; case Arg.Imm:
return Arg.isValidImmForm(this.value); case Arg.BigImm:
return true; case Arg.BitImm:
return Arg.isValidBitImmForm(this.value); case Arg.BitImm64:
return Arg.isValidBitImm64Form(this.value); case Arg.Addr: case Arg.Stack: case Arg.CallArg:
return Arg.isValidAddrForm(this.offset, width); case Arg.Index:
return Arg.isValidIndexForm(this.scale, this.offset, width); case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond: case Arg.Width: case Arg.Special:
return true; default: thrownew Error("Bad kind");
}
}
forEachTmpFast(func)
{ switch (this._kind) { case Arg.Tmp: {
let replacement; if (replacement = func(this._tmp))
return Arg.createTmp(replacement); break;
} case Arg.Addr: {
let replacement; if (replacement = func(this._base))
return Arg.createAddr(replacement, this._offset); break;
} case Arg.Index: {
let baseReplacement = func(this._base);
let indexReplacement = func(this._index); if (baseReplacement || indexReplacement) {
return Arg.createIndex(
baseReplacement ? baseReplacement : this._base,
indexReplacement ? indexReplacement : this._index, this._scale, this._offset);
} break;
} default: break;
}
}
get condition()
{ switch (this._kind) { case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond:
return this._condition; default: thrownew Error("Called .condition for non-condition");
}
}
get isInvertible()
{ switch (this._kind) { case Arg.RelCond: case Arg.DoubleCold:
return true; case Arg.ResCond: switch (this._condition) { case Zero: case NonZero: case Signed: case PositiveOrZero:
return true; default:
return false;
} default:
return false;
}
}
static kindCode(kind)
{ switch (kind) { case Arg.Invalid:
return 0; case Arg.Tmp:
return 1; case Arg.Imm:
return 2; case Arg.BigImm:
return 3; case Arg.BitImm:
return 4; case Arg.BitImm64:
return 5; case Arg.Addr:
return 6; case Arg.Stack:
return 7; case Arg.CallArg:
return 8; case Arg.Index:
return 9; case Arg.RelCond:
return 10; case Arg.ResCond:
return 11; case Arg.DoubleCond:
return 12; case Arg.Special:
return 13; case Arg.WidthArg:
return 14; default: thrownew Error("Bad kind");
}
}
hash()
{
let result = Arg.kindCode(this._kind);
switch (this._kind) { case Arg.Invalid: case Arg.Special: break; case Arg.Tmp:
result += this._tmp.hash();
result |= 0; break; case Arg.Imm: case Arg.BitImm:
result += this._value;
result |= 0; break; case Arg.BigImm: case Arg.BitImm64:
result += this._lowValue;
result |= 0;
result += this._highValue;
result |= 0; break; case Arg.CallArg:
result += this._offset;
result |= 0; break; case Arg.RelCond:
result += relCondCode(this._condition);
result |= 0; break; case Arg.ResCond:
result += resCondCode(this._condition);
result |= 0; break; case Arg.DoubleCond:
result += doubleCondCode(this._condition);
result |= 0; break; case Arg.WidthArg:
result += this._width;
result |= 0; break; case Arg.Addr:
result += this._offset;
result |= 0;
result += this._base.hash();
result |= 0; break; case Arg.Index:
result += this._offset;
result |= 0;
result += this._scale;
result |= 0;
result += this._base.hash();
result |= 0;
result += this._index.hash();
result |= 0; break; case Arg.Stack:
result += this._offset;
result |= 0;
result += this.stackSlot.index;
result |= 0; break;
}
return result >>> 0;
}
toString()
{ switch (this._kind) { case Arg.Invalid:
return "<invalid>"; case Arg.Tmp:
return this._tmp.toString(); case Arg.Imm:
return "$" + this._value; case Arg.BigImm: case Arg.BitImm64:
return "$0x" + this._highValue.toString(16) + ":" + this._lowValue.toString(16); case Arg.Addr:
return "" + (this._offset ? this._offset : "") + "(" + this._base + ")"; case Arg.Index:
return "" + (this._offset ? this._offset : "") + "(" + this._base + "," + this._index + (this._scale == 1 ? "" : "," + this._scale) + ")"; case Arg.Stack:
return "" + (this._offset ? this._offset : "") + "(" + this._slot + ")"; case Arg.CallArg:
return "" + (this._offset ? this._offset : "") + "(callArg)"; case Arg.RelCond: case Arg.ResCond: case Arg.DoubleCond:
return symbolName(this._condition); case Arg.Special:
return "special"; case Arg.Width:
return "" + this._value; default: thrownew Error("Bad kind");
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.