PageRenderTime 57ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/rtyper/rint.py

https://bitbucket.org/pypy/pypy/
Python | 650 lines | 579 code | 62 blank | 9 comment | 35 complexity | 735041ae8dc4aa34dd6fef624f72036a MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import sys
  2. from rpython.annotator import model as annmodel
  3. from rpython.flowspace.operation import op_appendices
  4. from rpython.rlib import objectmodel, jit
  5. from rpython.rlib.rarithmetic import intmask, longlongmask, r_int, r_longlong
  6. from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlonglong
  7. from rpython.rtyper.error import TyperError
  8. from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, Bool, Float,
  9. Char, UniChar, UnsignedLongLong, SignedLongLong, build_number, Number,
  10. cast_primitive, typeOf, SignedLongLongLong)
  11. from rpython.rtyper.rfloat import FloatRepr
  12. from rpython.rtyper.rmodel import inputconst, log
  13. from rpython.tool.pairtype import pairtype
  14. from rpython.rtyper.lltypesystem.lloperation import llop
  15. class IntegerRepr(FloatRepr):
  16. def __init__(self, lowleveltype, opprefix):
  17. self.lowleveltype = lowleveltype
  18. self._opprefix = opprefix
  19. self.as_int = self
  20. @property
  21. def opprefix(self):
  22. if self._opprefix is None:
  23. raise TyperError("arithmetic not supported on %r, its size is too small" %
  24. self.lowleveltype)
  25. return self._opprefix
  26. def convert_const(self, value):
  27. if isinstance(value, objectmodel.Symbolic):
  28. return value
  29. T = typeOf(value)
  30. if isinstance(T, Number) or T is Bool:
  31. return cast_primitive(self.lowleveltype, value)
  32. raise TyperError("not an integer: %r" % (value,))
  33. def get_ll_eq_function(self):
  34. if getattr(self, '_opprefix', '?') is None:
  35. return ll_eq_shortint
  36. return None
  37. def get_ll_ge_function(self):
  38. return None
  39. get_ll_gt_function = get_ll_ge_function
  40. get_ll_lt_function = get_ll_ge_function
  41. get_ll_le_function = get_ll_ge_function
  42. def get_ll_hash_function(self):
  43. if (sys.maxint == 2147483647 and
  44. self.lowleveltype in (SignedLongLong, UnsignedLongLong)):
  45. return ll_hash_long_long
  46. return ll_hash_int
  47. get_ll_fasthash_function = get_ll_hash_function
  48. def get_ll_dummyval_obj(self, rtyper, s_value):
  49. # if >= 0, then all negative values are special
  50. if s_value.nonneg and self.lowleveltype is Signed:
  51. return signed_repr # whose ll_dummy_value is -1
  52. else:
  53. return None
  54. ll_dummy_value = -1
  55. def rtype_chr(_, hop):
  56. vlist = hop.inputargs(Signed)
  57. if hop.has_implicit_exception(ValueError):
  58. hop.exception_is_here()
  59. hop.gendirectcall(ll_check_chr, vlist[0])
  60. else:
  61. hop.exception_cannot_occur()
  62. return hop.genop('cast_int_to_char', vlist, resulttype=Char)
  63. def rtype_unichr(_, hop):
  64. vlist = hop.inputargs(Signed)
  65. if hop.has_implicit_exception(ValueError):
  66. hop.exception_is_here()
  67. hop.gendirectcall(ll_check_unichr, vlist[0])
  68. else:
  69. hop.exception_cannot_occur()
  70. return hop.genop('cast_int_to_unichar', vlist, resulttype=UniChar)
  71. def rtype_bool(self, hop):
  72. assert self is self.as_int # rtype_is_true() is overridden in BoolRepr
  73. vlist = hop.inputargs(self)
  74. return hop.genop(self.opprefix + 'is_true', vlist, resulttype=Bool)
  75. #Unary arithmetic operations
  76. def rtype_abs(self, hop):
  77. self = self.as_int
  78. vlist = hop.inputargs(self)
  79. if hop.s_result.unsigned:
  80. return vlist[0]
  81. else:
  82. return hop.genop(self.opprefix + 'abs', vlist, resulttype=self)
  83. def rtype_abs_ovf(self, hop):
  84. self = self.as_int
  85. if hop.s_result.unsigned:
  86. raise TyperError("forbidden uint_abs_ovf")
  87. else:
  88. return _rtype_call_helper(hop, 'abs_ovf')
  89. def rtype_invert(self, hop):
  90. self = self.as_int
  91. vlist = hop.inputargs(self)
  92. return hop.genop(self.opprefix + 'invert', vlist, resulttype=self)
  93. def rtype_neg(self, hop):
  94. self = self.as_int
  95. vlist = hop.inputargs(self)
  96. if hop.s_result.unsigned:
  97. # implement '-r_uint(x)' with unsigned subtraction '0 - x'
  98. zero = self.lowleveltype._defl()
  99. vlist.insert(0, hop.inputconst(self.lowleveltype, zero))
  100. return hop.genop(self.opprefix + 'sub', vlist, resulttype=self)
  101. else:
  102. return hop.genop(self.opprefix + 'neg', vlist, resulttype=self)
  103. def rtype_neg_ovf(self, hop):
  104. self = self.as_int
  105. if hop.s_result.unsigned:
  106. # this is supported (and turns into just 0-x) for rbigint.py
  107. hop.exception_cannot_occur()
  108. return self.rtype_neg(hop)
  109. else:
  110. return _rtype_call_helper(hop, 'neg_ovf')
  111. def rtype_pos(self, hop):
  112. self = self.as_int
  113. vlist = hop.inputargs(self)
  114. return vlist[0]
  115. def rtype_int(self, hop):
  116. if self.lowleveltype in (Unsigned, UnsignedLongLong):
  117. raise TyperError("use intmask() instead of int(r_uint(...))")
  118. vlist = hop.inputargs(Signed)
  119. hop.exception_cannot_occur()
  120. return vlist[0]
  121. def rtype_float(_, hop):
  122. vlist = hop.inputargs(Float)
  123. hop.exception_cannot_occur()
  124. return vlist[0]
  125. @jit.elidable
  126. def ll_str(self, i):
  127. from rpython.rtyper.lltypesystem.ll_str import ll_int2dec
  128. return ll_int2dec(i)
  129. def rtype_hex(self, hop):
  130. from rpython.rtyper.lltypesystem.ll_str import ll_int2hex
  131. self = self.as_int
  132. varg = hop.inputarg(self, 0)
  133. true = inputconst(Bool, True)
  134. return hop.gendirectcall(ll_int2hex, varg, true)
  135. def rtype_oct(self, hop):
  136. from rpython.rtyper.lltypesystem.ll_str import ll_int2oct
  137. self = self.as_int
  138. varg = hop.inputarg(self, 0)
  139. true = inputconst(Bool, True)
  140. return hop.gendirectcall(ll_int2oct, varg, true)
  141. _integer_reprs = {}
  142. def getintegerrepr(lltype, prefix=None):
  143. try:
  144. return _integer_reprs[lltype]
  145. except KeyError:
  146. pass
  147. repr = _integer_reprs[lltype] = IntegerRepr(lltype, prefix)
  148. return repr
  149. class __extend__(annmodel.SomeInteger):
  150. def rtyper_makerepr(self, rtyper):
  151. lltype = build_number(None, self.knowntype)
  152. return getintegerrepr(lltype)
  153. def rtyper_makekey(self):
  154. return self.__class__, self.knowntype
  155. signed_repr = getintegerrepr(Signed, 'int_')
  156. signedlonglong_repr = getintegerrepr(SignedLongLong, 'llong_')
  157. signedlonglonglong_repr = getintegerrepr(SignedLongLongLong, 'lllong_')
  158. unsigned_repr = getintegerrepr(Unsigned, 'uint_')
  159. unsignedlonglong_repr = getintegerrepr(UnsignedLongLong, 'ullong_')
  160. class __extend__(pairtype(IntegerRepr, IntegerRepr)):
  161. def convert_from_to((r_from, r_to), v, llops):
  162. if r_from.lowleveltype == Signed and r_to.lowleveltype == Unsigned:
  163. log.debug('explicit cast_int_to_uint')
  164. return llops.genop('cast_int_to_uint', [v], resulttype=Unsigned)
  165. if r_from.lowleveltype == Unsigned and r_to.lowleveltype == Signed:
  166. log.debug('explicit cast_uint_to_int')
  167. return llops.genop('cast_uint_to_int', [v], resulttype=Signed)
  168. if r_from.lowleveltype == Signed and r_to.lowleveltype == SignedLongLong:
  169. return llops.genop('cast_int_to_longlong', [v], resulttype=SignedLongLong)
  170. if r_from.lowleveltype == SignedLongLong and r_to.lowleveltype == Signed:
  171. return llops.genop('truncate_longlong_to_int', [v], resulttype=Signed)
  172. return llops.genop('cast_primitive', [v], resulttype=r_to.lowleveltype)
  173. #arithmetic
  174. def rtype_add(_, hop):
  175. return _rtype_template(hop, 'add')
  176. rtype_inplace_add = rtype_add
  177. def rtype_add_ovf(_, hop):
  178. func = 'add_ovf'
  179. if hop.r_result.opprefix == 'int_':
  180. if hop.args_s[1].nonneg:
  181. func = 'add_nonneg_ovf'
  182. elif hop.args_s[0].nonneg:
  183. hop = hop.copy()
  184. hop.swap_fst_snd_args()
  185. func = 'add_nonneg_ovf'
  186. return _rtype_template(hop, func)
  187. def rtype_sub(_, hop):
  188. return _rtype_template(hop, 'sub')
  189. rtype_inplace_sub = rtype_sub
  190. def rtype_sub_ovf(_, hop):
  191. return _rtype_template(hop, 'sub_ovf')
  192. def rtype_mul(_, hop):
  193. return _rtype_template(hop, 'mul')
  194. rtype_inplace_mul = rtype_mul
  195. def rtype_mul_ovf(_, hop):
  196. return _rtype_template(hop, 'mul_ovf')
  197. def rtype_floordiv(_, hop):
  198. return _rtype_call_helper(hop, 'py_div', [ZeroDivisionError])
  199. rtype_inplace_floordiv = rtype_floordiv
  200. def rtype_floordiv_ovf(_, hop):
  201. return _rtype_call_helper(hop, 'py_div_ovf', [ZeroDivisionError])
  202. # turn 'div' on integers into 'floordiv'
  203. rtype_div = rtype_floordiv
  204. rtype_inplace_div = rtype_inplace_floordiv
  205. rtype_div_ovf = rtype_floordiv_ovf
  206. # 'def rtype_truediv' is delegated to the superclass FloatRepr
  207. def rtype_mod(_, hop):
  208. return _rtype_call_helper(hop, 'py_mod', [ZeroDivisionError])
  209. rtype_inplace_mod = rtype_mod
  210. def rtype_mod_ovf(_, hop):
  211. return _rtype_call_helper(hop, 'py_mod_ovf', [ZeroDivisionError])
  212. def rtype_xor(_, hop):
  213. return _rtype_template(hop, 'xor')
  214. rtype_inplace_xor = rtype_xor
  215. def rtype_and_(_, hop):
  216. return _rtype_template(hop, 'and')
  217. rtype_inplace_and = rtype_and_
  218. def rtype_or_(_, hop):
  219. return _rtype_template(hop, 'or')
  220. rtype_inplace_or = rtype_or_
  221. def rtype_lshift(_, hop):
  222. return _rtype_template(hop, 'lshift')
  223. rtype_inplace_lshift = rtype_lshift
  224. def rtype_lshift_ovf(_, hop):
  225. return _rtype_call_helper(hop, 'lshift_ovf')
  226. def rtype_rshift(_, hop):
  227. return _rtype_template(hop, 'rshift')
  228. rtype_inplace_rshift = rtype_rshift
  229. #comparisons: eq is_ ne lt le gt ge
  230. def rtype_eq(_, hop):
  231. return _rtype_compare_template(hop, 'eq')
  232. rtype_is_ = rtype_eq
  233. def rtype_ne(_, hop):
  234. return _rtype_compare_template(hop, 'ne')
  235. def rtype_lt(_, hop):
  236. return _rtype_compare_template(hop, 'lt')
  237. def rtype_le(_, hop):
  238. return _rtype_compare_template(hop, 'le')
  239. def rtype_gt(_, hop):
  240. return _rtype_compare_template(hop, 'gt')
  241. def rtype_ge(_, hop):
  242. return _rtype_compare_template(hop, 'ge')
  243. #Helper functions
  244. def _rtype_template(hop, func):
  245. """Write a simple operation implementing the given 'func'.
  246. It must be an operation that cannot raise.
  247. """
  248. r_result = hop.r_result
  249. if r_result.lowleveltype == Bool:
  250. repr = signed_repr
  251. else:
  252. repr = r_result
  253. if func.startswith(('lshift', 'rshift')):
  254. repr2 = signed_repr
  255. else:
  256. repr2 = repr
  257. vlist = hop.inputargs(repr, repr2)
  258. prefix = repr.opprefix
  259. if '_ovf' in func or func.startswith(('py_mod', 'py_div')):
  260. if prefix+func not in ('int_add_ovf', 'int_add_nonneg_ovf',
  261. 'int_sub_ovf', 'int_mul_ovf'):
  262. raise TyperError("%r should not be used here any more" % (func,))
  263. hop.has_implicit_exception(OverflowError)
  264. hop.exception_is_here()
  265. else:
  266. hop.exception_cannot_occur()
  267. v_res = hop.genop(prefix+func, vlist, resulttype=repr)
  268. v_res = hop.llops.convertvar(v_res, repr, r_result)
  269. return v_res
  270. def _rtype_call_helper(hop, func, implicit_excs=[]):
  271. """Write a call to a helper implementing the given 'func'.
  272. It can raise OverflowError if 'func' ends with '_ovf'.
  273. Other possible exceptions can be specified in 'implicit_excs'.
  274. """
  275. any_implicit_exception = False
  276. if func.endswith('_ovf'):
  277. if hop.s_result.unsigned:
  278. raise TyperError("forbidden unsigned " + func)
  279. else:
  280. hop.has_implicit_exception(OverflowError)
  281. any_implicit_exception = True
  282. for implicit_exc in implicit_excs:
  283. if hop.has_implicit_exception(implicit_exc):
  284. appendix = op_appendices[implicit_exc]
  285. func += '_' + appendix
  286. any_implicit_exception = True
  287. if not any_implicit_exception:
  288. if not func.startswith(('py_mod', 'py_div')):
  289. return _rtype_template(hop, func)
  290. repr = hop.r_result
  291. assert repr.lowleveltype != Bool
  292. if func in ('abs_ovf', 'neg_ovf'):
  293. vlist = hop.inputargs(repr)
  294. else:
  295. if func.startswith(('lshift', 'rshift')):
  296. vlist = hop.inputargs(repr, signed_repr)
  297. else:
  298. vlist = hop.inputargs(repr, repr)
  299. if any_implicit_exception:
  300. hop.exception_is_here()
  301. else:
  302. hop.exception_cannot_occur()
  303. funcname = 'll_' + repr.opprefix + func
  304. llfunc = globals()[funcname]
  305. if all(s_arg.nonneg for s_arg in hop.args_s):
  306. llfunc = globals().get(funcname + '_nonnegargs', llfunc)
  307. v_result = hop.gendirectcall(llfunc, *vlist)
  308. assert v_result.concretetype == repr.lowleveltype
  309. return v_result
  310. INT_BITS_1 = r_int.BITS - 1
  311. LLONG_BITS_1 = r_longlong.BITS - 1
  312. LLLONG_BITS_1 = r_longlonglong.BITS - 1
  313. INT_MIN = int(-(1 << INT_BITS_1))
  314. # ---------- floordiv ----------
  315. @jit.oopspec("int.py_div(x, y)")
  316. def ll_int_py_div(x, y):
  317. # Python, and RPython, assume that integer division truncates
  318. # towards -infinity. However, in C, integer division truncates
  319. # towards 0. So assuming that, we need to apply a correction
  320. # in the right cases.
  321. r = llop.int_floordiv(Signed, x, y) # <= truncates like in C
  322. p = r * y
  323. if y < 0: u = p - x
  324. else: u = x - p
  325. return r + (u >> INT_BITS_1)
  326. @jit.oopspec("int.py_div(x, y)")
  327. def ll_int_py_div_nonnegargs(x, y):
  328. from rpython.rlib.debug import ll_assert
  329. r = llop.int_floordiv(Signed, x, y) # <= truncates like in C
  330. ll_assert(r >= 0, "int_py_div_nonnegargs(): one arg is negative")
  331. return r
  332. def ll_int_py_div_zer(x, y):
  333. if y == 0:
  334. raise ZeroDivisionError("integer division")
  335. return ll_int_py_div(x, y)
  336. def ll_int_py_div_ovf(x, y):
  337. # JIT: intentionally not short-circuited to produce only one guard
  338. # and to remove the check fully if one of the arguments is known
  339. if (x == -sys.maxint - 1) & (y == -1):
  340. raise OverflowError("integer division")
  341. return ll_int_py_div(x, y)
  342. def ll_int_py_div_ovf_zer(x, y):
  343. if y == 0:
  344. raise ZeroDivisionError("integer division")
  345. return ll_int_py_div_ovf(x, y)
  346. @jit.oopspec("int.udiv(x, y)")
  347. def ll_uint_py_div(x, y):
  348. return llop.uint_floordiv(Unsigned, x, y)
  349. def ll_uint_py_div_zer(x, y):
  350. if y == 0:
  351. raise ZeroDivisionError("unsigned integer division")
  352. return ll_uint_py_div(x, y)
  353. if SignedLongLong == Signed:
  354. ll_llong_py_div = ll_int_py_div
  355. ll_llong_py_div_zer = ll_int_py_div_zer
  356. ll_ullong_py_div = ll_uint_py_div
  357. ll_ullong_py_div_zer = ll_uint_py_div_zer
  358. else:
  359. @jit.dont_look_inside
  360. def ll_llong_py_div(x, y):
  361. r = llop.llong_floordiv(SignedLongLong, x, y) # <= truncates like in C
  362. p = r * y
  363. if y < 0: u = p - x
  364. else: u = x - p
  365. return r + (u >> LLONG_BITS_1)
  366. def ll_llong_py_div_zer(x, y):
  367. if y == 0:
  368. raise ZeroDivisionError("longlong division")
  369. return ll_llong_py_div(x, y)
  370. @jit.dont_look_inside
  371. def ll_ullong_py_div(x, y):
  372. return llop.ullong_floordiv(UnsignedLongLong, x, y)
  373. def ll_ullong_py_div_zer(x, y):
  374. if y == 0:
  375. raise ZeroDivisionError("unsigned longlong division")
  376. return ll_ullong_py_div(x, y)
  377. @jit.dont_look_inside
  378. def ll_lllong_py_div(x, y):
  379. r = llop.lllong_floordiv(SignedLongLongLong, x, y) # <= truncates like in C
  380. p = r * y
  381. if y < 0: u = p - x
  382. else: u = x - p
  383. return r + (u >> LLLONG_BITS_1)
  384. def ll_lllong_py_div_zer(x, y):
  385. if y == 0:
  386. raise ZeroDivisionError("longlonglong division")
  387. return ll_lllong_py_div(x, y)
  388. # ---------- mod ----------
  389. @jit.oopspec("int.py_mod(x, y)")
  390. def ll_int_py_mod(x, y):
  391. r = llop.int_mod(Signed, x, y) # <= truncates like in C
  392. if y < 0: u = -r
  393. else: u = r
  394. return r + (y & (u >> INT_BITS_1))
  395. @jit.oopspec("int.py_mod(x, y)")
  396. def ll_int_py_mod_nonnegargs(x, y):
  397. from rpython.rlib.debug import ll_assert
  398. r = llop.int_mod(Signed, x, y) # <= truncates like in C
  399. ll_assert(r >= 0, "int_py_mod_nonnegargs(): one arg is negative")
  400. return r
  401. def ll_int_py_mod_zer(x, y):
  402. if y == 0:
  403. raise ZeroDivisionError
  404. return ll_int_py_mod(x, y)
  405. def ll_int_py_mod_ovf(x, y):
  406. # see comment in ll_int_py_div_ovf
  407. if (x == -sys.maxint - 1) & (y == -1):
  408. raise OverflowError
  409. return ll_int_py_mod(x, y)
  410. def ll_int_py_mod_ovf_zer(x, y):
  411. if y == 0:
  412. raise ZeroDivisionError
  413. return ll_int_py_mod_ovf(x, y)
  414. @jit.oopspec("int.umod(x, y)")
  415. def ll_uint_py_mod(x, y):
  416. return llop.uint_mod(Unsigned, x, y)
  417. def ll_uint_py_mod_zer(x, y):
  418. if y == 0:
  419. raise ZeroDivisionError
  420. return ll_uint_py_mod(x, y)
  421. if SignedLongLong == Signed:
  422. ll_llong_py_mod = ll_int_py_mod
  423. ll_llong_py_mod_zer = ll_int_py_mod_zer
  424. ll_ullong_py_mod = ll_uint_py_mod
  425. ll_ullong_py_mod_zer = ll_uint_py_mod_zer
  426. else:
  427. @jit.dont_look_inside
  428. def ll_llong_py_mod(x, y):
  429. r = llop.llong_mod(SignedLongLong, x, y) # <= truncates like in C
  430. if y < 0: u = -r
  431. else: u = r
  432. return r + (y & (u >> LLONG_BITS_1))
  433. def ll_llong_py_mod_zer(x, y):
  434. if y == 0:
  435. raise ZeroDivisionError
  436. return ll_llong_py_mod(x, y)
  437. @jit.dont_look_inside
  438. def ll_ullong_py_mod(x, y):
  439. return llop.ullong_mod(UnsignedLongLong, x, y)
  440. def ll_ullong_py_mod_zer(x, y):
  441. if y == 0:
  442. raise ZeroDivisionError
  443. return llop.ullong_mod(UnsignedLongLong, x, y)
  444. @jit.dont_look_inside
  445. def ll_lllong_py_mod(x, y):
  446. r = llop.lllong_mod(SignedLongLongLong, x, y) # <= truncates like in C
  447. if y < 0: u = -r
  448. else: u = r
  449. return r + (y & (u >> LLLONG_BITS_1))
  450. def ll_lllong_py_mod_zer(x, y):
  451. if y == 0:
  452. raise ZeroDivisionError
  453. return ll_lllong_py_mod(x, y)
  454. # ---------- lshift, neg, abs ----------
  455. def ll_int_lshift_ovf(x, y):
  456. result = x << y
  457. if (result >> y) != x:
  458. raise OverflowError("x<<y loosing bits or changing sign")
  459. return result
  460. @jit.oopspec("int.neg_ovf(x)")
  461. def ll_int_neg_ovf(x):
  462. if x == INT_MIN:
  463. raise OverflowError
  464. return -x
  465. def ll_int_abs_ovf(x):
  466. if x == INT_MIN:
  467. raise OverflowError
  468. return abs(x)
  469. #Helper functions for comparisons
  470. def _rtype_compare_template(hop, func):
  471. s_int1, s_int2 = hop.args_s
  472. if s_int1.unsigned or s_int2.unsigned:
  473. if not s_int1.nonneg or not s_int2.nonneg:
  474. raise TyperError("comparing a signed and an unsigned number")
  475. repr = hop.rtyper.getrepr(annmodel.unionof(s_int1, s_int2)).as_int
  476. vlist = hop.inputargs(repr, repr)
  477. hop.exception_is_here()
  478. return hop.genop(repr.opprefix + func, vlist, resulttype=Bool)
  479. #
  480. def ll_hash_int(n):
  481. return intmask(n)
  482. def ll_hash_long_long(n):
  483. return intmask(intmask(n) + 9 * intmask(n >> 32))
  484. def ll_eq_shortint(n, m):
  485. return intmask(n) == intmask(m)
  486. ll_eq_shortint.no_direct_compare = True
  487. def ll_check_chr(n):
  488. if 0 <= n <= 255:
  489. return
  490. else:
  491. raise ValueError
  492. def ll_check_unichr(n):
  493. from rpython.rlib.runicode import MAXUNICODE
  494. if 0 <= n <= MAXUNICODE:
  495. return
  496. else:
  497. raise ValueError
  498. #
  499. # _________________________ Conversions _________________________
  500. class __extend__(pairtype(IntegerRepr, FloatRepr)):
  501. def convert_from_to((r_from, r_to), v, llops):
  502. if r_from.lowleveltype == Unsigned and r_to.lowleveltype == Float:
  503. log.debug('explicit cast_uint_to_float')
  504. return llops.genop('cast_uint_to_float', [v], resulttype=Float)
  505. if r_from.lowleveltype == Signed and r_to.lowleveltype == Float:
  506. log.debug('explicit cast_int_to_float')
  507. return llops.genop('cast_int_to_float', [v], resulttype=Float)
  508. if r_from.lowleveltype == SignedLongLong and r_to.lowleveltype == Float:
  509. log.debug('explicit cast_longlong_to_float')
  510. return llops.genop('cast_longlong_to_float', [v], resulttype=Float)
  511. if r_from.lowleveltype == UnsignedLongLong and r_to.lowleveltype == Float:
  512. log.debug('explicit cast_ulonglong_to_float')
  513. return llops.genop('cast_ulonglong_to_float', [v], resulttype=Float)
  514. return NotImplemented
  515. class __extend__(pairtype(FloatRepr, IntegerRepr)):
  516. def convert_from_to((r_from, r_to), v, llops):
  517. if r_from.lowleveltype == Float and r_to.lowleveltype == Unsigned:
  518. log.debug('explicit cast_float_to_uint')
  519. return llops.genop('cast_float_to_uint', [v], resulttype=Unsigned)
  520. if r_from.lowleveltype == Float and r_to.lowleveltype == Signed:
  521. log.debug('explicit cast_float_to_int')
  522. return llops.genop('cast_float_to_int', [v], resulttype=Signed)
  523. if r_from.lowleveltype == Float and r_to.lowleveltype == SignedLongLong:
  524. log.debug('explicit cast_float_to_longlong')
  525. return llops.genop('cast_float_to_longlong', [v], resulttype=SignedLongLong)
  526. if r_from.lowleveltype == Float and r_to.lowleveltype == UnsignedLongLong:
  527. log.debug('explicit cast_float_to_ulonglong')
  528. return llops.genop('cast_float_to_ulonglong', [v], resulttype=UnsignedLongLong)
  529. return NotImplemented