Commits

Armin Rigo committed d7c8a96

(alex, arigo, greg) Support read_timestamp in x86-64.

Comments (0)

Files changed (3)

pypy/jit/backend/test/runner_test.py

         self.execute_operation(rop.JIT_DEBUG, [c_box, c_nest, c_nest,
                                                c_nest, c_nest], 'void')
 
+    def test_read_timestamp(self):
+        if longlong.is_64_bit:
+            got1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int')
+            got2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int')
+            res1 = got1.getint()
+            res2 = got2.getint()
+        else:
+            got1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float')
+            got2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float')
+            res1 = got1.getlonglong()
+            res2 = got2.getlonglong()
+        assert res1 < res2 < res1 + 2**32
+
 
 class LLtypeBackendTest(BaseBackendTest):
 

pypy/jit/backend/x86/assembler.py

             assert 0, itemsize
 
     def genop_read_timestamp(self, op, arglocs, resloc):
-        # XXX cheat
-        addr1 = self.fail_boxes_int.get_addr_for_num(0)
-        addr2 = self.fail_boxes_int.get_addr_for_num(1)
         self.mc.RDTSC()
-        self.mc.MOV(heap(addr1), eax)
-        self.mc.MOV(heap(addr2), edx)
-        self.mc.MOVSD(resloc, heap(addr1))
+        if longlong.is_64_bit:
+            self.mc.SHL_ri(edx.value, 32)
+            self.mc.OR_rr(edx.value, eax.value)
+        else:
+            loc1, = arglocs
+            self.mc.MOVD_xr(loc1.value, edx.value)
+            self.mc.MOVD_xr(resloc.value, eax.value)
+            self.mc.PUNPCKLDQ_xx(resloc.value, loc1.value)
 
     def genop_guard_guard_true(self, ign_1, guard_op, guard_token, locs, ign_2):
         loc = locs[0]

pypy/jit/backend/x86/regalloc.py

 
     def consider_read_timestamp(self, op):
         tmpbox_high = TempBox()
-        tmpbox_low = TempBox()
         self.rm.force_allocate_reg(tmpbox_high, selected_reg=eax)
-        self.rm.force_allocate_reg(tmpbox_low, selected_reg=edx)
-        result_loc = self.xrm.force_allocate_reg(op.result)
-        self.Perform(op, [], result_loc)
+        if longlong.is_64_bit:
+            # on 64-bit, use rax as temporary register and returns the
+            # result in rdx
+            result_loc = self.rm.force_allocate_reg(op.result,
+                                                    selected_reg=edx)
+            self.Perform(op, [], result_loc)
+        else:
+            # on 32-bit, use both eax and edx as temporary registers,
+            # use a temporary xmm register, and returns the result in
+            # another xmm register.
+            tmpbox_low = TempBox()
+            self.rm.force_allocate_reg(tmpbox_low, selected_reg=edx)
+            xmmtmpbox = TempBox()
+            xmmtmploc = self.xrm.force_allocate_reg(xmmtmpbox)
+            result_loc = self.xrm.force_allocate_reg(op.result)
+            self.Perform(op, [xmmtmploc], result_loc)
+            self.xrm.possibly_free_var(xmmtmpbox)
+            self.rm.possibly_free_var(tmpbox_low)
         self.rm.possibly_free_var(tmpbox_high)
-        self.rm.possibly_free_var(tmpbox_low)
 
     def consider_jump(self, op):
         assembler = self.assembler