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
|
import py
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER
from rpython.rlib import rgc
from rpython.jit.backend.x86.assembler import Assembler386
from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls
from rpython.jit.backend.x86.profagent import ProfileAgent
from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
from rpython.jit.backend.x86 import regloc
from rpython.jit.backend.x86.vector_ext import X86VectorExt
import sys
class AbstractX86CPU(AbstractLLCPU):
debug = True
supports_floats = True
supports_singlefloats = True
dont_keepalive_stuff = False # for tests
with_threads = False
frame_reg = regloc.ebp
vector_ext = None
# can an ISA instruction handle a factor to the offset?
load_supported_factors = (1,2,4,8)
HAS_CODEMAP = True
from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE
all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes
gen_regs = gpr_reg_mgr_cls.all_regs
float_regs = xmm_reg_mgr_cls.all_regs
def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
gcdescr=None):
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
profile_agent = ProfileAgent()
if rtyper is not None:
config = rtyper.annotator.translator.config
if config.translation.jit_profiler == "oprofile":
from rpython.jit.backend.x86 import oprofile
if not oprofile.OPROFILE_AVAILABLE:
raise Exception('oprofile support was explicitly enabled, but oprofile headers seem not to be available')
profile_agent = oprofile.OProfileAgent()
self.with_threads = config.translation.thread
self.profile_agent = profile_agent
def set_debug(self, flag):
return self.assembler.set_debug(flag)
def setup(self):
self.assembler = Assembler386(self, self.translate_support_code)
def build_regalloc(self):
''' for tests'''
from rpython.jit.backend.x86.regalloc import RegAlloc
assert self.assembler is not None
return RegAlloc(self.assembler, False)
@rgc.no_release_gil
def setup_once(self):
self.profile_agent.startup()
if self.HAS_CODEMAP:
self.codemap.setup()
self.assembler.setup_once()
@rgc.no_release_gil
def finish_once(self):
self.assembler.finish_once()
self.profile_agent.shutdown()
def dump_loop_token(self, looptoken):
"""
NOT_RPYTHON
"""
from rpython.jit.backend.x86.tool.viewcode import machine_code_dump
data = []
label_list = [(offset, name) for name, offset in
looptoken._x86_ops_offset.iteritems()]
label_list.sort()
addr = looptoken._x86_rawstart
src = rffi.cast(rffi.CCHARP, addr)
for p in range(looptoken._x86_fullsize):
data.append(src[p])
data = ''.join(data)
lines = machine_code_dump(data, addr, self.backend_name, label_list)
print ''.join(lines)
def compile_bridge(self, faildescr, inputargs, operations,
original_loop_token, log=True, logger=None):
clt = original_loop_token.compiled_loop_token
clt.compiling_a_bridge()
return self.assembler.assemble_bridge(faildescr, inputargs, operations,
original_loop_token, log, logger)
def cast_ptr_to_int(x):
adr = llmemory.cast_ptr_to_adr(x)
return CPU386.cast_adr_to_int(adr)
cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)'
cast_ptr_to_int = staticmethod(cast_ptr_to_int)
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)
def invalidate_loop(self, looptoken):
from rpython.jit.backend.x86 import codebuf
for addr, tgt in looptoken.compiled_loop_token.invalidate_positions:
mc = codebuf.MachineCodeBlockWrapper()
mc.JMP_l(tgt)
assert mc.get_relative_pos() == 5 # [JMP] [tgt 4 bytes]
mc.copy_to_raw_memory(addr - 1)
# positions invalidated
looptoken.compiled_loop_token.invalidate_positions = []
def get_all_loop_runs(self):
asm = self.assembler
l = lltype.malloc(LOOP_RUN_CONTAINER,
len(asm.loop_run_counters))
for i, ll_s in enumerate(asm.loop_run_counters):
l[i].type = ll_s.type
l[i].number = ll_s.number
l[i].counter = ll_s.i
return l
class CPU386(AbstractX86CPU):
backend_name = 'x86'
NUM_REGS = 8
CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.esi, regloc.edi]
supports_longlong = True
IS_64_BIT = False
def __init__(self, *args, **kwargs):
assert sys.maxint == (2**31 - 1)
super(CPU386, self).__init__(*args, **kwargs)
class CPU386_NO_SSE2(CPU386):
supports_floats = False
supports_longlong = False
class CPU_X86_64(AbstractX86CPU):
vector_ext = X86VectorExt()
backend_name = 'x86_64'
NUM_REGS = 16
CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15]
IS_64_BIT = True
CPU = CPU386
|