1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
from rpython.jit.metainterp.history import AbstractValue, ConstInt, FLOAT, Const
from rpython.jit.backend.zarch.locations import imm, addr
from rpython.jit.backend.llsupport.regalloc import TempVar
import rpython.jit.backend.zarch.registers as r
def check_imm_value(value, lower_bound=-2**15, upper_bound=2**15-1):
return lower_bound <= value <= upper_bound
def check_imm(arg, lower_bound=-2**15, upper_bound=2**15-1):
if isinstance(arg, ConstInt):
i = arg.getint()
return lower_bound <= i <= upper_bound
return False
def check_imm32(arg):
return check_imm(arg, -2**31, 2**31-1)
def check_imm20(arg):
return check_imm(arg, -2**19, 2**19-1)
def prepare_int_add(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if a0.is_constant():
a0, a1 = a1, a0
if check_imm32(a1):
l1 = imm(a1.getint())
else:
l1 = self.ensure_reg_or_pool(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
def prepare_int_mul(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if a0.is_constant():
a0, a1 = a1, a0
if check_imm32(a1):
l1 = imm(a1.getint())
else:
l1 = self.ensure_reg_or_pool(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
def prepare_int_mul_ovf(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if a0.is_constant():
a0, a1 = a1, a0
if check_imm32(a1):
l1 = imm(a1.getint())
else:
l1 = self.ensure_reg_or_pool(a1)
lr,lq = self.rm.ensure_even_odd_pair(a0, op, bind_first=False)
return [lr, lq, l1]
def generate_div_mod(modulus):
def f(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
l1 = self.ensure_reg(a1)
if isinstance(a0, Const):
loc = self.ensure_reg_or_pool(a0)
lr,lq = self.rm.ensure_even_odd_pair(a0, op,
bind_first=modulus, must_exist=False,
move_regs=False)
self.assembler.regalloc_mov(loc, lq)
else:
lr,lq = self.rm.ensure_even_odd_pair(a0, op, bind_first=modulus)
return [lr, lq, l1]
return f
prepare_int_div = generate_div_mod(False)
prepare_int_mod = generate_div_mod(True)
def prepare_int_sub(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
# sub is not commotative, thus cannot swap operands
l0 = self.ensure_reg(a0)
l1 = self.ensure_reg(a1)
res = self.force_allocate_reg(op)
return [res, l0, l1]
def prepare_int_logic(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if a0.is_constant():
a0, a1 = a1, a0
l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
def prepare_int_shift(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if isinstance(a1, ConstInt):
# note that the shift value is stored
# in the addr part of the instruction
l1 = addr(a1.getint())
else:
tmp = self.rm.ensure_reg(a1)
l1 = addr(0, tmp)
l0 = self.ensure_reg(a0)
lr = self.force_allocate_reg(op)
return [lr, l0, l1]
def generate_cmp_op(signed=True):
def prepare_cmp_op(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
invert = imm(0)
l0 = self.ensure_reg(a0)
if signed and check_imm32(a1):
l1 = imm(a1.getint())
else:
l1 = self.ensure_reg(a1)
res = self.force_allocate_reg_or_cc(op)
return [l0, l1, res, invert]
return prepare_cmp_op
def prepare_float_cmp_op(self, op):
l0 = self.ensure_reg(op.getarg(0))
l1 = self.ensure_reg(op.getarg(1))
res = self.force_allocate_reg_or_cc(op)
return [l0, l1, res]
def prepare_binary_op(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
l0 = self.ensure_reg(a0)
l1 = self.ensure_reg(a1)
self.force_result_in_reg(op, a0)
return [l0, l1]
def generate_prepare_float_binary_op(allow_swap=False):
def prepare_float_binary_op(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if allow_swap:
if isinstance(a0, Const):
a0,a1 = a1,a0
l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
return prepare_float_binary_op
def prepare_unary_cmp(self, op):
l0 = self.ensure_reg(op.getarg(0))
res = self.force_allocate_reg_or_cc(op)
return [l0, res]
def prepare_unary_op(self, op):
res = self.force_result_in_reg(op, op.getarg(0))
return [res,]
def prepare_same_as(self, op):
a0 = op.getarg(0)
l0 = self.ensure_reg(a0)
res = self.force_allocate_reg(op)
return [l0, res]
|