From 1da285dfcc31b904afc27e440544d006aae25b38 Mon Sep 17 00:00:00 2001 From: Giacomo Gabrielli Date: Tue, 14 Feb 2017 14:25:41 +0000 Subject: arm: Add support for RCpc load-acquire instructions (ARMv8.3) Please note that at the moment these instructions behave like the existing load-acquire instructions, which follow the more conservative RCsc consistency model. This means that the new instructions are _functionally_ correct, but the potential performance improvements enabled by the RCpc model will not be experienced in timing simulations. Change-Id: I04c786ad2941072bf28feba7d2ec6e142c8b74cb Reviewed-by: Andreas Hansson Reviewed-on: https://gem5-review.googlesource.com/11989 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini --- src/arch/arm/isa/formats/aarch64.isa | 182 +++++++++++++++++++++++------------ src/arch/arm/isa/insts/ldr64.isa | 7 +- 2 files changed, 126 insertions(+), 63 deletions(-) diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index 722cd7415..43dd557aa 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -782,68 +782,126 @@ namespace Aarch64 return new Unknown64(machInst); } } else if (bits(machInst, 21) == 1) { - if (bits(machInst, 11, 10) != 0x2) - return new Unknown64(machInst); - if (!bits(machInst, 14)) - return new Unknown64(machInst); - IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); - IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); - IntRegIndex rnsp = makeSP(rn); - IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); - ArmExtendType type = - (ArmExtendType)(uint32_t)bits(machInst, 15, 13); - uint8_t s = bits(machInst, 12); - switch (switchVal) { - case 0x00: - return new STRB64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x01: - return new LDRB64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x02: - return new LDRSBX64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x03: - return new LDRSBW64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x04: - return new STRBFP64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x05: - return new LDRBFP64_REG(machInst, rt, rnsp, rm, type, 0); - case 0x6: - return new BigFpMemReg("str", machInst, false, - rt, rnsp, rm, type, s * 4); - case 0x7: - return new BigFpMemReg("ldr", machInst, true, - rt, rnsp, rm, type, s * 4); - case 0x08: - return new STRH64_REG(machInst, rt, rnsp, rm, type, s); - case 0x09: - return new LDRH64_REG(machInst, rt, rnsp, rm, type, s); - case 0x0a: - return new LDRSHX64_REG(machInst, rt, rnsp, rm, type, s); - case 0x0b: - return new LDRSHW64_REG(machInst, rt, rnsp, rm, type, s); - case 0x0c: - return new STRHFP64_REG(machInst, rt, rnsp, rm, type, s); - case 0x0d: - return new LDRHFP64_REG(machInst, rt, rnsp, rm, type, s); - case 0x10: - return new STRW64_REG(machInst, rt, rnsp, rm, type, s * 2); - case 0x11: - return new LDRW64_REG(machInst, rt, rnsp, rm, type, s * 2); - case 0x12: - return new LDRSW64_REG(machInst, rt, rnsp, rm, type, s * 2); - case 0x14: - return new STRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); - case 0x15: - return new LDRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); - case 0x18: - return new STRX64_REG(machInst, rt, rnsp, rm, type, s * 3); - case 0x19: - return new LDRX64_REG(machInst, rt, rnsp, rm, type, s * 3); - case 0x1a: - return new PRFM64_REG(machInst, rt, rnsp, rm, type, s * 3); - case 0x1c: - return new STRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); - case 0x1d: - return new LDRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); + uint8_t group = bits(machInst, 11, 10); + switch (group) { + case 0x0: + { + if ((switchVal & 0x7) == 0x2 && + bits(machInst, 20, 12) == 0x1fc) { + IntRegIndex rt = (IntRegIndex)(uint32_t) + bits(machInst, 4, 0); + IntRegIndex rn = (IntRegIndex)(uint32_t) + bits(machInst, 9, 5); + IntRegIndex rnsp = makeSP(rn); + uint8_t size = bits(machInst, 31, 30); + switch (size) { + case 0x0: + return new LDAPRB64(machInst, rt, rnsp); + case 0x1: + return new LDAPRH64(machInst, rt, rnsp); + case 0x2: + return new LDAPRW64(machInst, rt, rnsp); + case 0x3: + return new LDAPRX64(machInst, rt, rnsp); + default: + M5_UNREACHABLE; + } + } else { + return new Unknown64(machInst); + } + } + case 0x2: + { + if (!bits(machInst, 14)) + return new Unknown64(machInst); + IntRegIndex rt = (IntRegIndex)(uint32_t) + bits(machInst, 4, 0); + IntRegIndex rn = (IntRegIndex)(uint32_t) + bits(machInst, 9, 5); + IntRegIndex rnsp = makeSP(rn); + IntRegIndex rm = (IntRegIndex)(uint32_t) + bits(machInst, 20, 16); + ArmExtendType type = + (ArmExtendType)(uint32_t)bits(machInst, 15, 13); + uint8_t s = bits(machInst, 12); + switch (switchVal) { + case 0x00: + return new STRB64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x01: + return new LDRB64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x02: + return new LDRSBX64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x03: + return new LDRSBW64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x04: + return new STRBFP64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x05: + return new LDRBFP64_REG(machInst, rt, rnsp, rm, + type, 0); + case 0x6: + return new BigFpMemReg("str", machInst, false, + rt, rnsp, rm, type, s * 4); + case 0x7: + return new BigFpMemReg("ldr", machInst, true, + rt, rnsp, rm, type, s * 4); + case 0x08: + return new STRH64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x09: + return new LDRH64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x0a: + return new LDRSHX64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x0b: + return new LDRSHW64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x0c: + return new STRHFP64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x0d: + return new LDRHFP64_REG(machInst, rt, rnsp, rm, + type, s); + case 0x10: + return new STRW64_REG(machInst, rt, rnsp, rm, + type, s * 2); + case 0x11: + return new LDRW64_REG(machInst, rt, rnsp, rm, + type, s * 2); + case 0x12: + return new LDRSW64_REG(machInst, rt, rnsp, rm, + type, s * 2); + case 0x14: + return new STRSFP64_REG(machInst, rt, rnsp, rm, + type, s * 2); + case 0x15: + return new LDRSFP64_REG(machInst, rt, rnsp, rm, + type, s * 2); + case 0x18: + return new STRX64_REG(machInst, rt, rnsp, rm, + type, s * 3); + case 0x19: + return new LDRX64_REG(machInst, rt, rnsp, rm, + type, s * 3); + case 0x1a: + return new PRFM64_REG(machInst, rt, rnsp, rm, + type, s * 3); + case 0x1c: + return new STRDFP64_REG(machInst, rt, rnsp, rm, + type, s * 3); + case 0x1d: + return new LDRDFP64_REG(machInst, rt, rnsp, rm, + type, s * 3); + default: + return new Unknown64(machInst); + + } + } default: return new Unknown64(machInst); } diff --git a/src/arch/arm/isa/insts/ldr64.isa b/src/arch/arm/isa/insts/ldr64.isa index 8c966e40e..7c177263d 100644 --- a/src/arch/arm/isa/insts/ldr64.isa +++ b/src/arch/arm/isa/insts/ldr64.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2011-2014 ARM Limited +// Copyright (c) 2011-2014, 2017 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -416,6 +416,11 @@ let {{ LoadEx64("ldxrh", "LDXRH64", 2, flavor="exclusive").emit() LoadEx64("ldxrb", "LDXRB64", 1, flavor="exclusive").emit() + LoadRaw64("ldapr", "LDAPRX64", 8, flavor="acquire").emit() + LoadRaw64("ldapr", "LDAPRW64", 4, flavor="acquire").emit() + LoadRaw64("ldaprh", "LDAPRH64", 2, flavor="acquire").emit() + LoadRaw64("ldaprb", "LDAPRB64", 1, flavor="acquire").emit() + class LoadImmU64(LoadImm64): decConstBase = 'LoadStoreImmU64' micro = True -- cgit v1.2.3