///|
// Target abstraction - corresponds to struct Target and amd64/all.h
///|
// AMD64 register numbers (as virtual tmp ids, matching C enum Amd64Reg)
pub const RXX : Int = 0
///|
pub const RAX : Int = 1
///|
pub const RCX : Int = 2
///|
pub const RDX : Int = 3
///|
pub const RSI : Int = 4
///|
pub const RDI : Int = 5
///|
pub const R8 : Int = 6
///|
pub const R9 : Int = 7
///|
pub const R10 : Int = 8
///|
pub const R11 : Int = 9
///|
pub const RBX : Int = 10
///|
pub const R12 : Int = 11
///|
pub const R13 : Int = 12
///|
pub const R14 : Int = 13
///|
pub const R15 : Int = 14
///|
pub const RBP : Int = 15
///|
pub const RSP : Int = 16
///|
pub const XMM0 : Int = 17
///|
pub const XMM1 : Int = 18
///|
pub const XMM2 : Int = 19
///|
pub const XMM3 : Int = 20
///|
pub const XMM4 : Int = 21
///|
pub const XMM5 : Int = 22
///|
pub const XMM6 : Int = 23
///|
pub const XMM7 : Int = 24
///|
pub const XMM8 : Int = 25
///|
pub const XMM9 : Int = 26
///|
pub const XMM10 : Int = 27
///|
pub const XMM11 : Int = 28
///|
pub const XMM12 : Int = 29
///|
pub const XMM13 : Int = 30
///|
pub const XMM14 : Int = 31
///|
pub const XMM15 : Int = 32
///|
// Tmp0 - first non-register temporary (NBit = 64)
pub const Tmp0 : Int = 64
///|
// Number of general purpose registers
pub const NGPR : Int = RSP - RAX + 1
///|
// Number of float registers
pub const NFPR : Int = XMM14 - XMM0 + 1
///|
// Number of caller-save GPRs (RAX..R11)
pub const NGPS : Int = R11 - RAX + 1
///|
// Number of caller-save FPRs
pub const NFPS : Int = NFPR
///|
// Number of callee-save registers (RBX..R15)
pub const NCLR : Int = R15 - RBX + 1
///|
// Caller-save registers for amd64 sysv (C amd64_sysv_rsave in sysv.c).
// These are the argument/return registers used by retregs/argregs and by
// the spill/rega passes (T.rsave).
pub let rsave : Array[Int] = [
RDI,
RSI,
RDX,
RCX,
R8,
R9,
R10,
R11,
RAX,
XMM0,
XMM1,
XMM2,
XMM3,
XMM4,
XMM5,
XMM6,
XMM7,
XMM8,
XMM9,
XMM10,
XMM11,
XMM12,
XMM13,
XMM14,
]
///|
// Callee-save registers (C amd64_sysv_rclob in sysv.c).
pub let rclob : Array[Int] = [RBX, R12, R13, R14, R15]
///|
// The registers returned by a call, given its RCall ref (C retregs).
// Returns (bits, ngp, nfpr).
#as_free_fn(retregs, deprecated="use `Ref::retregs` instead")
pub fn Ref::retregs(self : Ref) -> (UInt64, Int, Int) {
let mut b : UInt64 = 0
let v = self.call_val()
let ni = v & 3
let nf = (v >> 2) & 3
if ni >= 1 {
b = b | (1UL << RAX)
}
if ni >= 2 {
b = b | (1UL << RDX)
}
if nf >= 1 {
b = b | (1UL << XMM0)
}
if nf >= 2 {
b = b | (1UL << XMM1)
}
(b, ni, nf)
}
///|
// The registers used to pass arguments, given an RCall ref (C argregs).
// Returns (bits, ngp, nfpr).
#as_free_fn(argregs, deprecated="use `Ref::argregs` instead")
pub fn Ref::argregs(self : Ref) -> (UInt64, Int, Int) {
let mut b : UInt64 = 0
let v = self.call_val()
let ni = (v >> 4) & 15
let nf = (v >> 8) & 15
let ra = (v >> 12) & 1
for j in 0.. UInt64 {
let one : UInt64 = 1
(one << RBP) | (one << RSP)
}
///|
// Number of globally live registers
pub const NRGLOB : Int = 2