1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
|
GHC supplied all of the information necessary for a registerised build on riscv using LLVM codegen in 9.2.
Andreas Schwab backported this to 8.10.7 in OpenSUSE: https://build.opensuse.org/package/show/openSUSE:Factory:RISCV/ghc
This is a forward-port of the backport to 9.0.
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs
index 23175a1cd2..3f77573495 100644
--- a/compiler/GHC/CmmToAsm.hs
+++ b/compiler/GHC/CmmToAsm.hs
@@ -182,6 +182,7 @@ nativeCodeGen dflags this_mod modLoc h us cmms
ArchAlpha -> panic "nativeCodeGen: No NCG for Alpha"
ArchMipseb -> panic "nativeCodeGen: No NCG for mipseb"
ArchMipsel -> panic "nativeCodeGen: No NCG for mipsel"
+ ArchRISCV64 -> panic "nativeCodeGen: No NCG for RISCV64"
ArchUnknown -> panic "nativeCodeGen: No NCG for unknown arch"
ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript"
diff --git a/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs b/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
index 105e2ebdf9..07eca93ac3 100644
--- a/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs
@@ -120,6 +120,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcInteger conflicts excl
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
+ ArchRISCV64 -> panic "trivColorable ArchRISCV64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_INTEGER
@@ -151,6 +152,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcFloat conflicts exclus
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
+ ArchRISCV64 -> panic "trivColorable ArchRISCV64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_FLOAT
@@ -184,6 +186,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcDouble conflicts exclu
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
+ ArchRISCV64 -> panic "trivColorable ArchRISCV64"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_DOUBLE
diff --git a/compiler/GHC/CmmToAsm/Reg/Linear.hs b/compiler/GHC/CmmToAsm/Reg/Linear.hs
index 1ab353cc34..d8228c69cd 100644
--- a/compiler/GHC/CmmToAsm/Reg/Linear.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Linear.hs
@@ -225,6 +225,7 @@ linearRegAlloc config entry_ids block_live sccs
ArchAlpha -> panic "linearRegAlloc ArchAlpha"
ArchMipseb -> panic "linearRegAlloc ArchMipseb"
ArchMipsel -> panic "linearRegAlloc ArchMipsel"
+ ArchRISCV64 -> panic "linearRegAlloc ArchRISCV64"
ArchJavaScript -> panic "linearRegAlloc ArchJavaScript"
ArchUnknown -> panic "linearRegAlloc ArchUnknown"
where
diff --git a/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs b/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
index b89c056a82..1768422f5c 100644
--- a/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
@@ -83,5 +83,6 @@ maxSpillSlots config = case platformArch (ncgPlatform config) of
ArchAlpha -> panic "maxSpillSlots ArchAlpha"
ArchMipseb -> panic "maxSpillSlots ArchMipseb"
ArchMipsel -> panic "maxSpillSlots ArchMipsel"
+ ArchRISCV64 -> panic "maxSpillSlots ArchRISCV64"
ArchJavaScript-> panic "maxSpillSlots ArchJavaScript"
ArchUnknown -> panic "maxSpillSlots ArchUnknown"
diff --git a/compiler/GHC/CmmToAsm/Reg/Target.hs b/compiler/GHC/CmmToAsm/Reg/Target.hs
index ba249801ba..284df45983 100644
--- a/compiler/GHC/CmmToAsm/Reg/Target.hs
+++ b/compiler/GHC/CmmToAsm/Reg/Target.hs
@@ -51,6 +51,7 @@ targetVirtualRegSqueeze platform
ArchAlpha -> panic "targetVirtualRegSqueeze ArchAlpha"
ArchMipseb -> panic "targetVirtualRegSqueeze ArchMipseb"
ArchMipsel -> panic "targetVirtualRegSqueeze ArchMipsel"
+ ArchRISCV64 -> panic "targetVirtualRegSqueeze ArchRISCV64"
ArchJavaScript-> panic "targetVirtualRegSqueeze ArchJavaScript"
ArchUnknown -> panic "targetVirtualRegSqueeze ArchUnknown"
@@ -70,6 +71,7 @@ targetRealRegSqueeze platform
ArchAlpha -> panic "targetRealRegSqueeze ArchAlpha"
ArchMipseb -> panic "targetRealRegSqueeze ArchMipseb"
ArchMipsel -> panic "targetRealRegSqueeze ArchMipsel"
+ ArchRISCV64 -> panic "targetRealRegSqueeze ArchRISCV64"
ArchJavaScript-> panic "targetRealRegSqueeze ArchJavaScript"
ArchUnknown -> panic "targetRealRegSqueeze ArchUnknown"
@@ -88,6 +90,7 @@ targetClassOfRealReg platform
ArchAlpha -> panic "targetClassOfRealReg ArchAlpha"
ArchMipseb -> panic "targetClassOfRealReg ArchMipseb"
ArchMipsel -> panic "targetClassOfRealReg ArchMipsel"
+ ArchRISCV64 -> panic "targetClassOfRealReg ArchRISCV64"
ArchJavaScript-> panic "targetClassOfRealReg ArchJavaScript"
ArchUnknown -> panic "targetClassOfRealReg ArchUnknown"
@@ -106,6 +109,7 @@ targetMkVirtualReg platform
ArchAlpha -> panic "targetMkVirtualReg ArchAlpha"
ArchMipseb -> panic "targetMkVirtualReg ArchMipseb"
ArchMipsel -> panic "targetMkVirtualReg ArchMipsel"
+ ArchRISCV64 -> panic "targetMkVirtualReg ArchRISCV64"
ArchJavaScript-> panic "targetMkVirtualReg ArchJavaScript"
ArchUnknown -> panic "targetMkVirtualReg ArchUnknown"
@@ -124,6 +128,7 @@ targetRegDotColor platform
ArchAlpha -> panic "targetRegDotColor ArchAlpha"
ArchMipseb -> panic "targetRegDotColor ArchMipseb"
ArchMipsel -> panic "targetRegDotColor ArchMipsel"
+ ArchRISCV64 -> panic "targetRegDotColor ArchRISCV64"
ArchJavaScript-> panic "targetRegDotColor ArchJavaScript"
ArchUnknown -> panic "targetRegDotColor ArchUnknown"
diff --git a/compiler/GHC/CmmToLlvm/Mangler.hs b/compiler/GHC/CmmToLlvm/Mangler.hs
index 0436dbcf07..5c71655ab3 100644
--- a/compiler/GHC/CmmToLlvm/Mangler.hs
+++ b/compiler/GHC/CmmToLlvm/Mangler.hs
@@ -42,7 +42,7 @@ llvmFixupAsm dflags f1 f2 = {-# SCC "llvm_mangler" #-}
-- | These are the rewrites that the mangler will perform
rewrites :: [Rewrite]
-rewrites = [rewriteSymType, rewriteAVX]
+rewrites = [rewriteSymType, rewriteAVX, rewriteCall]
type Rewrite = DynFlags -> B.ByteString -> Maybe B.ByteString
@@ -106,6 +106,27 @@ rewriteAVX dflags s
isVmovdqa = B.isPrefixOf (B.pack "vmovdqa")
isVmovap = B.isPrefixOf (B.pack "vmovap")
+-- | This rewrites (tail) calls to avoid creating PLT entries for
+-- functions on riscv64. The replacement will load the address from the
+-- GOT, which is resolved to point to the real address of the function.
+rewriteCall :: Rewrite
+rewriteCall dflags l
+ | not isRISCV64 = Nothing
+ | isCall l = Just $ replaceCall "call" "jalr" "ra" l
+ | isTail l = Just $ replaceCall "tail" "jr" "t1" l
+ | otherwise = Nothing
+ where
+ isRISCV64 = platformArch (targetPlatform dflags) == ArchRISCV64
+ isCall = B.isPrefixOf (B.pack "call\t")
+ isTail = B.isPrefixOf (B.pack "tail\t")
+
+ replaceCall call jump reg l =
+ appendInsn (jump ++ "\t" ++ reg) $ removePlt $
+ replaceOnce (B.pack call) (B.pack ("la\t" ++ reg ++ ",")) l
+ where
+ removePlt = replaceOnce (B.pack "@plt") (B.pack "")
+ appendInsn i = (`B.append` B.pack ("\n\t" ++ i))
+
-- | @replaceOnce match replace bs@ replaces the first occurrence of the
-- substring @match@ in @bs@ with @replace@.
replaceOnce :: B.ByteString -> B.ByteString -> B.ByteString -> B.ByteString
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index 8edf49dfdd..d66404e916 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -936,6 +936,7 @@ llvmOptions dflags =
++ [("", "-mcpu=" ++ mcpu) | not (null mcpu)
, not (any (isInfixOf "-mcpu") (getOpts dflags opt_lc)) ]
++ [("", "-mattr=" ++ attrs) | not (null attrs) ]
+ ++ [("", "-target-abi=" ++ abi) | not (null abi) ]
where target = platformMisc_llvmTarget $ platformMisc dflags
Just (LlvmTarget _ mcpu mattr) = lookup target (llvmTargets $ llvmConfig dflags)
@@ -965,6 +966,11 @@ llvmOptions dflags =
++ ["+bmi" | isBmiEnabled dflags ]
++ ["+bmi2" | isBmi2Enabled dflags ]
+ abi :: String
+ abi = case platformArch (targetPlatform dflags) of
+ ArchRISCV64 -> "lp64d"
+ _ -> ""
+
-- -----------------------------------------------------------------------------
-- | Each phase in the pipeline returns the next phase to execute, and the
-- name of the file in which the output was placed.
diff --git a/compiler/GHC/Platform/RISCV64.hs b/compiler/GHC/Platform/RISCV64.hs
new file mode 100644
index 0000000000..289e2e27a8
--- /dev/null
+++ b/compiler/GHC/Platform/RISCV64.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE CPP #-}
+
+module GHC.Platform.RISCV64 where
+
+import GHC.Prelude
+
+#define MACHREGS_NO_REGS 0
+#define MACHREGS_riscv64 1
+#include "../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/GHC/Platform/Regs.hs b/compiler/GHC/Platform/Regs.hs
index 1bf21370c7..e0bdf5d6e5 100644
--- a/compiler/GHC/Platform/Regs.hs
+++ b/compiler/GHC/Platform/Regs.hs
@@ -15,6 +15,7 @@ import qualified GHC.Platform.S390X as S390X
import qualified GHC.Platform.SPARC as SPARC
import qualified GHC.Platform.X86 as X86
import qualified GHC.Platform.X86_64 as X86_64
+import qualified GHC.Platform.RISCV64 as RISCV64
import qualified GHC.Platform.NoRegs as NoRegs
-- | Returns 'True' if this global register is stored in a caller-saves
@@ -31,6 +32,7 @@ callerSaves platform
ArchSPARC -> SPARC.callerSaves
ArchARM {} -> ARM.callerSaves
ArchAArch64 -> AArch64.callerSaves
+ ArchRISCV64 -> RISCV64.callerSaves
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.callerSaves
@@ -53,6 +55,7 @@ activeStgRegs platform
ArchSPARC -> SPARC.activeStgRegs
ArchARM {} -> ARM.activeStgRegs
ArchAArch64 -> AArch64.activeStgRegs
+ ArchRISCV64 -> RISCV64.activeStgRegs
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.activeStgRegs
@@ -70,6 +73,7 @@ haveRegBase platform
ArchSPARC -> SPARC.haveRegBase
ArchARM {} -> ARM.haveRegBase
ArchAArch64 -> AArch64.haveRegBase
+ ArchRISCV64 -> RISCV64.haveRegBase
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.haveRegBase
@@ -87,6 +91,7 @@ globalRegMaybe platform
ArchSPARC -> SPARC.globalRegMaybe
ArchARM {} -> ARM.globalRegMaybe
ArchAArch64 -> AArch64.globalRegMaybe
+ ArchRISCV64 -> RISCV64.globalRegMaybe
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.globalRegMaybe
@@ -104,6 +109,7 @@ freeReg platform
ArchSPARC -> SPARC.freeReg
ArchARM {} -> ARM.freeReg
ArchAArch64 -> AArch64.freeReg
+ ArchRISCV64 -> RISCV64.freeReg
arch
| arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->
PPC.freeReg
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index de53f7f548..483a601602 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -261,6 +261,7 @@ Library
GHC.Platform.AArch64
GHC.Platform.NoRegs
GHC.Platform.PPC
+ GHC.Platform.RISCV64
GHC.Platform.S390X
GHC.Platform.SPARC
GHC.Platform.X86
diff --git a/configure.ac b/configure.ac
index 20911ae43f..b017d50bd6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,7 +283,7 @@ dnl --------------------------------------------------------------
AC_MSG_CHECKING(whether target supports a registerised ABI)
case "$TargetArch" in
- i386|x86_64|powerpc|powerpc64|powerpc64le|s390x|arm|aarch64)
+ i386|x86_64|powerpc|powerpc64|powerpc64le|s390x|arm|aarch64|riscv64)
UnregisterisedDefault=NO
AC_MSG_RESULT([yes])
;;
@@ -318,7 +318,7 @@ AC_MSG_CHECKING(whether target supports tables next to code)
case "$Unregisterised" in
NO)
case "$TargetArch" in
- ia64|powerpc64|powerpc64le|s390x)
+ ia64|powerpc64|powerpc64le|s390x|riscv64)
TablesNextToCodeDefault=NO
AC_MSG_RESULT([no])
;;
@@ -347,7 +347,7 @@ AC_SUBST(TablesNextToCode)
dnl ** Does target have runtime linker support?
dnl --------------------------------------------------------------
case "$target" in
- powerpc64-*|powerpc64le-*|powerpc-ibm-aix*|s390x-ibm-linux)
+ powerpc64-*|powerpc64le-*|powerpc-ibm-aix*|s390x-ibm-linux|riscv64-*)
TargetHasRTSLinker=NO
;;
*)
diff --git a/includes/CodeGen.Platform.hs b/includes/CodeGen.Platform.hs
index b00acfa38a..8c942662e6 100644
--- a/includes/CodeGen.Platform.hs
+++ b/includes/CodeGen.Platform.hs
@@ -380,6 +380,74 @@ import GHC.Platform.Reg
# define f14 30
# define f15 31
+#elif defined(MACHREGS_riscv64)
+
+# define zero 0
+# define ra 1
+# define sp 2
+# define gp 3
+# define tp 4
+# define t0 5
+# define t1 6
+# define t2 7
+# define s0 8
+# define s1 9
+# define a0 10
+# define a1 11
+# define a2 12
+# define a3 13
+# define a4 14
+# define a5 15
+# define a6 16
+# define a7 17
+# define s2 18
+# define s3 19
+# define s4 20
+# define s5 21
+# define s6 22
+# define s7 23
+# define s8 24
+# define s9 25
+# define s10 26
+# define s11 27
+# define t3 28
+# define t4 29
+# define t5 30
+# define t6 31
+
+# define ft0 32
+# define ft1 33
+# define ft2 34
+# define ft3 35
+# define ft4 36
+# define ft5 37
+# define ft6 38
+# define ft7 39
+# define fs0 40
+# define fs1 41
+# define fa0 42
+# define fa1 43
+# define fa2 44
+# define fa3 45
+# define fa4 46
+# define fa5 47
+# define fa6 48
+# define fa7 49
+# define fs2 50
+# define fs3 51
+# define fs4 52
+# define fs5 53
+# define fs6 54
+# define fs7 55
+# define fs8 56
+# define fs9 57
+# define fs10 58
+# define fs11 59
+# define ft8 60
+# define ft9 61
+# define ft10 62
+# define ft11 63
+
#endif
callerSaves :: GlobalReg -> Bool
@@ -667,7 +735,7 @@ globalRegMaybe :: GlobalReg -> Maybe RealReg
#if defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \
|| defined(MACHREGS_sparc) || defined(MACHREGS_powerpc) \
|| defined(MACHREGS_arm) || defined(MACHREGS_aarch64) \
- || defined(MACHREGS_s390x)
+ || defined(MACHREGS_s390x) || defined(MACHREGS_riscv64)
# if defined(REG_Base)
globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
# endif
diff --git a/includes/stg/MachRegs.h b/includes/stg/MachRegs.h
index be7b7d60b4..1a9012e7ef 100644
--- a/includes/stg/MachRegs.h
+++ b/includes/stg/MachRegs.h
@@ -663,6 +663,68 @@ the stack. See Note [Overlapping global registers] for implications.
#define CALLER_SAVES_D5
#define CALLER_SAVES_D6
+/* -----------------------------------------------------------------------------
+ The riscv64 register mapping
+
+ Register | Role(s) | Call effect
+ ------------+-----------------------------------------+-------------
+ zero | Hard-wired zero | -
+ ra | Return address | caller-saved
+ sp | Stack pointer | callee-saved
+ gp | Global pointer | callee-saved
+ tp | Thread pointer | callee-saved
+ t0,t1,t2 | - | caller-saved
+ s0 | Frame pointer | callee-saved
+ s1 | - | callee-saved
+ a0,a1 | Arguments / return values | caller-saved
+ a2..a7 | Arguments | caller-saved
+ s2..s11 | - | callee-saved
+ t3..t6 | - | caller-saved
+ ft0..ft7 | - | caller-saved
+ fs0,fs1 | - | callee-saved
+ fa0,fa1 | Arguments / return values | caller-saved
+ fa2..fa7 | Arguments | caller-saved
+ fs2..fs11 | - | callee-saved
+ ft8..ft11 | - | caller-saved
+
+ Each general purpose register as well as each floating-point
+ register is 64 bits wide.
+
+ -------------------------------------------------------------------------- */
+
+#elif defined(MACHREGS_riscv64)
+
+#define REG(x) __asm__(#x)
+
+#define REG_Base s1
+#define REG_Sp s2
+#define REG_Hp s3
+#define REG_R1 s4
+#define REG_R2 s5
+#define REG_R3 s6
+#define REG_R4 s7
+#define REG_R5 s8
+#define REG_R6 s9
+#define REG_R7 s10
+#define REG_SpLim s11
+
+#define REG_F1 fs0
+#define REG_F2 fs1
+#define REG_F3 fs2
+#define REG_F4 fs3
+#define REG_F5 fs4
+#define REG_F6 fs5
+
+#define REG_D1 fs6
+#define REG_D2 fs7
+#define REG_D3 fs8
+#define REG_D4 fs9
+#define REG_D5 fs10
+#define REG_D6 fs11
+
+#define MAX_REAL_FLOAT_REG 6
+#define MAX_REAL_DOUBLE_REG 6
+
#else
#error Cannot find platform to give register info for
diff --git a/includes/stg/MachRegsForHost.h b/includes/stg/MachRegsForHost.h
index 3597b2be90..e902d528f6 100644
--- a/includes/stg/MachRegsForHost.h
+++ b/includes/stg/MachRegsForHost.h
@@ -71,6 +71,10 @@
#define MACHREGS_s390x 1
#endif
+#if defined(riscv64_HOST_ARCH)
+#define MACHREGS_riscv64 1
+#endif
+
#endif
#include "MachRegs.h"
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index 389dd95c88..f12fd3f71b 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.h
@@ -377,6 +377,8 @@ write_barrier(void) {
__asm__ __volatile__ ("" : : : "memory");
#elif defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)
__asm__ __volatile__ ("dmb st" : : : "memory");
+#elif defined(riscv64_HOST_ARCH)
+ __asm__ __volatile__ ("fence w,w" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
@@ -401,6 +403,8 @@ store_load_barrier(void) {
__asm__ __volatile__ ("dmb" : : : "memory");
#elif defined(aarch64_HOST_ARCH)
__asm__ __volatile__ ("dmb sy" : : : "memory");
+#elif defined(riscv64_HOST_ARCH)
+ __asm__ __volatile__ ("fence w,r" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
@@ -426,6 +430,8 @@ load_load_barrier(void) {
__asm__ __volatile__ ("dmb" : : : "memory");
#elif defined(aarch64_HOST_ARCH)
__asm__ __volatile__ ("dmb sy" : : : "memory");
+#elif defined(riscv64_HOST_ARCH)
+ __asm__ __volatile__ ("fence w,r" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
diff --git a/libraries/ghc-boot/GHC/Platform.hs b/libraries/ghc-boot/GHC/Platform.hs
index 186f8c8af6..44d2c68c0a 100644
--- a/libraries/ghc-boot/GHC/Platform.hs
+++ b/libraries/ghc-boot/GHC/Platform.hs
@@ -130,6 +130,7 @@ data Arch
| ArchAlpha
| ArchMipseb
| ArchMipsel
+ | ArchRISCV64
| ArchJavaScript
deriving (Read, Show, Eq)
@@ -171,6 +172,7 @@ stringEncodeArch = \case
ArchAlpha -> "alpha"
ArchMipseb -> "mipseb"
ArchMipsel -> "mipsel"
+ ArchRISCV64 -> "riscv64"
ArchJavaScript -> "js"
isARM :: Arch -> Bool
@@ -338,6 +340,7 @@ platformCConvNeedsExtension :: Platform -> Bool
platformCConvNeedsExtension platform = case platformArch platform of
ArchPPC_64 _ -> True
ArchS390X -> True
+ ArchRISCV64 -> True
_ -> False
diff --git a/libraries/ghci/GHCi/InfoTable.hsc b/libraries/ghci/GHCi/InfoTable.hsc
index ad4eb4d6a8..1d1f8cd074 100644
--- a/libraries/ghci/GHCi/InfoTable.hsc
+++ b/libraries/ghci/GHCi/InfoTable.hsc
@@ -73,6 +73,7 @@ data Arch = ArchSPARC
| ArchPPC64
| ArchPPC64LE
| ArchS390X
+ | ArchRISCV64
deriving Show
mkJumpToAddr :: MonadFail m => EntryFunPtr-> m ItblCodes
@@ -109,6 +110,8 @@ mArch =
Just ArchPPC64LE
#elif defined(s390x_HOST_ARCH)
Just ArchS390X
+#elif defined(riscv64_HOST_ARCH)
+ Just ArchRISCV64
#else
Nothing
#endif
@@ -288,6 +291,15 @@ mkJumpToAddr' platform a = case platform of
0xC0, 0x19, byte3 w64, byte2 w64, byte1 w64, byte0 w64,
0x07, 0xF1 ]
+ ArchRISCV64 ->
+ let w64 = fromIntegral (funPtrToInt a) :: Word64
+ in Right [ 0x00000297 -- auipc t0,0
+ , 0x01053283 -- ld t0,16(t0)
+ , 0x00028067 -- jr t0
+ , 0x00000013 -- nop
+ , fromIntegral w64
+ , fromIntegral (w64 `shiftR` 32) ]
+
byte0 :: (Integral w) => w -> Word8
byte0 w = fromIntegral w
diff --git a/llvm-targets b/llvm-targets
index c328b2e001..0f809b2418 100644
--- a/llvm-targets
+++ b/llvm-targets
@@ -38,6 +38,8 @@
,("powerpc64le-unknown-linux-musl", ("e-m:e-i64:64-n32:64", "ppc64le", "+secure-plt"))
,("powerpc64le-unknown-linux", ("e-m:e-i64:64-n32:64", "ppc64le", ""))
,("s390x-ibm-linux", ("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64", "z10", ""))
+,("riscv64-unknown-linux-gnu", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+m +a +f +d +c +relax"))
+,("riscv64-unknown-linux", ("e-m:e-p:64:64-i64:64-i128:128-n64-S128", "", "+m +a +f +d +c +relax"))
,("i386-apple-darwin", ("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:128-n8:16:32-S128", "penryn", ""))
,("x86_64-apple-darwin", ("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "penryn", ""))
,("arm64-apple-darwin", ("e-m:o-i64:64-i128:128-n32:64-S128", "apple-a12", "+v8.3a +fp-armv8 +neon +crc +crypto +fullfp16 +ras +lse +rdm +rcpc +zcm +zcz +sha2 +aes"))
diff --git a/m4/fptools.m4 b/m4/fptools.m4
index 8c6c9b7062..7dbe53d3b4 100644
--- a/m4/fptools.m4
+++ b/m4/fptools.m4
@@ -231,7 +231,10 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS],
mipsel)
test -z "[$]2" || eval "[$]2=ArchMipsel"
;;
- hppa|hppa1_1|ia64|m68k|nios2|riscv32|riscv64|rs6000|s390|sh4|vax)
+ riscv64)
+ test -z "[$]2" || eval "[$]2=ArchRISCV64"
+ ;;
+ hppa|hppa1_1|ia64|m68k|nios2|riscv32|rs6000|s390|sh4|vax)
test -z "[$]2" || eval "[$]2=ArchUnknown"
;;
*)
diff --git a/mk/config.mk.in b/mk/config.mk.in
index 48b8e23145..e260730991 100644
--- a/mk/config.mk.in
+++ b/mk/config.mk.in
@@ -179,7 +179,7 @@ ifeq "$(TargetArch_CPP)" "arm"
# We don't support load/store barriers pre-ARMv7. See #10433.
ArchSupportsSMP=$(if $(filter $(ARM_ISA),ARMv5 ARMv6),NO,YES)
else
-ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc powerpc64 powerpc64le s390x aarch64)))
+ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc powerpc64 powerpc64le s390x aarch64 riscv64)))
endif
# The THREADED_RTS requires `BaseReg` to be in a register and the
diff --git a/rts/StgCRunAsm.S b/rts/StgCRunAsm.S
index 60f1bf9a13..16b125a7e8 100644
--- a/rts/StgCRunAsm.S
+++ b/rts/StgCRunAsm.S
@@ -232,6 +232,150 @@ StgReturn:
.size StgReturn, .-StgReturn
.section .note.GNU-stack,"",@progbits
+
+#elif defined(riscv64_HOST_ARCH)
+# define STACK_FRAME_SIZE (RESERVED_C_STACK_BYTES+208)
+ .text
+ .align 1
+ .globl StgRun
+ .type StgRun, @function
+StgRun:
+ .cfi_startproc
+ addi sp,sp,-208
+ .cfi_def_cfa_offset 208
+ /* save callee-saved registers */
+ sd ra,200(sp)
+ sd s0,192(sp)
+ sd s1,184(sp)
+ sd s2,176(sp)
+ sd s3,168(sp)
+ sd s4,160(sp)
+ sd s5,152(sp)
+ sd s6,144(sp)
+ sd s7,136(sp)
+ sd s8,128(sp)
+ sd s9,120(sp)
+ sd s10,112(sp)
+ sd s11,104(sp)
+ fsd fs0,88(sp)
+ fsd fs1,80(sp)
+ fsd fs2,72(sp)
+ fsd fs3,64(sp)
+ fsd fs4,56(sp)
+ fsd fs5,48(sp)
+ fsd fs6,40(sp)
+ fsd fs7,32(sp)
+ fsd fs8,24(sp)
+ fsd fs9,16(sp)
+ fsd fs10,8(sp)
+ fsd fs11,0(sp)
+ /* allocate stack frame */
+ li t0,RESERVED_C_STACK_BYTES
+ sub sp,sp,t0
+ .cfi_def_cfa_offset STACK_FRAME_SIZE
+ .cfi_offset 1, -8
+ .cfi_offset 8, -16
+ .cfi_offset 9, -24
+ .cfi_offset 18, -32
+ .cfi_offset 19, -40
+ .cfi_offset 20, -48
+ .cfi_offset 21, -56
+ .cfi_offset 22, -64
+ .cfi_offset 23, -72
+ .cfi_offset 24, -80
+ .cfi_offset 25, -88
+ .cfi_offset 26, -96
+ .cfi_offset 27, -104
+ .cfi_offset 40, -120
+ .cfi_offset 41, -128
+ .cfi_offset 50, -136
+ .cfi_offset 51, -144
+ .cfi_offset 52, -152
+ .cfi_offset 53, -160
+ .cfi_offset 54, -168
+ .cfi_offset 55, -176
+ .cfi_offset 56, -184
+ .cfi_offset 57, -192
+ .cfi_offset 58, -200
+ .cfi_offset 59, -208
+ /* set STGs BaseReg from RISCV a1 */
+ mv s1,a1
+ /* jump to STG function */
+ jr a0
+ .cfi_endproc
+ .size StgRun, .-StgRun
+
+ .text
+ .align 1
+ .globl StgReturn
+ .type StgReturn, @function
+StgReturn:
+ .cfi_startproc
+ /* set return value from STGs R1 (RISCV s4) */
+ mv a0,s4
+ /* deallocate stack frame */
+ li t0,RESERVED_C_STACK_BYTES
+ add sp,sp,t0
+ .cfi_def_cfa_offset 208
+ /* restore callee-saved registers */
+ ld ra,200(sp)
+ .cfi_restore 1
+ ld s0,192(sp)
+ .cfi_restore 8
+ ld s1,184(sp)
+ .cfi_restore 9
+ ld s2,176(sp)
+ .cfi_restore 18
+ ld s3,168(sp)
+ .cfi_restore 19
+ ld s4,160(sp)
+ .cfi_restore 20
+ ld s5,152(sp)
+ .cfi_restore 21
+ ld s6,144(sp)
+ .cfi_restore 22
+ ld s7,136(sp)
+ .cfi_restore 23
+ ld s8,128(sp)
+ .cfi_restore 24
+ ld s9,120(sp)
+ .cfi_restore 25
+ ld s10,112(sp)
+ .cfi_restore 26
+ ld s11,104(sp)
+ .cfi_restore 27
+ fld fs0,88(sp)
+ .cfi_restore 40
+ fld fs1,80(sp)
+ .cfi_restore 41
+ fld fs2,72(sp)
+ .cfi_restore 50
+ fld fs3,64(sp)
+ .cfi_restore 51
+ fld fs4,56(sp)
+ .cfi_restore 52
+ fld fs5,48(sp)
+ .cfi_restore 53
+ fld fs6,40(sp)
+ .cfi_restore 54
+ fld fs7,32(sp)
+ .cfi_restore 55
+ fld fs8,24(sp)
+ .cfi_restore 56
+ fld fs9,16(sp)
+ .cfi_restore 57
+ fld fs10,8(sp)
+ .cfi_restore 58
+ fld fs11,0(sp)
+ .cfi_restore 59
+ addi sp,sp,208
+ .cfi_def_cfa_offset 0
+ /* jump back to caller of StgRun() */
+ ret
+ .cfi_endproc
+ .size StgReturn, .-StgReturn
+
+ .section .note.GNU-stack,"",@progbits
#endif
#endif /* !USE_MINIINTERPRETER */
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index 1da69d03fa..0aa1c8dd3f 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -412,6 +412,12 @@ ocVerifyImage_ELF ( ObjectCode* oc )
#endif
#if defined(EM_AARCH64)
case EM_AARCH64: IF_DEBUG(linker,debugBelch( "aarch64" )); break;
+#endif
+#if defined(EM_RISCV)
+ case EM_RISCV: IF_DEBUG(linker,debugBelch( "riscv" ));
+ errorBelch("%s: RTS linker not implemented on riscv",
+ oc->fileName);
+ return 0;
#endif
default: IF_DEBUG(linker,debugBelch( "unknown" ));
errorBelch("%s: unknown architecture (e_machine == %d)"
diff --git a/utils/genapply/Main.hs b/utils/genapply/Main.hs
index a6d944efa4..a5697b427f 100644
--- a/utils/genapply/Main.hs
+++ b/utils/genapply/Main.hs
@@ -17,6 +17,8 @@ module Main(main) where
-- We improperly include *HOST* macros for our target...
#include "../../includes/ghcconfig.h"
+#undef UnregisterisedCompiler
+
-- ...so that this header defines the right stuff. It is the RTS's host, but
-- our target, as we are generating code that uses that RTS.
#include "../../includes/stg/MachRegsForHost.h"
diff --git a/utils/llvm-targets/gen-data-layout.sh b/utils/llvm-targets/gen-data-layout.sh
index 32032cb97e..092e0892e5 100755
--- a/utils/llvm-targets/gen-data-layout.sh
+++ b/utils/llvm-targets/gen-data-layout.sh
@@ -76,6 +76,9 @@ TARGETS=(
"powerpc64le-unknown-linux"
# Linux s390x
"s390x-ibm-linux"
+ # Linux riscv64
+ "riscv64-unknown-linux-gnu"
+ "riscv64-unknown-linux"
#########################
# Darwin
|