diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 7d7ca6344..149d45f4a 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -1103,6 +1103,14 @@ class LLVMIRGenerator: return self.map(insn.operands[0]) elif insn.op == "now_mu": if self.target.now_pinning: + # Word swap now.old for little endian target + # Most significant word is stored in lower address (see generated csr.rs) + if self.target.little_endian: + llnow_raw = self.llbuilder.load(self.llbuiltin("now"), name=insn.name) + llnow_lo = self.llbuilder.shl(llnow_raw, ll.Constant(lli64, 32)) + llnow_hi = self.llbuilder.lshr(llnow_raw, ll.Constant(lli64, 32)) + return self.llbuilder.or_(llnow_lo, llnow_hi) + else: return self.llbuilder.load(self.llbuiltin("now"), name=insn.name) else: return self.llbuilder.call(self.llbuiltin("now_mu"), []) @@ -1114,8 +1122,6 @@ class LLVMIRGenerator: 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 @@ -1127,13 +1133,17 @@ class LLVMIRGenerator: if self.target.now_pinning: llnowptr = self.llbuiltin("now") llnow = self.llbuilder.load(llnowptr, name="now.old") + # Word swap now.old for little endian target + # Most significant word is stored in lower address (see generated csr.rs) + if self.target.little_endian: + llnow_lo = self.llbuilder.shl(llnow, ll.Constant(lli64, 32)) + llnow_hi = self.llbuilder.lshr(llnow, ll.Constant(lli64, 32)) + llnow = self.llbuilder.or_(llnow_lo, llnow_hi) 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