summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/formats/fp.isa
diff options
context:
space:
mode:
authorARM gem5 Developers <none@none>2014-01-24 15:29:34 -0600
committerARM gem5 Developers <none@none>2014-01-24 15:29:34 -0600
commit612f8f074fa1099cf70faf495d46cc647762a031 (patch)
treebd1e99c43bf15292395eadd4b7ae3f5c823545c3 /src/arch/arm/isa/formats/fp.isa
parentf3585c841e964c98911784a187fc4f081a02a0a6 (diff)
downloadgem5-612f8f074fa1099cf70faf495d46cc647762a031.tar.xz
arm: Add support for ARMv8 (AArch64 & AArch32)
Note: AArch64 and AArch32 interworking is not supported. If you use an AArch64 kernel you are restricted to AArch64 user-mode binaries. This will be addressed in a later patch. Note: Virtualization is only supported in AArch32 mode. This will also be fixed in a later patch. Contributors: Giacomo Gabrielli (TrustZone, LPAE, system-level AArch64, AArch64 NEON, validation) Thomas Grocutt (AArch32 Virtualization, AArch64 FP, validation) Mbou Eyole (AArch64 NEON, validation) Ali Saidi (AArch64 Linux support, code integration, validation) Edmund Grimley-Evans (AArch64 FP) William Wang (AArch64 Linux support) Rene De Jong (AArch64 Linux support, performance opt.) Matt Horsnell (AArch64 MP, validation) Matt Evans (device models, code integration, validation) Chris Adeniyi-Jones (AArch64 syscall-emulation) Prakash Ramrakhyani (validation) Dam Sunwoo (validation) Chander Sudanthi (validation) Stephan Diestelhorst (validation) Andreas Hansson (code integration, performance opt.) Eric Van Hensbergen (performance opt.) Gabe Black
Diffstat (limited to 'src/arch/arm/isa/formats/fp.isa')
-rw-r--r--src/arch/arm/isa/formats/fp.isa103
1 files changed, 81 insertions, 22 deletions
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index 6d779e541..ccd4589a3 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
-// Copyright (c) 2010 ARM Limited
+// Copyright (c) 2010-2011 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -151,8 +151,7 @@ let {{
if (singleAll) {
size = bits(machInst, 7, 6);
bool t = bits(machInst, 5);
- unsigned eBytes = (1 << size);
- align = (eBytes - 1) | TLB::AllowUnaligned;
+ align = size | TLB::AllowUnaligned;
if (width == 1) {
regs = t ? 2 : 1;
inc = 1;
@@ -164,7 +163,7 @@ let {{
case 1:
case 2:
if (bits(machInst, 4))
- align = width * eBytes - 1;
+ align = size + width - 1;
break;
case 3:
break;
@@ -173,20 +172,19 @@ let {{
if (bits(machInst, 4) == 0)
return new Unknown(machInst);
size = 2;
- align = 0xf;
+ align = 0x4;
} else if (size == 2) {
if (bits(machInst, 4))
- align = 7;
+ align = 0x3;
} else {
if (bits(machInst, 4))
- align = 4 * eBytes - 1;
+ align = size + 2;
}
break;
}
} else {
size = bits(machInst, 11, 10);
- unsigned eBytes = (1 << size);
- align = (eBytes - 1) | TLB::AllowUnaligned;
+ align = size | TLB::AllowUnaligned;
regs = width;
unsigned indexAlign = bits(machInst, 7, 4);
// If width is 1, inc is always 1. That's overridden later.
@@ -219,13 +217,13 @@ let {{
break;
case 2:
if (bits(indexAlign, 1, 0))
- align = 3;
+ align = 2;
break;
}
break;
case 2:
if (bits(indexAlign, 0))
- align = (2 * eBytes) - 1;
+ align = size + 1;
break;
case 3:
break;
@@ -234,11 +232,11 @@ let {{
case 0:
case 1:
if (bits(indexAlign, 0))
- align = (4 * eBytes) - 1;
+ align = size + 2;
break;
case 2:
if (bits(indexAlign, 0))
- align = (4 << bits(indexAlign, 1, 0)) - 1;
+ align = bits(indexAlign, 1, 0) + 2;
break;
}
break;
@@ -252,9 +250,9 @@ let {{
align = bits(machInst, 5, 4);
if (align == 0) {
// @align wasn't specified, so alignment can be turned off.
- align = ((1 << size) - 1) | TLB::AllowUnaligned;
+ align = size | TLB::AllowUnaligned;
} else {
- align = ((4 << align) - 1);
+ align = align + 2;
}
switch (width) {
case 1:
@@ -588,6 +586,23 @@ let {{
}
}
case 0xc:
+ if (b) {
+ if (!u) {
+ if (bits(c, 1) == 0) {
+ if (q) {
+ return new NVfmaQFp<float>(machInst, vd, vn, vm);
+ } else {
+ return new NVfmaDFp<float>(machInst, vd, vn, vm);
+ }
+ } else {
+ if (q) {
+ return new NVfmsQFp<float>(machInst, vd, vn, vm);
+ } else {
+ return new NVfmsDFp<float>(machInst, vd, vn, vm);
+ }
+ }
+ }
+ }
return new Unknown(machInst);
case 0xd:
if (b) {
@@ -1827,7 +1842,7 @@ let {{
break;
case 0x1:
{
- if (offset == 0 || vd + offset/2 > NumFloatArchRegs) {
+ if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) {
break;
}
switch (bits(opcode, 1, 0)) {
@@ -1951,8 +1966,9 @@ let {{
} else if (a == 0x7) {
const IntRegIndex rt =
(IntRegIndex)(uint32_t)bits(machInst, 15, 12);
- uint32_t specReg = bits(machInst, 19, 16);
- switch (specReg) {
+ uint32_t reg = bits(machInst, 19, 16);
+ uint32_t specReg;
+ switch (reg) {
case 0:
specReg = MISCREG_FPSID;
break;
@@ -1974,7 +1990,9 @@ let {{
if (specReg == MISCREG_FPSCR) {
return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt);
} else {
- return new Vmsr(machInst, (IntRegIndex)specReg, rt);
+ uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt,
+ reg, a, bits(machInst, 7, 5));
+ return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss);
}
}
} else if (l == 0 && c == 1) {
@@ -2041,8 +2059,9 @@ let {{
} else if (a == 7) {
const IntRegIndex rt =
(IntRegIndex)(uint32_t)bits(machInst, 15, 12);
- uint32_t specReg = bits(machInst, 19, 16);
- switch (specReg) {
+ uint32_t reg = bits(machInst, 19, 16);
+ uint32_t specReg;
+ switch (reg) {
case 0:
specReg = MISCREG_FPSID;
break;
@@ -2070,7 +2089,9 @@ let {{
} else if (specReg == MISCREG_FPSCR) {
return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg);
} else {
- return new Vmrs(machInst, rt, (IntRegIndex)specReg);
+ uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt,
+ reg, a, bits(machInst, 7, 5));
+ return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss);
}
}
} else {
@@ -2235,6 +2256,44 @@ let {{
}
}
break;
+ case 0x9:
+ if ((opc3 & 0x1) == 0) {
+ if (single) {
+ return decodeVfpRegRegRegOp<VfnmaS>(
+ machInst, vd, vn, vm, false);
+ } else {
+ return decodeVfpRegRegRegOp<VfnmaD>(
+ machInst, vd, vn, vm, true);
+ }
+ } else {
+ if (single) {
+ return decodeVfpRegRegRegOp<VfnmsS>(
+ machInst, vd, vn, vm, false);
+ } else {
+ return decodeVfpRegRegRegOp<VfnmsD>(
+ machInst, vd, vn, vm, true);
+ }
+ }
+ break;
+ case 0xa:
+ if ((opc3 & 0x1) == 0) {
+ if (single) {
+ return decodeVfpRegRegRegOp<VfmaS>(
+ machInst, vd, vn, vm, false);
+ } else {
+ return decodeVfpRegRegRegOp<VfmaD>(
+ machInst, vd, vn, vm, true);
+ }
+ } else {
+ if (single) {
+ return decodeVfpRegRegRegOp<VfmsS>(
+ machInst, vd, vn, vm, false);
+ } else {
+ return decodeVfpRegRegRegOp<VfmsD>(
+ machInst, vd, vn, vm, true);
+ }
+ }
+ break;
case 0xb:
if ((opc3 & 0x1) == 0) {
const uint32_t baseImm =