141 lines
4.0 KiB
JavaScript
141 lines
4.0 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 Reg extends TmpBase {
|
|
constructor(index, type, name, isCalleeSave)
|
|
{
|
|
super();
|
|
this._index = index;
|
|
this._type = type;
|
|
this._name = name;
|
|
this._isCalleeSave = !!isCalleeSave;
|
|
}
|
|
|
|
static fromReg(reg)
|
|
{
|
|
return reg;
|
|
}
|
|
|
|
get index() { return this._index; }
|
|
get type() { return this._type; }
|
|
get name() { return this._name; }
|
|
get isCalleeSave() { return this._isCalleeSave; }
|
|
|
|
get isReg() { return true; }
|
|
|
|
hash()
|
|
{
|
|
if (this.isGP)
|
|
return 1 + this._index;
|
|
return -1 - this._index;
|
|
}
|
|
|
|
toString()
|
|
{
|
|
return `%${this._name}`;
|
|
}
|
|
|
|
static extract(arg)
|
|
{
|
|
if (arg.isReg)
|
|
return arg.reg;
|
|
return null;
|
|
}
|
|
|
|
static forEachFast(arg, func)
|
|
{
|
|
return arg.forEachTmpFast(tmp => {
|
|
if (!tmp.isReg)
|
|
return;
|
|
return func(tmp);
|
|
});
|
|
}
|
|
|
|
static forEach(arg, argRole, argType, argWidth, func)
|
|
{
|
|
return arg.forEachTmp(
|
|
argRole, argType, argWidth,
|
|
(tmp, role, type, width) => {
|
|
if (!tmp.isReg)
|
|
return;
|
|
return func(tmp, role, type, width);
|
|
});
|
|
}
|
|
}
|
|
|
|
{
|
|
Reg.regs = [];
|
|
function newReg(...args)
|
|
{
|
|
let result = new Reg(...args);
|
|
Reg.regs.push(result);
|
|
return result;
|
|
}
|
|
|
|
// Define X86_64 GPRs
|
|
{
|
|
let index = 0;
|
|
function newGPR(name, isCalleeSave) { return newReg(index++, GP, name, isCalleeSave); }
|
|
|
|
Reg.rax = newGPR("rax");
|
|
Reg.rcx = newGPR("rcx");
|
|
Reg.rdx = newGPR("rdx");
|
|
Reg.rbx = newGPR("rbx", true);
|
|
Reg.rsp = newGPR("rsp");
|
|
Reg.rbp = newGPR("rbp", true);
|
|
Reg.rsi = newGPR("rsi");
|
|
Reg.rdi = newGPR("rdi");
|
|
for (let i = 8; i <= 15; ++i)
|
|
Reg[`r${i}`] = newGPR(`r${i}`, i >= 12);
|
|
}
|
|
|
|
// Define X86_64 FPRs.
|
|
for (let i = 0; i <= 15; ++i)
|
|
Reg[`xmm${i}`] = newReg(i, FP, `xmm${i}`);
|
|
|
|
Reg.gprs = []
|
|
Reg.fprs = []
|
|
Reg.calleeSaveGPRs = []
|
|
Reg.calleeSaveFPRs = []
|
|
Reg.calleeSaves = []
|
|
for (let reg of Reg.regs) {
|
|
if (reg.isGP) {
|
|
Reg.gprs.push(reg);
|
|
if (reg.isCalleeSave)
|
|
Reg.calleeSaveGPRs.push(reg);
|
|
} else {
|
|
Reg.fprs.push(reg);
|
|
if (reg.isCalleeSave)
|
|
Reg.calleeSaveFPRS.push(reg);
|
|
}
|
|
if (reg.isCalleeSave)
|
|
Reg.calleeSaves.push(reg);
|
|
}
|
|
|
|
Reg.callFrameRegister = Reg.rbp;
|
|
Reg.stackPointerRegister = Reg.rsp;
|
|
}
|