forked from M-Labs/artiq
1
0
Fork 0

ll_gen: adjust csr address by detecting target class

This commit is contained in:
occheung 2021-11-08 13:02:15 +08:00 committed by Sébastien Bourdeauducq
parent 0755757601
commit 0f660735bf
1 changed files with 24 additions and 13 deletions

View File

@ -10,6 +10,7 @@ from llvmlite import ir as ll, binding as llvm
from ...language import core as language_core from ...language import core as language_core
from .. import types, builtins, ir from .. import types, builtins, ir
from ..embedding import SpecializedFunction from ..embedding import SpecializedFunction
from artiq.compiler.targets import RV32GTarget
llvoid = ll.VoidType() llvoid = ll.VoidType()
@ -1097,20 +1098,28 @@ class LLVMIRGenerator:
if self.target.now_pinning: if self.target.now_pinning:
# Word swap now.old as CPU is little endian # Word swap now.old as CPU is little endian
# Most significant word is stored in lower address (see generated csr.rs) # Most significant word is stored in lower address (see generated csr.rs)
llnow_raw = self.llbuilder.load(self.llbuiltin("now"), name=insn.name) csr_offset = 2 if isinstance(self.target, RV32GTarget) else 1
llnow_lo = self.llbuilder.shl(llnow_raw, ll.Constant(lli64, 32))
llnow_hi = self.llbuilder.lshr(llnow_raw, ll.Constant(lli64, 32)) llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer())
return self.llbuilder.or_(llnow_lo, llnow_hi) llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(csr_offset)])
llnow_hi = self.llbuilder.load(llnow_hiptr, name="now.hi")
llnow_lo = self.llbuilder.load(llnow_loptr, name="now.lo")
llzext_hi = self.llbuilder.zext(llnow_hi, lli64)
llshifted_hi = self.llbuilder.shl(llzext_hi, ll.Constant(lli64, 32))
llzext_lo = self.llbuilder.zext(llnow_lo, lli64)
return self.llbuilder.or_(llshifted_hi, llzext_lo)
else: else:
return self.llbuilder.call(self.llbuiltin("now_mu"), []) return self.llbuilder.call(self.llbuiltin("now_mu"), [])
elif insn.op == "at_mu": elif insn.op == "at_mu":
time, = insn.operands time, = insn.operands
lltime = self.map(time) lltime = self.map(time)
if self.target.now_pinning: if self.target.now_pinning:
csr_offset = 2 if isinstance(self.target, RV32GTarget) else 1
lltime_hi = self.llbuilder.trunc(self.llbuilder.lshr(lltime, ll.Constant(lli64, 32)), lli32) lltime_hi = self.llbuilder.trunc(self.llbuilder.lshr(lltime, ll.Constant(lli64, 32)), lli32)
lltime_lo = self.llbuilder.trunc(lltime, lli32) lltime_lo = self.llbuilder.trunc(lltime, lli32)
llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer()) llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer())
llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(1)]) llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(csr_offset)])
llstore_hi = self.llbuilder.store_atomic(lltime_hi, llnow_hiptr, ordering="seq_cst", align=4) llstore_hi = self.llbuilder.store_atomic(lltime_hi, llnow_hiptr, ordering="seq_cst", align=4)
llstore_lo = self.llbuilder.store_atomic(lltime_lo, llnow_loptr, ordering="seq_cst", align=4) llstore_lo = self.llbuilder.store_atomic(lltime_lo, llnow_loptr, ordering="seq_cst", align=4)
return llstore_lo return llstore_lo
@ -1120,20 +1129,22 @@ class LLVMIRGenerator:
interval, = insn.operands interval, = insn.operands
llinterval = self.map(interval) llinterval = self.map(interval)
if self.target.now_pinning: if self.target.now_pinning:
llnowptr = self.llbuiltin("now")
llnow = self.llbuilder.load(llnowptr, name="now.old")
# Word swap now.old as CPU is little endian # Word swap now.old as CPU is little endian
# Most significant word is stored in lower address (see generated csr.rs) # Most significant word is stored in lower address (see generated csr.rs)
llnow_lo = self.llbuilder.shl(llnow, ll.Constant(lli64, 32)) csr_offset = 2 if isinstance(self.target, RV32GTarget) else 1
llnow_hi = self.llbuilder.lshr(llnow, ll.Constant(lli64, 32))
llnow = self.llbuilder.or_(llnow_lo, llnow_hi) llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer())
llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(csr_offset)])
llnow_hi = self.llbuilder.load(llnow_hiptr, name="now.hi")
llnow_lo = self.llbuilder.load(llnow_loptr, name="now.lo")
llzext_hi = self.llbuilder.zext(llnow_hi, lli64)
llshifted_hi = self.llbuilder.shl(llzext_hi, ll.Constant(lli64, 32))
llzext_lo = self.llbuilder.zext(llnow_lo, lli64)
llnow = self.llbuilder.or_(llshifted_hi, llzext_lo)
lladjusted = self.llbuilder.add(llnow, llinterval, name="now.new") lladjusted = self.llbuilder.add(llnow, llinterval, name="now.new")
lladjusted_hi = self.llbuilder.trunc(self.llbuilder.lshr(lladjusted, ll.Constant(lli64, 32)), lli32) lladjusted_hi = self.llbuilder.trunc(self.llbuilder.lshr(lladjusted, ll.Constant(lli64, 32)), lli32)
lladjusted_lo = self.llbuilder.trunc(lladjusted, lli32) lladjusted_lo = self.llbuilder.trunc(lladjusted, lli32)
llnow_hiptr = self.llbuilder.bitcast(llnowptr, lli32.as_pointer())
llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(1)])
llstore_hi = self.llbuilder.store_atomic(lladjusted_hi, llnow_hiptr, ordering="seq_cst", align=4) llstore_hi = self.llbuilder.store_atomic(lladjusted_hi, llnow_hiptr, ordering="seq_cst", align=4)
llstore_lo = self.llbuilder.store_atomic(lladjusted_lo, llnow_loptr, ordering="seq_cst", align=4) llstore_lo = self.llbuilder.store_atomic(lladjusted_lo, llnow_loptr, ordering="seq_cst", align=4)
return llstore_lo return llstore_lo