35
35
#include "tcc.h"
36
36
#include <assert.h>
37
37
38
+ #define UPPER (x ) (((unsigned)(x) + 0x800u) & 0xfffff000)
39
+ #define SIGN7 (x ) ((((x) & 0xff) ^ 0x80) - 0x80)
40
+ #define SIGN11 (x ) ((((x) & 0xfff) ^ 0x800) - 0x800)
41
+
38
42
ST_DATA const char * const target_machine_defs =
39
43
"__riscv\0"
40
44
"__riscv_xlen 64\0"
@@ -163,7 +167,7 @@ ST_FUNC void gsym_addr(int t_, int a_)
163
167
}
164
168
}
165
169
166
- static int load_symofs (int r , SValue * sv , int forstore )
170
+ static int load_symofs (int r , SValue * sv , int forstore , int * new_fc )
167
171
{
168
172
int rr , doload = 0 , large_addend = 0 ;
169
173
int fc = sv -> c .i , v = sv -> r & VT_VALMASK ;
@@ -173,7 +177,7 @@ static int load_symofs(int r, SValue *sv, int forstore)
173
177
if (sv -> sym -> type .t & VT_STATIC ) { // XXX do this per linker relax
174
178
greloca (cur_text_section , sv -> sym , ind ,
175
179
R_RISCV_PCREL_HI20 , sv -> c .i );
176
- sv -> c . i = 0 ;
180
+ * new_fc = 0 ;
177
181
} else {
178
182
if (((unsigned )fc + (1 << 11 )) >> 12 ){
179
183
large_addend = 1 ;
@@ -193,9 +197,9 @@ static int load_symofs(int r, SValue *sv, int forstore)
193
197
if (doload ) {
194
198
EI (0x03 , 3 , rr , rr , 0 ); // ld RR, 0(RR)
195
199
if (large_addend ) {
196
- o (0x37 | (6 << 7 ) | (( 0x800 + fc ) & 0xfffff000 )); //lui t1, high(fc)
200
+ o (0x37 | (6 << 7 ) | UPPER ( fc )); //lui t1, high(fc)
197
201
ER (0x33 , 0 , rr , rr , 6 , 0 ); // add RR, RR, t1
198
- sv -> c . i = fc << 20 >> 20 ;
202
+ * new_fc = SIGN11 ( fc ) ;
199
203
}
200
204
}
201
205
} else if (v == VT_LOCAL || v == VT_LLOCAL ) {
@@ -204,9 +208,9 @@ static int load_symofs(int r, SValue *sv, int forstore)
204
208
tcc_error ("unimp: store(giant local off) (0x%lx)" , (long )sv -> c .i );
205
209
if (((unsigned )fc + (1 << 11 )) >> 12 ) {
206
210
rr = is_ireg (r ) ? ireg (r ) : 5 ; // t0
207
- o (0x37 | (rr << 7 ) | (( 0x800 + fc ) & 0xfffff000 )); //lui RR, upper(fc)
211
+ o (0x37 | (rr << 7 ) | UPPER ( fc )); //lui RR, upper(fc)
208
212
ER (0x33 , 0 , rr , rr , 8 , 0 ); // add RR, RR, s0
209
- sv -> c . i = fc << 20 >> 20 ;
213
+ * new_fc = SIGN11 ( fc ) ;
210
214
}
211
215
} else
212
216
tcc_error ("uhh" );
@@ -217,13 +221,12 @@ static void load_large_constant(int rr, int fc, uint32_t pi)
217
221
{
218
222
if (fc < 0 )
219
223
pi ++ ;
220
- o (0x37 | (rr << 7 ) | ((( pi + 0x800 ) & 0xfffff000 ) )); // lui RR, up(up(fc))
221
- EI (0x13 , 0 , rr , rr , ( int ) pi << 20 >> 20 ); // addi RR, RR, lo(up(fc))
224
+ o (0x37 | (rr << 7 ) | UPPER ( pi )); // lui RR, up(up(fc))
225
+ EI (0x13 , 0 , rr , rr , SIGN11 ( pi ) ); // addi RR, RR, lo(up(fc))
222
226
EI (0x13 , 1 , rr , rr , 12 ); // slli RR, RR, 12
223
- EI (0x13 , 0 , rr , rr , ( fc + (1 << 19 )) >> 20 ); // addi RR, RR, up(lo(fc))
227
+ EI (0x13 , 0 , rr , rr , SIGN11 ((( unsigned ) fc + (1 << 19 )) >> 20 )); // addi RR, RR, up(lo(fc))
224
228
EI (0x13 , 1 , rr , rr , 12 ); // slli RR, RR, 12
225
- fc = (fc + (1 << 7 )) << 12 >> 12 ;
226
- EI (0x13 , 0 , rr , rr , fc >> 8 ); // addi RR, RR, lo1(lo(fc))
229
+ EI (0x13 , 0 , rr , rr , SIGN11 (((unsigned )fc + (1 << 7 )) >> 8 )); // addi RR, RR, lo1(lo(fc))
227
230
EI (0x13 , 1 , rr , rr , 8 ); // slli RR, RR, 8
228
231
}
229
232
@@ -233,7 +236,6 @@ ST_FUNC void load(int r, SValue *sv)
233
236
int v = fr & VT_VALMASK ;
234
237
int rr = is_ireg (r ) ? ireg (r ) : freg (r );
235
238
int fc = sv -> c .i ;
236
- uint64_t save_fc = sv -> c .i ;
237
239
int bt = sv -> type .t & VT_BTYPE ;
238
240
int align , size ;
239
241
if (fr & VT_LVAL ) {
@@ -246,16 +248,14 @@ ST_FUNC void load(int r, SValue *sv)
246
248
if (size < 4 && !is_float (sv -> type .t ) && (sv -> type .t & VT_UNSIGNED ))
247
249
func3 |= 4 ;
248
250
if (v == VT_LOCAL || (fr & VT_SYM )) {
249
- br = load_symofs (r , sv , 0 );
250
- fc = sv -> c .i ;
251
+ br = load_symofs (r , sv , 0 , & fc );
251
252
} else if (v < VT_CONST ) {
252
253
br = ireg (v );
253
254
/*if (((unsigned)fc + (1 << 11)) >> 12)
254
255
tcc_error("unimp: load(large addend) (0x%x)", fc);*/
255
256
fc = 0 ; // XXX store ofs in LVAL(reg)
256
257
} else if (v == VT_LLOCAL ) {
257
- br = load_symofs (r , sv , 0 );
258
- fc = sv -> c .i ;
258
+ br = load_symofs (r , sv , 0 , & fc );
259
259
EI (0x03 , 3 , rr , br , fc ); // ld RR, fc(BR)
260
260
br = rr ;
261
261
fc = 0 ;
@@ -264,10 +264,10 @@ ST_FUNC void load(int r, SValue *sv)
264
264
si >>= 32 ;
265
265
if (si != 0 ) {
266
266
load_large_constant (rr , fc , si );
267
- fc = fc << 24 >> 24 ;
267
+ fc = SIGN7 ( fc ) ;
268
268
} else {
269
- o (0x37 | (rr << 7 ) | (( 0x800 + fc ) & 0xfffff000 )); //lui RR, upper(fc)
270
- fc = fc << 20 >> 20 ;
269
+ o (0x37 | (rr << 7 ) | UPPER ( fc )); //lui RR, upper(fc)
270
+ fc = SIGN11 ( fc ) ;
271
271
}
272
272
br = rr ;
273
273
} else {
@@ -278,18 +278,17 @@ ST_FUNC void load(int r, SValue *sv)
278
278
int rb = 0 , do32bit = 8 , zext = 0 ;
279
279
assert ((!is_float (sv -> type .t ) && is_ireg (r )) || bt == VT_LDOUBLE );
280
280
if (fr & VT_SYM ) {
281
- rb = load_symofs (r , sv , 0 );
282
- fc = sv -> c .i ;
281
+ rb = load_symofs (r , sv , 0 , & fc );
283
282
do32bit = 0 ;
284
283
}
285
284
if (is_float (sv -> type .t ) && bt != VT_LDOUBLE )
286
285
tcc_error ("unimp: load(float)" );
287
- if (fc != sv -> c .i ) {
286
+ if (do32bit && fc != sv -> c .i ) {
288
287
int64_t si = sv -> c .i ;
289
288
si >>= 32 ;
290
289
if (si != 0 ) {
291
290
load_large_constant (rr , fc , si );
292
- fc = fc << 24 >> 24 ;
291
+ fc = SIGN7 ( fc ) ;
293
292
rb = rr ;
294
293
do32bit = 0 ;
295
294
} else if (bt == VT_LLONG ) {
@@ -299,17 +298,16 @@ ST_FUNC void load(int r, SValue *sv)
299
298
}
300
299
}
301
300
if (((unsigned )fc + (1 << 11 )) >> 12 )
302
- o (0x37 | (rr << 7 ) | (( 0x800 + fc ) & 0xfffff000 )), rb = rr ; //lui RR, upper(fc)
301
+ o (0x37 | (rr << 7 ) | UPPER ( fc )), rb = rr ; //lui RR, upper(fc)
303
302
if (fc || (rr != rb ) || do32bit || (fr & VT_SYM ))
304
- EI (0x13 | do32bit , 0 , rr , rb , fc << 20 >> 20 ); // addi[w] R, x0|R, FC
303
+ EI (0x13 | do32bit , 0 , rr , rb , SIGN11 ( fc ) ); // addi[w] R, x0|R, FC
305
304
if (zext ) {
306
305
EI (0x13 , 1 , rr , rr , 32 ); // slli RR, RR, 32
307
306
EI (0x13 , 5 , rr , rr , 32 ); // srli RR, RR, 32
308
307
}
309
308
} else if (v == VT_LOCAL ) {
310
- int br = load_symofs (r , sv , 0 );
309
+ int br = load_symofs (r , sv , 0 , & fc );
311
310
assert (is_ireg (r ));
312
- fc = sv -> c .i ;
313
311
EI (0x13 , 0 , rr , br , fc ); // addi R, s0, FC
314
312
} else if (v < VT_CONST ) { /* reg-reg */
315
313
//assert(!fc); XXX support offseted regs
@@ -324,7 +322,7 @@ ST_FUNC void load(int r, SValue *sv)
324
322
func7 |= 1 ;
325
323
assert (size == 4 || size == 8 );
326
324
o (0x53 | (rr << 7 ) | ((is_freg (v ) ? freg (v ) : ireg (v )) << 15 )
327
- | (func7 << 25 )); // fmv.{w.x, x.w, d.x, x.d} RR, VR
325
+ | (( unsigned ) func7 << 25 )); // fmv.{w.x, x.w, d.x, x.d} RR, VR
328
326
}
329
327
} else if (v == VT_CMP ) {
330
328
int op = vtop -> cmp_op ;
@@ -371,15 +369,13 @@ ST_FUNC void load(int r, SValue *sv)
371
369
EI (0x13 , 0 , rr , 0 , t ^ 1 ); // addi RR, x0, !t
372
370
} else
373
371
tcc_error ("unimp: load(non-const)" );
374
- sv -> c .i = save_fc ;
375
372
}
376
373
377
374
ST_FUNC void store (int r , SValue * sv )
378
375
{
379
376
int fr = sv -> r & VT_VALMASK ;
380
377
int rr = is_ireg (r ) ? ireg (r ) : freg (r ), ptrreg ;
381
378
int fc = sv -> c .i ;
382
- uint64_t save_fc = sv -> c .i ;
383
379
int bt = sv -> type .t & VT_BTYPE ;
384
380
int align , size = type_size (& sv -> type , & align );
385
381
assert (!is_float (bt ) || is_freg (r ) || bt == VT_LDOUBLE );
@@ -393,8 +389,7 @@ ST_FUNC void store(int r, SValue *sv)
393
389
tcc_error ("unimp: large sized store" );
394
390
assert (sv -> r & VT_LVAL );
395
391
if (fr == VT_LOCAL || (sv -> r & VT_SYM )) {
396
- ptrreg = load_symofs (-1 , sv , 1 );
397
- fc = sv -> c .i ;
392
+ ptrreg = load_symofs (-1 , sv , 1 , & fc );
398
393
} else if (fr < VT_CONST ) {
399
394
ptrreg = ireg (fr );
400
395
/*if (((unsigned)fc + (1 << 11)) >> 12)
@@ -406,17 +401,16 @@ ST_FUNC void store(int r, SValue *sv)
406
401
si >>= 32 ;
407
402
if (si != 0 ) {
408
403
load_large_constant (ptrreg , fc , si );
409
- fc = fc << 24 >> 24 ;
404
+ fc = SIGN7 ( fc ) ;
410
405
} else {
411
- o (0x37 | (ptrreg << 7 ) | (( 0x800 + fc ) & 0xfffff000 )); //lui RR, upper(fc)
412
- fc = fc << 20 >> 20 ;
406
+ o (0x37 | (ptrreg << 7 ) | UPPER ( fc )); //lui RR, upper(fc)
407
+ fc = SIGN11 ( fc ) ;
413
408
}
414
409
} else
415
410
tcc_error ("implement me: %s(!local)" , __FUNCTION__ );
416
411
ES (is_freg (r ) ? 0x27 : 0x23 , // fs... | s...
417
412
size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3 , // ... [wd] | [bhwd]
418
413
ptrreg , rr , fc ); // RR, fc(base)
419
- sv -> c .i = save_fc ;
420
414
}
421
415
422
416
static void gcall_or_jmp (int docall )
@@ -634,11 +628,8 @@ ST_FUNC void gfunc_call(int nb_args)
634
628
635
629
if (stack_add ) {
636
630
if (stack_add >= 0x800 ) {
637
- unsigned int bit11 = (((unsigned int )- stack_add ) >> 11 ) & 1 ;
638
- o (0x37 | (5 << 7 ) |
639
- ((- stack_add + (bit11 << 12 )) & 0xfffff000 )); //lui t0, upper(v)
640
- EI (0x13 , 0 , 5 , 5 , ((- stack_add & 0xfff ) - bit11 * (1 << 12 )));
641
- // addi t0, t0, lo(v)
631
+ o (0x37 | (5 << 7 ) | UPPER (- stack_add )); //lui t0, upper(v)
632
+ EI (0x13 , 0 , 5 , 5 , SIGN11 (- stack_add )); // addi t0, t0, lo(v)
642
633
ER (0x33 , 0 , 2 , 2 , 5 , 0 ); // add sp, sp, t0
643
634
}
644
635
else
@@ -766,11 +757,8 @@ ST_FUNC void gfunc_call(int nb_args)
766
757
vtop -= nb_args + 1 ;
767
758
if (stack_add ) {
768
759
if (stack_add >= 0x800 ) {
769
- unsigned int bit11 = ((unsigned int )stack_add >> 11 ) & 1 ;
770
- o (0x37 | (5 << 7 ) |
771
- ((stack_add + (bit11 << 12 )) & 0xfffff000 )); //lui t0, upper(v)
772
- EI (0x13 , 0 , 5 , 5 , (stack_add & 0xfff ) - bit11 * (1 << 12 ));
773
- // addi t0, t0, lo(v)
760
+ o (0x37 | (5 << 7 ) | UPPER (stack_add )); //lui t0, upper(v)
761
+ EI (0x13 , 0 , 5 , 5 , SIGN11 (stack_add )); // addi t0, t0, lo(v)
774
762
ER (0x33 , 0 , 2 , 2 , 5 , 0 ); // add sp, sp, t0
775
763
}
776
764
else
@@ -911,8 +899,8 @@ ST_FUNC void gfunc_epilog(void)
911
899
912
900
if (v >= (1 << 11 )) {
913
901
d = 16 ;
914
- o (0x37 | (5 << 7 ) | (( 0x800 + ( v - 16 )) & 0xfffff000 )); //lui t0, upper(v)
915
- EI (0x13 , 0 , 5 , 5 , (v - 16 ) << 20 >> 20 ); // addi t0, t0, lo(v)
902
+ o (0x37 | (5 << 7 ) | UPPER ( v - 16 )); //lui t0, upper(v)
903
+ EI (0x13 , 0 , 5 , 5 , SIGN11 (v - 16 )); // addi t0, t0, lo(v)
916
904
ER (0x33 , 0 , 2 , 2 , 5 , 0 ); // add sp, sp, t0
917
905
}
918
906
EI (0x03 , 3 , 1 , 2 , d - 8 - num_va_regs * 8 ); // ld ra, v-8(sp)
@@ -922,8 +910,8 @@ ST_FUNC void gfunc_epilog(void)
922
910
large_ofs_ind = ind ;
923
911
if (v >= (1 << 11 )) {
924
912
EI (0x13 , 0 , 8 , 2 , d - num_va_regs * 8 ); // addi s0, sp, d
925
- o (0x37 | (5 << 7 ) | (( 0x800 + ( v - 16 )) & 0xfffff000 )); //lui t0, upper(v)
926
- EI (0x13 , 0 , 5 , 5 , (v - 16 ) << 20 >> 20 ); // addi t0, t0, lo(v)
913
+ o (0x37 | (5 << 7 ) | UPPER ( v - 16 )); //lui t0, upper(v)
914
+ EI (0x13 , 0 , 5 , 5 , SIGN11 (v - 16 )); // addi t0, t0, lo(v)
927
915
ER (0x33 , 0 , 2 , 2 , 5 , 0x20 ); // sub sp, sp, t0
928
916
gjmp_addr (func_sub_sp_offset + 5 * 4 );
929
917
}
@@ -972,8 +960,8 @@ ST_FUNC void gjmp_addr(int a)
972
960
{
973
961
uint32_t r = a - ind , imm ;
974
962
if ((r + (1 << 21 )) & ~((1U << 22 ) - 2 )) {
975
- o (0x17 | (5 << 7 ) | ((( r + 0x800 ) & 0xfffff000 ) )); // lui RR, up(r)
976
- r = ( int ) r << 20 >> 20 ;
963
+ o (0x17 | (5 << 7 ) | UPPER ( r )); // lui RR, up(r)
964
+ r = SIGN11 ( r ) ;
977
965
EI (0x67 , 0 , 0 , 5 , r ); // jalr x0, r(t0)
978
966
} else {
979
967
imm = (((r >> 12 ) & 0xff ) << 12 )
@@ -1394,9 +1382,9 @@ ST_FUNC void ggoto(void)
1394
1382
ST_FUNC void gen_vla_sp_save (int addr )
1395
1383
{
1396
1384
if (((unsigned )addr + (1 << 11 )) >> 12 ) {
1397
- o (0x37 | (5 << 7 ) | (( 0x800 + addr ) & 0xfffff000 )); //lui t0,upper(addr)
1385
+ o (0x37 | (5 << 7 ) | UPPER ( addr )); //lui t0,upper(addr)
1398
1386
ER (0x33 , 0 , 5 , 5 , 8 , 0 ); // add t0, t0, s0
1399
- ES (0x23 , 3 , 5 , 2 , ( int ) addr << 20 >> 20 ); // sd sp, fc(t0)
1387
+ ES (0x23 , 3 , 5 , 2 , SIGN11 ( addr ) ); // sd sp, fc(t0)
1400
1388
}
1401
1389
else
1402
1390
ES (0x23 , 3 , 8 , 2 , addr ); // sd sp, fc(s0)
@@ -1405,9 +1393,9 @@ ST_FUNC void gen_vla_sp_save(int addr)
1405
1393
ST_FUNC void gen_vla_sp_restore (int addr )
1406
1394
{
1407
1395
if (((unsigned )addr + (1 << 11 )) >> 12 ) {
1408
- o (0x37 | (5 << 7 ) | (( 0x800 + addr ) & 0xfffff000 )); //lui t0,upper(addr)
1396
+ o (0x37 | (5 << 7 ) | UPPER ( addr )); //lui t0,upper(addr)
1409
1397
ER (0x33 , 0 , 5 , 5 , 8 , 0 ); // add t0, t0, s0
1410
- EI (0x03 , 3 , 2 , 5 , ( int ) addr << 20 >> 20 ); // ld sp, fc(t0)
1398
+ EI (0x03 , 3 , 2 , 5 , SIGN11 ( addr ) ); // ld sp, fc(t0)
1411
1399
}
1412
1400
else
1413
1401
EI (0x03 , 3 , 2 , 8 , addr ); // ld sp, fc(s0)
0 commit comments