From 6379bebd41899ca74ac146e8073aee0bd1781b3f Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 18 Jan 2019 11:42:59 +0000 Subject: arch-arm: Implement LoadAcquire/StoreRelease in AArch32 This patch is implementing LoadAcquire/StoreRelease instructions in AArch32, which were added in ARMv8-A only and where not present in ARMv7. Change-Id: I5e26459971d0b183a955cd7b0c9c7eaffef453be Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/15817 Maintainer: Andreas Sandberg --- src/arch/arm/isa/formats/mem.isa | 115 +++++++++++++++++++++++++++++++++++---- src/arch/arm/isa/insts/ldr.isa | 30 ++++++++-- src/arch/arm/isa/insts/str.isa | 24 +++++++- 3 files changed, 150 insertions(+), 19 deletions(-) diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 888bbdff6..9bc23f6cf 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010 ARM Limited +// Copyright (c) 2010,2019 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -225,21 +225,54 @@ def format ArmSyncMem() {{ const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); - switch (PUBWL) { - case 0x18: + + const auto type_L = bits(machInst, 22, 20); + const auto ex_ord = bits(machInst, 9, 8); + const auto dec_fields = (type_L << 2) | ex_ord; + + switch (dec_fields) { + case 0x00: + return new %(stl)s(machInst, rt, rn, true, 0); + case 0x02: + return new %(stlex)s(machInst, rt, rt2, rn, true, 0); + case 0x03: return new %(strex)s(machInst, rt, rt2, rn, true, 0); - case 0x19: + case 0x04: + return new %(lda)s(machInst, rt, rn, true, 0); + case 0x06: + return new %(ldaex)s(machInst, rt, rn, true, 0); + case 0x07: return new %(ldrex)s(machInst, rt, rn, true, 0); - case 0x1a: + case 0x0a: + return new %(stlexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); + case 0x0b: return new %(strexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); - case 0x1b: + case 0x0e: + return new %(ldaexd)s(machInst, rt, rt + 1, rn, true, 0); + case 0x0f: return new %(ldrexd)s(machInst, rt, rt + 1, rn, true, 0); - case 0x1c: + case 0x10: + return new %(stlb)s(machInst, rt, rn, true, 0); + case 0x12: + return new %(stlexb)s(machInst, rt, rt2, rn, true, 0); + case 0x13: return new %(strexb)s(machInst, rt, rt2, rn, true, 0); - case 0x1d: + case 0x14: + return new %(ldab)s(machInst, rt, rn, true, 0); + case 0x16: + return new %(ldaexb)s(machInst, rt, rn, true, 0); + case 0x17: return new %(ldrexb)s(machInst, rt, rn, true, 0); - case 0x1e: + case 0x18: + return new %(stlh)s(machInst, rt, rn, true, 0); + case 0x1a: + return new %(stlexh)s(machInst, rt, rt2, rn, true, 0); + case 0x1b: return new %(strexh)s(machInst, rt, rt2, rn, true, 0); + case 0x1c: + return new %(ldah)s(machInst, rt, rn, true, 0); + case 0x1e: + return new %(ldaexh)s(machInst, rt, rn, true, 0); case 0x1f: return new %(ldrexh)s(machInst, rt, rn, true, 0); default: @@ -254,7 +287,23 @@ def format ArmSyncMem() {{ "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), - "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False) + "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False), + + "lda" : "LDA_" + loadImmClassName(False, True, False, size=4), + "ldab" : "LDAB_" + loadImmClassName(False, True, False, size=1), + "ldah" : "LDAH_" + loadImmClassName(False, True, False, size=2), + "ldaex" : "LDAEX_" + loadImmClassName(False, True, False, size=4), + "ldaexb" : "LDAEXB_" + loadImmClassName(False, True, False, size=1), + "ldaexh" : "LDAEXH_" + loadImmClassName(False, True, False, size=2), + "ldaexd" : "LDAEXD_" + loadDoubleImmClassName(False, True, False), + + "stl" : "STL_" + storeImmClassName(False, True, False, size=4), + "stlb" : "STLB_" + storeImmClassName(False, True, False, size=1), + "stlh" : "STLH_" + storeImmClassName(False, True, False, size=2), + "stlex" : "STLEX_" + storeImmClassName(False, True, False, size=4), + "stlexb" : "STLEXB_" + storeImmClassName(False, True, False, size=1), + "stlexh" : "STLEXH_" + storeImmClassName(False, True, False, size=2), + "stlexd" : "STLEXD_" + storeDoubleImmClassName(False, True, False) } }}; @@ -341,6 +390,21 @@ def format Thumb32LdrStrDExTbh() {{ case 0x7: return new %(strexd)s(machInst, rd, rt, rt2, rn, true, 0); + case 0x8: + return new %(stlb)s(machInst, rt, rn, true, 0); + case 0x9: + return new %(stlh)s(machInst, rt, rn, true, 0); + case 0xa: + return new %(stl)s(machInst, rt, rn, true, 0); + case 0xc: + return new %(stlexb)s(machInst, rd, rt, rn, true, 0); + case 0xd: + return new %(stlexh)s(machInst, rd, rt, rn, true, 0); + case 0xe: + return new %(stlex)s(machInst, rd, rt, rn, true, 0); + case 0xf: + return new %(stlexd)s(machInst, rd, rt, + rt2, rn, true, 0); default: return new Unknown(machInst); } @@ -356,6 +420,20 @@ def format Thumb32LdrStrDExTbh() {{ return new %(ldrexh)s(machInst, rt, rn, true, 0); case 0x7: return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); + case 0x8: + return new %(ldab)s(machInst, rt, rn, true, 0); + case 0x9: + return new %(ldah)s(machInst, rt, rn, true, 0); + case 0xa: + return new %(lda)s(machInst, rt, rn, true, 0); + case 0xc: + return new %(ldaexb)s(machInst, rt, rn, true, 0); + case 0xd: + return new %(ldaexh)s(machInst, rt, rn, true, 0); + case 0xe: + return new %(ldaex)s(machInst, rt, rn, true, 0); + case 0xf: + return new %(ldaexd)s(machInst, rt, rt2, rn, true, 0); default: return new Unknown(machInst); } @@ -422,7 +500,22 @@ def format Thumb32LdrStrDExTbh() {{ "strd_p" : storeDoubleImmClassName(False, False, False), "strd_pw" : storeDoubleImmClassName(False, False, True), "strd_pu" : storeDoubleImmClassName(False, True, False), - "strd_puw" : storeDoubleImmClassName(False, True, True) + "strd_puw" : storeDoubleImmClassName(False, True, True), + + "stl" : "STL_" + storeImmClassName(False, True, False, size=4), + "stlh" : "STLH_" + storeImmClassName(False, True, False, size=2), + "stlb" : "STLB_" + storeImmClassName(False, True, False, size=1), + "stlex" : "STLEX_" + storeImmClassName(False, True, False, size=4), + "stlexh" : "STLEXH_" + storeImmClassName(False, True, False, size=2), + "stlexb" : "STLEXB_" + storeImmClassName(False, True, False, size=1), + "stlexd" : "STLEXD_" + storeDoubleImmClassName(False, True, False), + "lda" : "LDA_" + loadImmClassName(False, True, False, size=4), + "ldah" : "LDAH_" + loadImmClassName(False, True, False, size=2), + "ldab" : "LDAB_" + loadImmClassName(False, True, False, size=1), + "ldaex" : "LDAEX_" + loadImmClassName(False, True, False, size=4), + "ldaexh" : "LDAEXH_" + loadImmClassName(False, True, False, size=2), + "ldaexb" : "LDAEXB_" + loadImmClassName(False, True, False, size=1), + "ldaexd" : "LDAEXD_" + loadDoubleImmClassName(False, True, False) } }}; diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index 3edeb3805..6e5122c6a 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2011 ARM Limited +// Copyright (c) 2010-2011,2019 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -173,11 +173,17 @@ let {{ elif self.flavor == "iprefetch": self.memFlags.append("Request::PREFETCH") self.instFlags = ['IsInstPrefetch'] - elif self.flavor == "exclusive": - self.memFlags.append("Request::LLSC") elif self.flavor == "normal": self.memFlags.append("ArmISA::TLB::AllowUnaligned") + if self.flavor in ("exclusive", "acex"): + self.memFlags.append("Request::LLSC") + + if self.flavor in ("acquire", "acex"): + self.instFlags.extend(["IsMemBarrier", + "IsWriteBarrier", + "IsReadBarrier"]) + # Disambiguate the class name for different flavors of loads if self.flavor != "normal": self.Name = "%s_%s" % (self.name.upper(), self.Name) @@ -235,8 +241,9 @@ let {{ # Build the default class name self.Name = self.nameFunc(self.post, self.add, self.writeback) + self.instFlags = [] # Add memory request flags where necessary - if self.flavor == "exclusive": + if self.flavor in ("exclusive", "acex"): self.memFlags.append("Request::LLSC") self.memFlags.append("ArmISA::TLB::AlignDoubleWord") else: @@ -246,6 +253,11 @@ let {{ if self.flavor != "normal": self.Name = "%s_%s" % (self.name.upper(), self.Name) + if self.flavor in ("acquire", "acex"): + self.instFlags.extend(["IsMemBarrier", + "IsWriteBarrier", + "IsReadBarrier"]) + def emit(self): # Address computation code eaCode = "EA = Base" @@ -279,7 +291,7 @@ let {{ wbDecl = None if self.writeback: wbDecl = self.wbDecl - self.emitHelper(base, wbDecl) + self.emitHelper(base, wbDecl, self.instFlags) def loadDoubleImmClassName(post, add, writeback): return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False) @@ -365,6 +377,14 @@ let {{ LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit() LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit() + LoadImm("lda", False, True, False, size=4, flavor="acquire").emit() + LoadImm("ldah", False, True, False, size=2, flavor="acquire").emit() + LoadImm("ldab", False, True, False, size=1, flavor="acquire").emit() + LoadImm("ldaex", False, True, False, size=4, flavor="acex").emit() + LoadImm("ldaexh", False, True, False, size=2, flavor="acex").emit() + LoadImm("ldaexb", False, True, False, size=1, flavor="acex").emit() + LoadDoubleImm("ldaexd", False, True, False, flavor="acex").emit() + LoadImm("vldr", False, True, False, size=4, flavor="fp").emit() LoadImm("vldr", False, False, False, size=4, flavor="fp").emit() LoadDoubleImm("vldr", False, True, False, flavor="fp").emit() diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index ea412aa8d..6b2e8cc77 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2011,2017 ARM Limited +// Copyright (c) 2010-2011,2017,2019 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -183,12 +183,17 @@ let {{ if self.user: self.memFlags.append("ArmISA::TLB::UserMode") - if self.flavor == "exclusive": + if self.flavor in ("exclusive", "relex"): self.instFlags.append("IsStoreConditional") self.memFlags.append("Request::LLSC") elif self.flavor != "fp": self.memFlags.append("ArmISA::TLB::AllowUnaligned") + if self.flavor in ("release", "relex"): + self.instFlags.extend(["IsMemBarrier", + "IsWriteBarrier", + "IsReadBarrier"]) + # Disambiguate the class name for different flavors of stores if self.flavor != "normal": self.Name = "%s_%s" % (self.name.upper(), self.Name) @@ -258,13 +263,18 @@ let {{ self.Name = self.nameFunc(self.post, self.add, self.writeback) # Add memory request flags where necessary - if self.flavor == "exclusive": + if self.flavor in ("exclusive", "relex"): self.instFlags.append("IsStoreConditional") self.memFlags.append("Request::LLSC") self.memFlags.append("ArmISA::TLB::AlignDoubleWord") else: self.memFlags.append("ArmISA::TLB::AlignWord") + if self.flavor in ("release", "relex"): + self.instFlags.extend(["IsMemBarrier", + "IsWriteBarrier", + "IsReadBarrier"]) + # Disambiguate the class name for different flavors of stores if self.flavor != "normal": self.Name = "%s_%s" % (self.name.upper(), self.Name) @@ -389,6 +399,14 @@ let {{ StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit() + StoreImm("stl", False, True, False, size=4, flavor="release").emit() + StoreImm("stlh", False, True, False, size=2, flavor="release").emit() + StoreImm("stlb", False, True, False, size=1, flavor="release").emit() + StoreImmEx("stlex", False, True, False, size=4, flavor="relex").emit() + StoreImmEx("stlexh", False, True, False, size=2, flavor="relex").emit() + StoreImmEx("stlexb", False, True, False, size=1, flavor="relex").emit() + StoreDoubleImmEx("stlexd", False, True, False, flavor="relex").emit() + StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() -- cgit v1.2.3