Author: Maciej Fijalkowski <[email protected]> Branch: arm64 Changeset: r96535:682a0e1492d9 Date: 2019-04-22 11:32 +0000 http://bitbucket.org/pypy/pypy/changeset/682a0e1492d9/
Log: enough to start passing basic field tests diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -10,7 +10,6 @@ PC_OFFSET = 0 # XXX class AbstractAarch64Builder(object): - # just copied some values from https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a def write32(self, word): self.writechar(chr(word & 0xFF)) self.writechar(chr((word >> 8) & 0xFF)) @@ -41,6 +40,18 @@ self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) | (reg2 << 10) | (rn << 5) | reg1) + def STR_size_rr(self, scale, rt, rn, rm): + base = 0b111000001 + assert 0 <= scale <= 3 + self.wirte32((scale << 30) | (base << 21) | (rm << 16) | (0b11 << 13) | + (0b010 << 10) | (rn << 5) | rt) + + def STR_size_ri(self, scale, rt, rn, imm): + assert 0 <= imm < 4096 + assert 0 <= scale <= 3 + base = 0b11100100 + self.write32((scale << 30) | (base << 22) | (imm >> scale << 10) | (rn << 5) | rt) + def MOV_rr(self, rd, rn): self.ORR_rr(rd, r.xzr.value, rn) @@ -100,6 +111,18 @@ assert 0 <= immed <= 1<<15 assert immed & 0x7 == 0 self.write32((base << 22) | (immed >> 3 << 10) | (rn << 5) | rt) + + def LDR_rr(self, rt, rn, rm): + xxx + + def LDR_size_ri(self, size, rt, rn, ofs): + assert 0 <= size <= 3 + assert 0 <= ofs <= 4096 + base = 0b11100101 + self.write32((size << 30) | (base << 22) | (ofs >> size << 10) | (rn << 5) | rt) + + def LDR_size_rr(self, size, rt, rn, rm): + xxx def LDR_r_literal(self, rt, offset): base = 0b01011000 @@ -236,9 +259,9 @@ # XXX use the IMM version if close enough target = rffi.cast(lltype.Signed, target) self.gen_load_int_full(r.ip0.value, target) - self.BLR(r.ip0.value) + self.BLR_r(r.ip0.value) - def BLR(self, reg): + def BLR_r(self, reg): base = 0b1101011000111111000000 self.write32((base << 10) | (reg << 5)) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -5,8 +5,10 @@ from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE +from rpython.jit.backend.aarch64.locations import imm from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler from rpython.jit.backend.llsupport.gcmap import allocate_gcmap +from rpython.jit.backend.llsupport.regalloc import get_scale from rpython.jit.metainterp.history import TargetToken def gen_comp_op(name, flag): @@ -152,6 +154,69 @@ self.mc.ADD_ri(value_loc.value, value_loc.value, 1) self.mc.STR_ri(value_loc.value, base_loc.value, 0) + # -------------------------------- fields ------------------------------- + + def emit_op_gc_store(self, op, arglocs): + value_loc, base_loc, ofs_loc, size_loc = arglocs + scale = get_scale(size_loc.value) + self._write_to_mem(value_loc, base_loc, ofs_loc, imm(scale)) + + def _emit_op_gc_load(self, op, arglocs): + base_loc, ofs_loc, res_loc, nsize_loc = arglocs + nsize = nsize_loc.value + signed = (nsize < 0) + scale = get_scale(abs(nsize)) + self._load_from_mem(res_loc, base_loc, ofs_loc, imm(scale), signed) + + emit_op_gc_load_i = _emit_op_gc_load + emit_op_gc_load_r = _emit_op_gc_load + emit_op_gc_load_f = _emit_op_gc_load + + def _write_to_mem(self, value_loc, base_loc, ofs_loc, scale): + # Write a value of size '1 << scale' at the address + # 'base_ofs + ofs_loc'. Note that 'scale' is not used to scale + # the offset! + assert base_loc.is_core_reg() + if scale.value == 3: + # WORD size + if ofs_loc.is_imm(): + self.mc.STR_ri(value_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.STR_rr(value_loc.value, base_loc.value, + ofs_loc.value) + else: + if ofs_loc.is_imm(): + self.mc.STR_size_ri(scale.value, value_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.STR_size_rr(scale.value, value_loc.value, base_loc.value, + ofs_loc.value) + + def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale, + signed=False): + # Load a value of '1 << scale' bytes, from the memory location + # 'base_loc + ofs_loc'. Note that 'scale' is not used to scale + # the offset! + # + if scale.value == 3: + # WORD + if ofs_loc.is_imm(): + self.mc.LDR_ri(res_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.LDR_rr(res_loc.value, base_loc.value, + ofs_loc.value) + else: + if ofs_loc.is_imm(): + self.mc.LDR_size_ri(scale.value, res_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.LDR_size_rr(scale.value, res_loc.value, base_loc.value, + ofs_loc.value) + + # -------------------------------- guard -------------------------------- + def build_guard_token(self, op, frame_depth, arglocs, offset, fcond): descr = op.getdescr() assert isinstance(descr, AbstractFailDescr) @@ -191,6 +256,8 @@ self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs) emit_guard_op_guard_overflow = emit_guard_op_guard_false + # ----------------------------- call ------------------------------ + def _genop_call(self, op, arglocs): return self._emit_call(op, arglocs) emit_op_call_i = _genop_call @@ -272,11 +339,11 @@ gcmap = self._finish_gcmap else: gcmap = self.gcmap_for_finish - self.push_gcmap(self.mc, gcmap, store=True) + self.push_gcmap(self.mc, gcmap) elif self._finish_gcmap: # we're returning with a guard_not_forced_2 gcmap = self._finish_gcmap - self.push_gcmap(self.mc, gcmap, store=True) + self.push_gcmap(self.mc, gcmap) else: # note that the 0 here is redundant, but I would rather # keep that one and kill all the others diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -410,6 +410,42 @@ prepare_op_int_neg = prepare_unary prepare_op_int_invert = prepare_unary + # --------------------------------- fields -------------------------- + + def prepare_op_gc_store(self, op): + boxes = op.getarglist() + base_loc = self.make_sure_var_in_reg(boxes[0], boxes) + ofs = boxes[1].getint() + value_loc = self.make_sure_var_in_reg(boxes[2], boxes) + size = boxes[3].getint() + if check_imm_arg(ofs): + ofs_loc = imm(ofs) + else: + ofs_loc = r.ip1 + self.assembler.load(ofs_loc, imm(ofs)) + return [value_loc, base_loc, ofs_loc, imm(size)] + + def _prepare_op_gc_load(self, op): + a0 = op.getarg(0) + ofs = op.getarg(1).getint() + nsize = op.getarg(2).getint() # negative for "signed" + base_loc = self.make_sure_var_in_reg(a0) + immofs = imm(ofs) + if check_imm_arg(ofs): + ofs_loc = immofs + else: + ofs_loc = r.ip1 + self.assembler.load(ofs_loc, immofs) + self.possibly_free_vars_for_op(op) + res_loc = self.force_allocate_reg(op) + return [base_loc, ofs_loc, res_loc, imm(nsize)] + + prepare_op_gc_load_i = _prepare_op_gc_load + prepare_op_gc_load_r = _prepare_op_gc_load + prepare_op_gc_load_f = _prepare_op_gc_load + + # --------------------------------- call ---------------------------- + def _prepare_op_call(self, op): calldescr = op.getdescr() assert calldescr is not None diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -709,6 +709,7 @@ shortdescr = self.cpu.fielddescrof(self.S, 'short') self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(250)], 'void', descr=fielddescr2) + self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(133)], 'void', descr=fielddescr1) self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(1331)], _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
