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