blob: c940ce1ac3150b47948491c953fc958354533ce1 [file] [log] [blame]
Paul Sokolovsky966879c2014-01-17 20:01:36 +02001#include <stdlib.h>
2#include <stdint.h>
3#include <string.h>
4#include <assert.h>
5
6#include "nlr.h"
7#include "misc.h"
8#include "mpconfig.h"
9#include "mpqstr.h"
10#include "obj.h"
11#include "objint.h"
12#include "runtime0.h"
13
14#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
15
16static mp_obj_t mp_obj_new_int_from_ll(long long val);
17
18// Python3 no longer has "l" suffix for long ints. We allow to use it
19// for debugging purpose though.
20#ifdef DEBUG
21#define SUFFIX "l"
22#else
23#define SUFFIX ""
24#endif
25
26void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
27 mp_obj_int_t *self = self_in;
28 print(env, "%lld" SUFFIX, self->val);
29}
30
31mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
32 mp_obj_int_t *lhs = lhs_in;
33 mp_obj_int_t *rhs = rhs_in;
34 long long rhs_val;
35
36 if (MP_OBJ_IS_SMALL_INT(rhs)) {
37 rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
38 } else if (MP_OBJ_IS_TYPE(rhs, &int_type)) {
39 rhs_val = rhs->val;
40 } else {
41 return MP_OBJ_NULL;
42 }
43
44 switch (op) {
45 case RT_BINARY_OP_ADD:
46 return mp_obj_new_int_from_ll(lhs->val + rhs_val);
47 case RT_BINARY_OP_SUBTRACT:
48 return mp_obj_new_int_from_ll(lhs->val - rhs_val);
49
50 case RT_BINARY_OP_INPLACE_ADD:
51 lhs->val += rhs_val;
52 return lhs;
53 case RT_BINARY_OP_INPLACE_SUBTRACT:
54 lhs->val -= rhs_val;
55 return lhs;
56
57 case RT_BINARY_OP_AND:
58 return mp_obj_new_int_from_ll(lhs->val & rhs_val);
59 case RT_BINARY_OP_OR:
60 return mp_obj_new_int_from_ll(lhs->val | rhs_val);
61 case RT_BINARY_OP_XOR:
62 return mp_obj_new_int_from_ll(lhs->val ^ rhs_val);
63
64 case RT_BINARY_OP_LSHIFT:
65 return mp_obj_new_int_from_ll(lhs->val << (int)rhs_val);
66 case RT_BINARY_OP_RSHIFT:
67 return mp_obj_new_int_from_ll(lhs->val >> (int)rhs_val);
68
69 case RT_COMPARE_OP_LESS:
70 return MP_BOOL(lhs->val < rhs_val);
71 case RT_COMPARE_OP_MORE:
72 return MP_BOOL(lhs->val > rhs_val);
73 case RT_COMPARE_OP_LESS_EQUAL:
74 return MP_BOOL(lhs->val <= rhs_val);
75 case RT_COMPARE_OP_MORE_EQUAL:
76 return MP_BOOL(lhs->val >= rhs_val);
77 case RT_COMPARE_OP_EQUAL:
78 return MP_BOOL(lhs->val == rhs_val);
79 case RT_COMPARE_OP_NOT_EQUAL:
80 return MP_BOOL(lhs->val != rhs_val);
81
82 default:
83 // op not supported
84 return MP_OBJ_NULL;
85 }
86}
87
88mp_obj_t mp_obj_new_int(machine_int_t value) {
89 if (MP_OBJ_FITS_SMALL_INT(value)) {
90 return MP_OBJ_NEW_SMALL_INT(value);
91 }
92 return mp_obj_new_int_from_ll(value);
93}
94
95mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
96 // SMALL_INT accepts only signed numbers, of one bit less size
97 // than word size, which totals 2 bits less for unsigned numbers.
98 if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
99 return MP_OBJ_NEW_SMALL_INT(value);
100 }
101 return mp_obj_new_int_from_ll(value);
102}
103
104mp_obj_t mp_obj_new_int_from_ll(long long val) {
105 mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
106 o->base.type = &int_type;
107 o->val = val;
108 return o;
109}
110
111mp_obj_t mp_obj_new_int_from_long_str(const char *s) {
112 long long v;
113 char *end;
114 // TODO: this doesn't handle Python hacked 0o octal syntax
115 v = strtoll(s, &end, 0);
116 assert(*end == 0);
117 mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
118 o->base.type = &int_type;
119 o->val = v;
120 return o;
121}
122
123machine_int_t mp_obj_int_get_int(mp_obj_t self_in) {
124 mp_obj_int_t *self = self_in;
125 return self->val;
126}
127
128#endif