PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/backend/ppc/test/test_ppc.py

https://bitbucket.org/pypy/pypy/
Python | 321 lines | 300 code | 8 blank | 13 comment | 0 complexity | f6361fe398eca2589e797cff64d76524 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. import random, sys, os
  3. from rpython.jit.backend.ppc.codebuilder import BasicPPCAssembler, PPCBuilder
  4. from rpython.jit.backend.ppc.regname import *
  5. from rpython.jit.backend.ppc.register import *
  6. from rpython.jit.backend.ppc import form
  7. from rpython.jit.backend import detect_cpu
  8. from rpython.jit.backend.ppc.arch import IS_PPC_32, IS_PPC_64, IS_BIG_ENDIAN
  9. from rpython.jit.backend.ppc.arch import WORD
  10. from rpython.rtyper.lltypesystem import lltype, rffi
  11. from rpython.rtyper.annlowlevel import llhelper
  12. cpu = detect_cpu.autodetect()
  13. class TestDisassemble(object):
  14. def test_match(self):
  15. class A(BasicPPCAssembler):
  16. insts = []
  17. a = A()
  18. a.add(1, 2, 3)
  19. inst = a.insts[-1]
  20. assert A.add.match(inst.assemble())
  21. """
  22. Creates the boilerplate code for the tests.
  23. - Make a PPCBuilder object
  24. - Let the given test create the machine code
  25. - Create a function and call it
  26. - Compare the return value with the expected result
  27. """
  28. def asmtest(expected):
  29. def testmaker(test):
  30. def newtest(self):
  31. a = PPCBuilder()
  32. test(self, a)
  33. f = a.get_assembler_function()
  34. assert f() == expected
  35. return newtest
  36. return testmaker
  37. """
  38. Treats the given bitstring as binary representation
  39. of an integer in two's complement.
  40. """
  41. def bits_to_signed_int(bits):
  42. assert len(bits) > 0
  43. sign = 1
  44. if bits[0] == "1":
  45. sign = -1
  46. bits = bits[1:].replace("0", "$").replace("1", "0").replace("$", "1")
  47. return sign * (int(bits, 2) + 1)
  48. def hex_to_signed_int(hx):
  49. return bits_to_signed_int(bin(int(hx, 16))[2:])
  50. # Testing simple assembler instructions
  51. class TestAssemble(object):
  52. def setup_class(cls):
  53. if cpu not in ["ppc", "ppc64", "ppc-64"]:
  54. py.test.skip("can't test all of ppcgen on non-PPC!")
  55. #py.test.xfail("assemble does not return a function any longer, fix tests")
  56. """
  57. Tests are build like this:
  58. @asmtest(expected=<EXPECTED RESULT>)
  59. def testX(self, assembler):
  60. <Assembler Code>
  61. This is equivalent to:
  62. def testX(self):
  63. assembler = MyPPCAssembler()
  64. <Assembler Code>
  65. f = assembler.assemble()
  66. assert f() == <EXPECTED RESULT>
  67. """
  68. @asmtest(expected=200)
  69. def test_li(self, a):
  70. a.li(3, 200)
  71. a.blr()
  72. @asmtest(expected=7)
  73. def test_add_imm(self, a):
  74. a.li(3, 6)
  75. a.addi(3, 3, 1)
  76. a.blr()
  77. @asmtest(expected=12341234)
  78. def test_load_imm(self, a):
  79. a.load_imm(r10, 12341234)
  80. a.mtctr(10)
  81. a.mfctr(11)
  82. a.mr(3, 11)
  83. a.blr()
  84. @asmtest(expected=33333333)
  85. def test_add_reg(self, a):
  86. a.load_imm(r10, 11111111)
  87. a.load_imm(r11, 22222222)
  88. a.add(12, 10, 11)
  89. a.mr(3, 12)
  90. a.blr()
  91. @asmtest(expected=-1000)
  92. def test_add_pos_and_neg(self, a):
  93. a.load_imm(r10, 2000)
  94. a.load_imm(r11, -3000)
  95. a.add(3, 10, 11)
  96. a.blr()
  97. @asmtest(expected=7)
  98. def test_sub_imm(self, a):
  99. a.li(3, 10)
  100. a.subi(3, 3, 3)
  101. a.blr()
  102. @asmtest(expected=(123435 - 76457))
  103. def test_sub_reg(self, a):
  104. a.load_imm(r5, 123435)
  105. a.load_imm(r6, 76457)
  106. a.sub(3, 5, 6)
  107. a.blr()
  108. @asmtest(expected=(10000 * 5000))
  109. def test_mul_imm(self, a):
  110. a.load_imm(r3, 10000)
  111. a.mulli(3, 3, 5000)
  112. a.blr()
  113. # 1000000 * 1000000 = 0b1110100011010100101001010001000000000000
  114. # expect: r3 = -HWORD-|11010100101001010001000000000000
  115. @asmtest(expected=bits_to_signed_int('11010100101001010001000000000000'))
  116. def test_mullw(self, a):
  117. word = 1000000
  118. a.load_imm(r5, word)
  119. a.load_imm(r6, word)
  120. a.mullw(3, 5, 6)
  121. if IS_PPC_64:
  122. a.extsw(3, 3)
  123. a.blr()
  124. # 1000000 * 1000000 = 0b1110100011010100101001010001000000000000
  125. # expect: r3 = 11101000|------------LWORD--------------
  126. @asmtest(expected=int('11101000', 2))
  127. def test_mulhw(self, a):
  128. word = 1000000
  129. a.load_imm(r5, word)
  130. a.load_imm(r6, word)
  131. a.mulhw(3, 5, 6)
  132. if IS_PPC_64:
  133. a.extsw(3, 3)
  134. a.blr()
  135. # 1000000 * 1000000 = 0b1110100011010100101001010001000000000000
  136. # expect: r3 = 11101000|------------LWORD--------------
  137. @asmtest(expected=int('11101000', 2))
  138. def test_mulhwu(self, a):
  139. word = 1000000
  140. a.load_imm(r5, word)
  141. a.load_imm(r6, word)
  142. a.mulhwu(3, 5, 6)
  143. if IS_PPC_64:
  144. a.extsw(3, 3)
  145. a.blr()
  146. @asmtest(expected=10000)
  147. def test_divw(self, a):
  148. divident = 1000000
  149. divisor = 100
  150. a.load_imm(r10, divident)
  151. a.load_imm(r11, divisor)
  152. a.divw(3, 10, 11)
  153. a.blr()
  154. def test_call_function(self):
  155. functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
  156. call_addr = rffi.cast(lltype.Signed, llhelper(functype, func))
  157. a = PPCBuilder()
  158. # NOW EXPLICITLY:
  159. #
  160. # - Load the address of the function to call into a register x
  161. # - Move the content of this register x into CTR
  162. # - Set the LR manually (or with bctrl)
  163. # - Do jump
  164. a.li(3, 50)
  165. if IS_PPC_32:
  166. a.load_imm(r10, call_addr)
  167. elif IS_BIG_ENDIAN:
  168. # load the 3-words descriptor
  169. a.load_from_addr(r10, call_addr)
  170. a.load_from_addr(r2, call_addr+WORD)
  171. a.load_from_addr(r11, call_addr+2*WORD)
  172. else:
  173. # no descriptor on little-endian, but the ABI says r12 must
  174. # contain the function pointer
  175. a.load_imm(r10, call_addr)
  176. a.mr(12, 10)
  177. a.mtctr(10)
  178. a.bctr()
  179. a.blr()
  180. f = a.get_assembler_function()
  181. assert f() == 65
  182. @asmtest(expected=0)
  183. def test_and(self, a):
  184. a.load_imm(r10, 8)
  185. a.load_imm(r11, 7)
  186. a.and_(3, 10, 11)
  187. a.blr()
  188. @asmtest(expected=15)
  189. def test_or(self, a):
  190. a.load_imm(r10, 8)
  191. a.load_imm(r11, 7)
  192. a.or_(3, 10, 11)
  193. a.blr()
  194. @asmtest(expected=15)
  195. def test_nand(self, a):
  196. a.load_imm(r10, 8)
  197. a.load_imm(r11, 7)
  198. a.nand(3, 10, 11)
  199. a.load_imm(r12, 0x0000000F) # zero out first 28 bits
  200. a.and_(3, 3, 12) #
  201. a.blr()
  202. @asmtest(expected=1)
  203. def test_nor(self, a):
  204. a.load_imm(r10, 10)
  205. a.load_imm(r11, 6)
  206. a.nor(3, 10, 11)
  207. a.load_imm(r12, 0x0000000F) # zero out first 28 bits
  208. a.and_(3, 3, 12) #
  209. a.blr()
  210. @asmtest(expected=5)
  211. def test_xor(self, a):
  212. a.load_imm(r10, 15)
  213. a.load_imm(r11, 10)
  214. a.xor(3, 10, 11)
  215. a.blr()
  216. @asmtest(expected=0x120)
  217. def test_slw(self, a):
  218. a.load_imm(r10, 9)
  219. a.load_imm(r11, 5)
  220. a.slw(3, 10, 11)
  221. a.blr()
  222. @asmtest(expected=9)
  223. def test_srw(self, a):
  224. a.load_imm(r10, 0x120)
  225. a.load_imm(r11, 5)
  226. a.srw(3, 10, 11)
  227. a.blr()
  228. def test_neg(self):
  229. a = PPCBuilder()
  230. a.load_imm(r10, 0x0000F0F0)
  231. a.neg(3, 10)
  232. a.blr()
  233. f = a.get_assembler_function()
  234. assert f() == hex_to_signed_int("FFFF0F10")
  235. def test_load_and_store(self):
  236. a = PPCBuilder()
  237. word1 = 1000
  238. word2 = 2000
  239. p = lltype.malloc(rffi.CArray(lltype.Signed), 2, flavor="raw")
  240. a.load_imm(r10, word1)
  241. a.load_imm(r11, word2)
  242. a.load_imm(r8, rffi.cast(lltype.Signed, p))
  243. a.load_imm(r9, rffi.cast(lltype.Signed, p) + WORD)
  244. a.stw(10, 8, 0)
  245. a.stw(11, 9, 0)
  246. a.lwz(4, 8, 0)
  247. a.lwz(5, 9, 0)
  248. a.add(3, 4, 5)
  249. a.blr()
  250. f = a.get_assembler_function()
  251. assert f() == word1 + word2
  252. lltype.free(p, flavor="raw")
  253. def test_load_from(self):
  254. a = PPCBuilder()
  255. p = lltype.malloc(rffi.CArray(rffi.LONG), 1, flavor="raw")
  256. addr = rffi.cast(lltype.Signed, p)
  257. p[0] = rffi.cast(rffi.LONG, 200)
  258. a.load_from_addr(r3, addr)
  259. a.blr()
  260. f = a.get_assembler_function()
  261. assert f() == 200
  262. p[0] = rffi.cast(rffi.LONG, 300)
  263. assert f() == 300
  264. lltype.free(p, flavor="raw")
  265. def func(arg):
  266. return arg + 15
  267. def is_64_bit_arch():
  268. import sys
  269. return sys.maxint == 9223372036854775807