forked from M-Labs/artiq
compiler: support disabling now-pinning
This commit is contained in:
parent
d19f28fa84
commit
251a0101a6
@ -78,13 +78,15 @@ class Target:
|
||||
:var little_endian: (boolean)
|
||||
Whether the code will be executed on a little-endian machine. This cannot be always
|
||||
determined from data_layout due to JIT.
|
||||
:var now_pinning: (boolean)
|
||||
Whether the target implements the now-pinning RTIO optimization.
|
||||
"""
|
||||
triple = "unknown"
|
||||
data_layout = ""
|
||||
features = []
|
||||
print_function = "printf"
|
||||
little_endian = False
|
||||
|
||||
now_pinning = True
|
||||
|
||||
def __init__(self):
|
||||
self.llcontext = ll.Context()
|
||||
@ -254,6 +256,7 @@ class OR1KTarget(Target):
|
||||
features = ["mul", "div", "ffl1", "cmov", "addc"]
|
||||
print_function = "core_log"
|
||||
little_endian = False
|
||||
now_pinning = True
|
||||
|
||||
class CortexA9Target(Target):
|
||||
triple = "armv7-unknown-linux-gnueabihf"
|
||||
@ -261,3 +264,4 @@ class CortexA9Target(Target):
|
||||
features = ["dsp", "fp16", "neon", "vfp3"]
|
||||
print_function = "core_log"
|
||||
little_endian = True
|
||||
now_pinning = False
|
||||
|
@ -380,8 +380,19 @@ class LLVMIRGenerator:
|
||||
llty = ll.FunctionType(llvoid, [lli32, llsliceptr, llptrptr])
|
||||
elif name == "rpc_recv":
|
||||
llty = ll.FunctionType(lli32, [llptr])
|
||||
|
||||
# with now-pinning
|
||||
elif name == "now":
|
||||
llty = lli64
|
||||
|
||||
# without now-pinning
|
||||
elif name == "now_mu":
|
||||
llty = ll.FunctionType(lli64, [])
|
||||
elif name == "at_mu":
|
||||
llty = ll.FunctionType(llvoid, [lli64])
|
||||
elif name == "delay_mu":
|
||||
llty = ll.FunctionType(llvoid, [lli64])
|
||||
|
||||
elif name == "watchdog_set":
|
||||
llty = ll.FunctionType(lli32, [lli64])
|
||||
elif name == "watchdog_clear":
|
||||
@ -1174,35 +1185,43 @@ class LLVMIRGenerator:
|
||||
# This is an identity cast at LLVM IR level.
|
||||
return self.map(insn.operands[0])
|
||||
elif insn.op == "now_mu":
|
||||
llnow = self.llbuilder.load(self.llbuiltin("now"), name=insn.name)
|
||||
return llnow
|
||||
if self.target.now_pinning:
|
||||
return self.llbuilder.load(self.llbuiltin("now"), name=insn.name)
|
||||
else:
|
||||
return self.llbuilder.call(self.llbuiltin("now_mu"), [])
|
||||
elif insn.op == "at_mu":
|
||||
time, = insn.operands
|
||||
lltime = self.map(time)
|
||||
lltime_hi = self.llbuilder.trunc(self.llbuilder.lshr(lltime, ll.Constant(lli64, 32)), lli32)
|
||||
lltime_lo = self.llbuilder.trunc(lltime, lli32)
|
||||
llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer())
|
||||
llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(1)])
|
||||
if self.target.little_endian:
|
||||
lltime_hi, lltime_lo = lltime_lo, lltime_hi
|
||||
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)
|
||||
return llstore_lo
|
||||
if self.target.now_pinning:
|
||||
lltime_hi = self.llbuilder.trunc(self.llbuilder.lshr(lltime, ll.Constant(lli64, 32)), lli32)
|
||||
lltime_lo = self.llbuilder.trunc(lltime, lli32)
|
||||
llnow_hiptr = self.llbuilder.bitcast(self.llbuiltin("now"), lli32.as_pointer())
|
||||
llnow_loptr = self.llbuilder.gep(llnow_hiptr, [self.llindex(1)])
|
||||
if self.target.little_endian:
|
||||
lltime_hi, lltime_lo = lltime_lo, lltime_hi
|
||||
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)
|
||||
return llstore_lo
|
||||
else:
|
||||
return self.llbuilder.call(self.llbuiltin("at_mu"), [lltime])
|
||||
elif insn.op == "delay_mu":
|
||||
interval, = insn.operands
|
||||
llnowptr = self.llbuiltin("now")
|
||||
llnow = self.llbuilder.load(llnowptr, name="now.old")
|
||||
lladjusted = self.llbuilder.add(llnow, self.map(interval), name="now.new")
|
||||
|
||||
lladjusted_hi = self.llbuilder.trunc(self.llbuilder.lshr(lladjusted, ll.Constant(lli64, 32)), 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)])
|
||||
if self.target.little_endian:
|
||||
lladjusted_hi, lladjusted_lo = lladjusted_lo, lladjusted_hi
|
||||
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)
|
||||
return llstore_lo
|
||||
llinterval = self.map(interval)
|
||||
if self.target.now_pinning:
|
||||
llnowptr = self.llbuiltin("now")
|
||||
llnow = self.llbuilder.load(llnowptr, name="now.old")
|
||||
lladjusted = self.llbuilder.add(llnow, llinterval, name="now.new")
|
||||
lladjusted_hi = self.llbuilder.trunc(self.llbuilder.lshr(lladjusted, ll.Constant(lli64, 32)), 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)])
|
||||
if self.target.little_endian:
|
||||
lladjusted_hi, lladjusted_lo = lladjusted_lo, lladjusted_hi
|
||||
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)
|
||||
return llstore_lo
|
||||
else:
|
||||
return self.llbuilder.call(self.llbuiltin("delay_mu"), [llinterval])
|
||||
elif insn.op == "watchdog_set":
|
||||
interval, = insn.operands
|
||||
return self.llbuilder.call(self.llbuiltin("watchdog_set"), [self.map(interval)])
|
||||
|
Loading…
Reference in New Issue
Block a user