2 * UniCore32 helper routines
4 * Copyright (C) 2010-2011 GUAN Xue-tao
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include "dyngen-exec.h"
14 #define SIGNBIT (uint32_t)0x80000000
15 #define SIGNBIT64 ((uint64_t)1 << 63)
17 void HELPER(exception
)(uint32_t excp
)
19 env
->exception_index
= excp
;
23 static target_ulong
asr_read(void)
27 return env
->uncached_asr
| (env
->NF
& 0x80000000) | (ZF
<< 30) |
28 (env
->CF
<< 29) | ((env
->VF
& 0x80000000) >> 3);
31 target_ulong
cpu_asr_read(CPUState
*env1
)
43 target_ulong
HELPER(asr_read
)(void)
48 static void asr_write(target_ulong val
, target_ulong mask
)
50 if (mask
& ASR_NZCV
) {
51 env
->ZF
= (~val
) & ASR_Z
;
53 env
->CF
= (val
>> 29) & 1;
54 env
->VF
= (val
<< 3) & 0x80000000;
57 if ((env
->uncached_asr
^ val
) & mask
& ASR_M
) {
58 switch_mode(env
, val
& ASR_M
);
61 env
->uncached_asr
= (env
->uncached_asr
& ~mask
) | (val
& mask
);
64 void cpu_asr_write(CPUState
*env1
, target_ulong val
, target_ulong mask
)
74 void HELPER(asr_write
)(target_ulong val
, target_ulong mask
)
79 /* Access to user mode registers from privileged modes. */
80 uint32_t HELPER(get_user_reg
)(uint32_t regno
)
85 val
= env
->banked_r29
[0];
86 } else if (regno
== 30) {
87 val
= env
->banked_r30
[0];
89 val
= env
->regs
[regno
];
94 void HELPER(set_user_reg
)(uint32_t regno
, uint32_t val
)
97 env
->banked_r29
[0] = val
;
98 } else if (regno
== 30) {
99 env
->banked_r30
[0] = val
;
101 env
->regs
[regno
] = val
;
105 /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
106 The only way to do that in TCG is a conditional branch, which clobbers
107 all our temporaries. For now implement these as helper functions. */
109 uint32_t HELPER(add_cc
)(uint32_t a
, uint32_t b
)
113 env
->NF
= env
->ZF
= result
;
114 env
->CF
= result
< a
;
115 env
->VF
= (a
^ b
^ -1) & (a
^ result
);
119 uint32_t HELPER(adc_cc
)(uint32_t a
, uint32_t b
)
124 env
->CF
= result
< a
;
127 env
->CF
= result
<= a
;
129 env
->VF
= (a
^ b
^ -1) & (a
^ result
);
130 env
->NF
= env
->ZF
= result
;
134 uint32_t HELPER(sub_cc
)(uint32_t a
, uint32_t b
)
138 env
->NF
= env
->ZF
= result
;
140 env
->VF
= (a
^ b
) & (a
^ result
);
144 uint32_t HELPER(sbc_cc
)(uint32_t a
, uint32_t b
)
154 env
->VF
= (a
^ b
) & (a
^ result
);
155 env
->NF
= env
->ZF
= result
;
159 /* Similarly for variable shift instructions. */
161 uint32_t HELPER(shl
)(uint32_t x
, uint32_t i
)
163 int shift
= i
& 0xff;
170 uint32_t HELPER(shr
)(uint32_t x
, uint32_t i
)
172 int shift
= i
& 0xff;
176 return (uint32_t)x
>> shift
;
179 uint32_t HELPER(sar
)(uint32_t x
, uint32_t i
)
181 int shift
= i
& 0xff;
185 return (int32_t)x
>> shift
;
188 uint32_t HELPER(shl_cc
)(uint32_t x
, uint32_t i
)
190 int shift
= i
& 0xff;
198 } else if (shift
!= 0) {
199 env
->CF
= (x
>> (32 - shift
)) & 1;
205 uint32_t HELPER(shr_cc
)(uint32_t x
, uint32_t i
)
207 int shift
= i
& 0xff;
210 env
->CF
= (x
>> 31) & 1;
215 } else if (shift
!= 0) {
216 env
->CF
= (x
>> (shift
- 1)) & 1;
222 uint32_t HELPER(sar_cc
)(uint32_t x
, uint32_t i
)
224 int shift
= i
& 0xff;
226 env
->CF
= (x
>> 31) & 1;
227 return (int32_t)x
>> 31;
228 } else if (shift
!= 0) {
229 env
->CF
= (x
>> (shift
- 1)) & 1;
230 return (int32_t)x
>> shift
;
235 uint32_t HELPER(ror_cc
)(uint32_t x
, uint32_t i
)
239 shift
= shift1
& 0x1f;
242 env
->CF
= (x
>> 31) & 1;
246 env
->CF
= (x
>> (shift
- 1)) & 1;
247 return ((uint32_t)x
>> shift
) | (x
<< (32 - shift
));