PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/jit/backend/x86/test/test_regloc.py

https://bitbucket.org/alex_gaynor/pypy-postgresql/
Python | 321 lines | 307 code | 8 blank | 6 comment | 6 complexity | 287f1c0dc8f9e0a8d6adafe6e227f568 MD5 | raw file
  1. import struct, sys
  2. from pypy.jit.backend.x86.regloc import *
  3. from pypy.jit.backend.x86.test.test_rx86 import CodeBuilder32, CodeBuilder64, assert_encodes_as
  4. from pypy.jit.backend.x86.assembler import heap
  5. from pypy.jit.backend.x86.arch import IS_X86_64, IS_X86_32
  6. from pypy.rlib.rarithmetic import intmask
  7. import py.test
  8. class LocationCodeBuilder32(CodeBuilder32, LocationCodeBuilder):
  9. pass
  10. class LocationCodeBuilder64(CodeBuilder64, LocationCodeBuilder):
  11. pass
  12. cb32 = LocationCodeBuilder32
  13. cb64 = LocationCodeBuilder64
  14. def test_mov_16():
  15. # 32-bit
  16. assert_encodes_as(cb32, "MOV16", (ecx, ebx), '\x66\x89\xD9')
  17. assert_encodes_as(cb32, "MOV16", (ecx, ImmedLoc(12345)), '\x66\xB9\x39\x30')
  18. # 64-bit
  19. assert_encodes_as(cb64, "MOV16", (r8, ebx), '\x66\x41\x89\xD8') # 11 011 000
  20. assert_encodes_as(cb64, "MOV16", (ebx, r8), '\x66\x44\x89\xC3') # 11 000 011
  21. assert_encodes_as(cb64, "MOV16", (ecx, ebx), '\x66\x40\x89\xD9')
  22. # XXX: What we are testing for here is actually not the most compact
  23. # encoding.
  24. assert_encodes_as(cb64, "MOV16", (ecx, ImmedLoc(12345)), '\x66\x40\xC7\xC1\x39\x30')
  25. assert_encodes_as(cb64, "MOV16", (AddressLoc(r13, ImmedLoc(0), 0, 0), ImmedLoc(12345)), '\x66\x41\xC7\x45\x00\x39\x30')
  26. def test_cmp_16():
  27. # 32-bit
  28. assert_encodes_as(cb32, "CMP16", (ecx, ebx), '\x66\x39\xD9')
  29. assert_encodes_as(cb32, "CMP16", (ecx, ImmedLoc(12345)), '\x66\x81\xF9\x39\x30')
  30. # 64-bit
  31. assert_encodes_as(cb64, "CMP16", (r8, ebx), '\x66\x41\x39\xD8') # 11 011 000
  32. assert_encodes_as(cb64, "CMP16", (ebx, r8), '\x66\x44\x39\xC3') # 11 000 011
  33. assert_encodes_as(cb64, "CMP16", (ecx, ebx), '\x66\x40\x39\xD9')
  34. assert_encodes_as(cb64, "CMP16", (ecx, ImmedLoc(12345)), '\x66\x40\x81\xF9\x39\x30')
  35. assert_encodes_as(cb64, "CMP16", (AddressLoc(r13, ImmedLoc(0), 0, 0), ImmedLoc(12345)), '\x66\x41\x81\x7D\x00\x39\x30')
  36. def test_relocation():
  37. from pypy.rpython.lltypesystem import lltype, rffi
  38. from pypy.jit.backend.x86 import codebuf
  39. for target in [0x01020304, 0x0102030405060708]:
  40. if target > sys.maxint:
  41. continue
  42. mc = codebuf.MachineCodeBlockWrapper()
  43. mc.CALL(ImmedLoc(target))
  44. length = mc.get_relative_pos()
  45. buf = lltype.malloc(rffi.CCHARP.TO, length, flavor='raw')
  46. rawstart = rffi.cast(lltype.Signed, buf)
  47. if IS_X86_32:
  48. assert length == 5
  49. assert mc.relocations == [5]
  50. expected = "\xE8" + struct.pack('<i', target - (rawstart + 5))
  51. elif IS_X86_64:
  52. assert mc.relocations == []
  53. if target <= 0x7fffffff:
  54. assert length == 10
  55. expected = (
  56. "\x49\xC7\xC3\x04\x03\x02\x01" # MOV %r11, target
  57. "\x41\xFF\xD3") # CALL *%r11
  58. else:
  59. assert length == 13
  60. expected = (
  61. "\x49\xBB\x08\x07\x06\x05\x04\x03\x02\x01" # MOV %r11, targ
  62. "\x41\xFF\xD3") # CALL *%r11
  63. mc.copy_to_raw_memory(rawstart)
  64. assert ''.join([buf[i] for i in range(length)]) == expected
  65. lltype.free(buf, flavor='raw')
  66. class Test64Bits:
  67. def setup_class(cls):
  68. if not IS_X86_64:
  69. py.test.skip()
  70. def test_reuse_scratch_register(self):
  71. base_addr = 0xFEDCBA9876543210
  72. cb = LocationCodeBuilder64()
  73. cb.begin_reuse_scratch_register()
  74. cb.MOV(ecx, heap(base_addr))
  75. cb.MOV(ecx, heap(base_addr + 8))
  76. cb.end_reuse_scratch_register()
  77. expected_instructions = (
  78. # mov r11, 0xFEDCBA9876543210
  79. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE' +
  80. # mov rcx, [r11]
  81. '\x49\x8B\x0B' +
  82. # mov rcx, [r11+8]
  83. '\x49\x8B\x4B\x08'
  84. )
  85. assert cb.getvalue() == expected_instructions
  86. # ------------------------------------------------------------
  87. def test_64bit_address_1(self):
  88. base_addr = 0xFEDCBA9876543210
  89. cb = LocationCodeBuilder64()
  90. cb.CMP(ecx, AddressLoc(ImmedLoc(0), ImmedLoc(0), 0, base_addr))
  91. # this case is a CMP_rj
  92. #
  93. expected_instructions = (
  94. # mov r11, 0xFEDCBA9876543210
  95. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  96. # cmp rcx, [r11]
  97. '\x49\x3B\x0B'
  98. )
  99. assert cb.getvalue() == expected_instructions
  100. def test_64bit_address_2(self):
  101. base_addr = 0xFEDCBA9876543210
  102. cb = LocationCodeBuilder64()
  103. cb.MOV(ecx, AddressLoc(ImmedLoc(0), edx, 3, base_addr))
  104. # this case is a CMP_ra
  105. #
  106. expected_instructions = (
  107. # mov r11, 0xFEDCBA9876543210
  108. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  109. # mov rcx, [r11+8*rdx]
  110. '\x49\x8B\x0C\xD3'
  111. )
  112. assert cb.getvalue() == expected_instructions
  113. def test_64bit_address_3(self):
  114. base_addr = 0xFEDCBA9876543210
  115. cb = LocationCodeBuilder64()
  116. cb.MOV(ecx, AddressLoc(edx, ImmedLoc(0), 0, base_addr))
  117. # this case is a CMP_rm
  118. #
  119. expected_instructions = (
  120. # mov r11, 0xFEDCBA9876543210
  121. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  122. # mov rcx, [rdx+r11]
  123. '\x4A\x8B\x0C\x1A'
  124. )
  125. assert cb.getvalue() == expected_instructions
  126. def test_64bit_address_4(self):
  127. base_addr = 0xFEDCBA9876543210
  128. cb = LocationCodeBuilder64()
  129. cb.begin_reuse_scratch_register()
  130. assert cb._reuse_scratch_register is True
  131. assert cb._scratch_register_known is False
  132. cb.MOV(ecx, AddressLoc(edx, esi, 2, base_addr))
  133. assert cb._reuse_scratch_register is True
  134. assert cb._scratch_register_known is False
  135. # this case is a CMP_ra
  136. #
  137. expected_instructions = (
  138. # mov r11, 0xFEDCBA9876543210
  139. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  140. # lea r11, [rdx+r11]
  141. '\x4E\x8D\x1C\x1A'
  142. # mov rcx, [r11+4*rsi]
  143. '\x49\x8B\x0C\xB3'
  144. )
  145. assert cb.getvalue() == expected_instructions
  146. # ------------------------------------------------------------
  147. def test_MOV_immed32_into_64bit_address_1(self):
  148. immed = -0x01234567
  149. base_addr = 0xFEDCBA9876543210
  150. cb = LocationCodeBuilder64()
  151. cb.MOV(AddressLoc(ImmedLoc(0), ImmedLoc(0), 0, base_addr),
  152. ImmedLoc(immed))
  153. # this case is a MOV_ji
  154. #
  155. expected_instructions = (
  156. # mov r11, 0xFEDCBA9876543210
  157. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  158. # mov [r11], -0x01234567
  159. '\x49\xC7\x03\x99\xBA\xDC\xFE'
  160. )
  161. assert cb.getvalue() == expected_instructions
  162. def test_MOV_immed32_into_64bit_address_2(self):
  163. immed = -0x01234567
  164. base_addr = 0xFEDCBA9876543210
  165. cb = LocationCodeBuilder64()
  166. cb.MOV(AddressLoc(ImmedLoc(0), edx, 3, base_addr),
  167. ImmedLoc(immed))
  168. # this case is a MOV_ai
  169. #
  170. expected_instructions = (
  171. # mov r11, 0xFEDCBA9876543210
  172. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  173. # mov [r11+8*rdx], -0x01234567
  174. '\x49\xC7\x04\xD3\x99\xBA\xDC\xFE'
  175. )
  176. assert cb.getvalue() == expected_instructions
  177. def test_MOV_immed32_into_64bit_address_3(self):
  178. immed = -0x01234567
  179. base_addr = 0xFEDCBA9876543210
  180. cb = LocationCodeBuilder64()
  181. cb.MOV(AddressLoc(edx, ImmedLoc(0), 0, base_addr),
  182. ImmedLoc(immed))
  183. # this case is a MOV_mi
  184. #
  185. expected_instructions = (
  186. # mov r11, 0xFEDCBA9876543210
  187. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  188. # mov [rdx+r11], -0x01234567
  189. '\x4A\xC7\x04\x1A\x99\xBA\xDC\xFE'
  190. )
  191. assert cb.getvalue() == expected_instructions
  192. def test_MOV_immed32_into_64bit_address_4(self):
  193. immed = -0x01234567
  194. base_addr = 0xFEDCBA9876543210
  195. cb = LocationCodeBuilder64()
  196. cb.MOV(AddressLoc(edx, esi, 2, base_addr), ImmedLoc(immed))
  197. # this case is a MOV_ai
  198. #
  199. expected_instructions = (
  200. # mov r11, 0xFEDCBA9876543210
  201. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  202. # lea r11, [rdx+r11]
  203. '\x4E\x8D\x1C\x1A'
  204. # mov [r11+4*rsi], -0x01234567
  205. '\x49\xC7\x04\xB3\x99\xBA\xDC\xFE'
  206. )
  207. assert cb.getvalue() == expected_instructions
  208. # ------------------------------------------------------------
  209. def test_MOV_immed64_into_64bit_address_1(self):
  210. immed = 0x0123456789ABCDEF
  211. base_addr = 0xFEDCBA9876543210
  212. cb = LocationCodeBuilder64()
  213. cb.MOV(AddressLoc(ImmedLoc(0), ImmedLoc(0), 0, base_addr),
  214. ImmedLoc(immed))
  215. # this case is a MOV_ji
  216. #
  217. expected_instructions = (
  218. # push rax
  219. '\x50'
  220. # mov rax, 0x0123456789ABCDEF
  221. '\x48\xB8\xEF\xCD\xAB\x89\x67\x45\x23\x01'
  222. # mov r11, 0xFEDCBA9876543210
  223. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  224. # mov [r11], rax
  225. '\x49\x89\x03'
  226. # pop rax
  227. '\x58'
  228. )
  229. assert cb.getvalue() == expected_instructions
  230. def test_MOV_immed64_into_64bit_address_2(self):
  231. immed = 0x0123456789ABCDEF
  232. base_addr = 0xFEDCBA9876543210
  233. cb = LocationCodeBuilder64()
  234. cb.MOV(AddressLoc(ImmedLoc(0), edx, 3, base_addr),
  235. ImmedLoc(immed))
  236. # this case is a MOV_ai
  237. #
  238. expected_instructions = (
  239. # push rax
  240. '\x50'
  241. # mov rax, 0x0123456789ABCDEF
  242. '\x48\xB8\xEF\xCD\xAB\x89\x67\x45\x23\x01'
  243. # mov r11, 0xFEDCBA9876543210
  244. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  245. # mov [r11+8*rdx], rax
  246. '\x49\x89\x04\xD3'
  247. # pop rax
  248. '\x58'
  249. )
  250. assert cb.getvalue() == expected_instructions
  251. def test_MOV_immed64_into_64bit_address_3(self):
  252. immed = 0x0123456789ABCDEF
  253. base_addr = 0xFEDCBA9876543210
  254. cb = LocationCodeBuilder64()
  255. cb.MOV(AddressLoc(eax, ImmedLoc(0), 0, base_addr),
  256. ImmedLoc(immed))
  257. # this case is a MOV_mi
  258. #
  259. expected_instructions = (
  260. # push rdx
  261. '\x52'
  262. # mov rdx, 0x0123456789ABCDEF
  263. '\x48\xBA\xEF\xCD\xAB\x89\x67\x45\x23\x01'
  264. # mov r11, 0xFEDCBA9876543210
  265. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  266. # mov [rax+r11], rdx
  267. '\x4A\x89\x14\x18'
  268. # pop rdx
  269. '\x5A'
  270. )
  271. assert cb.getvalue() == expected_instructions
  272. def test_MOV_immed64_into_64bit_address_4(self):
  273. immed = 0x0123456789ABCDEF
  274. base_addr = 0xFEDCBA9876543210
  275. cb = LocationCodeBuilder64()
  276. cb.MOV(AddressLoc(edx, eax, 2, base_addr), ImmedLoc(immed))
  277. # this case is a MOV_ai
  278. #
  279. expected_instructions = (
  280. # push rcx
  281. '\x51'
  282. # mov rcx, 0x0123456789ABCDEF
  283. '\x48\xB9\xEF\xCD\xAB\x89\x67\x45\x23\x01'
  284. # mov r11, 0xFEDCBA9876543210
  285. '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
  286. # lea r11, [rdx+r11]
  287. '\x4E\x8D\x1C\x1A'
  288. # mov [r11+4*rax], rcx
  289. '\x49\x89\x0C\x83'
  290. # pop rcx
  291. '\x59'
  292. )
  293. assert cb.getvalue() == expected_instructions