144 lines
4.1 KiB
JavaScript
144 lines
4.1 KiB
JavaScript
/*
|
|
* Copyright (C) 2016 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
"use strict";
|
|
|
|
class Inst {
|
|
constructor(opcode, args = [])
|
|
{
|
|
this._opcode = opcode;
|
|
this._args = args;
|
|
}
|
|
|
|
append(...args)
|
|
{
|
|
this._args.push(...args);
|
|
}
|
|
|
|
clear()
|
|
{
|
|
this._opcode = Nop;
|
|
this._args = [];
|
|
}
|
|
|
|
get opcode() { return this._opcode; }
|
|
get args() { return this._args; }
|
|
|
|
visitArg(index, func, ...args)
|
|
{
|
|
let replacement = func(this._args[index], ...args);
|
|
if (replacement)
|
|
this._args[index] = replacement;
|
|
}
|
|
|
|
forEachTmpFast(func)
|
|
{
|
|
for (let i = 0; i < this._args.length; ++i) {
|
|
let replacement;
|
|
if (replacement = this._args[i].forEachTmpFast(func))
|
|
this._args[i] = replacement;
|
|
}
|
|
}
|
|
|
|
forEachArg(func)
|
|
{
|
|
Inst_forEachArg(this, func);
|
|
}
|
|
|
|
forEachTmp(func)
|
|
{
|
|
this.forEachArg((arg, role, type, width) => {
|
|
return arg.forEachTmp(role, type, width, func);
|
|
});
|
|
}
|
|
|
|
forEach(thing, func)
|
|
{
|
|
this.forEachArg((arg, role, type, width) => {
|
|
return arg.forEach(thing, role, type, width, func);
|
|
});
|
|
}
|
|
|
|
static forEachDef(thing, prevInst, nextInst, func)
|
|
{
|
|
if (prevInst) {
|
|
prevInst.forEach(
|
|
thing,
|
|
(value, role, type, width) => {
|
|
if (Arg.isLateDef(role))
|
|
return func(value, role, type, width);
|
|
});
|
|
}
|
|
|
|
if (nextInst) {
|
|
nextInst.forEach(
|
|
thing,
|
|
(value, role, type, width) => {
|
|
if (Arg.isEarlyDef(role))
|
|
return func(value, role, type, width);
|
|
});
|
|
}
|
|
}
|
|
|
|
static forEachDefWithExtraClobberedRegs(thing, prevInst, nextInst, func)
|
|
{
|
|
forEachDef(thing, prevInst, nextInst, func);
|
|
|
|
let regDefRole;
|
|
|
|
let reportReg = reg => {
|
|
let type = reg.isGPR ? GP : FP;
|
|
func(thing.fromReg(reg), regDefRole, type, Arg.conservativeWidth(type));
|
|
};
|
|
|
|
if (prevInst && prevInst.opcode == Patch) {
|
|
regDefRole = Arg.Def;
|
|
prevInst.extraClobberedRegs.forEach(reportReg);
|
|
}
|
|
|
|
if (nextInst && nextInst.opcode == Patch) {
|
|
regDefRole = Arg.EarlyDef;
|
|
nextInst.extraEarlyClobberedRegs.forEach(reportReg);
|
|
}
|
|
}
|
|
|
|
get hasNonArgEffects() { return Inst_hasNonArgEffects(this); }
|
|
|
|
hash()
|
|
{
|
|
let result = opcodeCode(this.opcode);
|
|
for (let arg of this.args) {
|
|
result += arg.hash();
|
|
result |= 0;
|
|
}
|
|
return result >>> 0;
|
|
}
|
|
|
|
toString()
|
|
{
|
|
return "" + symbolName(this._opcode) + " " + this._args.join(", ");
|
|
}
|
|
}
|
|
|