summaryrefslogtreecommitdiff
path: root/src/arch/arm/insts/pred_inst.hh
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:12 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:12 -0500
commit7eb4d02dd9a008db32449f42037d670eab41f2c4 (patch)
treeb1177b2f8bc786bc2cca87dbaa7a0c42f50ca8cf /src/arch/arm/insts/pred_inst.hh
parentabda50173cee3c8a9fc080e07040c042b57cb4aa (diff)
downloadgem5-7eb4d02dd9a008db32449f42037d670eab41f2c4.tar.xz
ARM: Add a function to decode SIMD modified immediate constants.
Diffstat (limited to 'src/arch/arm/insts/pred_inst.hh')
-rw-r--r--src/arch/arm/insts/pred_inst.hh67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh
index 8f92a2f26..76d1029e8 100644
--- a/src/arch/arm/insts/pred_inst.hh
+++ b/src/arch/arm/insts/pred_inst.hh
@@ -77,6 +77,73 @@ modified_imm(uint8_t ctrlImm, uint8_t dataImm)
return bigData << (32 - bigCtrl);
}
+static inline uint64_t
+simd_modified_imm(bool op, uint8_t cmode, uint8_t data)
+{
+ uint64_t bigData = data;
+ switch (cmode) {
+ case 0x0:
+ case 0x1:
+ bigData = (bigData << 0) | (bigData << 32);
+ break;
+ case 0x2:
+ case 0x3:
+ bigData = (bigData << 8) | (bigData << 40);
+ break;
+ case 0x4:
+ case 0x5:
+ bigData = (bigData << 16) | (bigData << 48);
+ break;
+ case 0x6:
+ case 0x7:
+ bigData = (bigData << 24) | (bigData << 56);
+ break;
+ case 0x8:
+ case 0x9:
+ bigData = (bigData << 0) | (bigData << 16) |
+ (bigData << 32) | (bigData << 48);
+ break;
+ case 0xa:
+ case 0xb:
+ bigData = (bigData << 8) | (bigData << 24) |
+ (bigData << 40) | (bigData << 56);
+ break;
+ case 0xc:
+ bigData = (0xffULL << 0) | (bigData << 8) |
+ (0xffULL << 32) | (bigData << 40);
+ break;
+ case 0xd:
+ bigData = (0xffffULL << 0) | (bigData << 16) |
+ (0xffffULL << 32) | (bigData << 48);
+ break;
+ case 0xe:
+ if (op) {
+ bigData = (bigData << 0) | (bigData << 8) |
+ (bigData << 16) | (bigData << 24) |
+ (bigData << 32) | (bigData << 40) |
+ (bigData << 48) | (bigData << 56);
+ } else {
+ bigData = 0;
+ for (int i = 7; i >= 0; i--) {
+ if (bits(data, i)) {
+ bigData |= (0xFF << (i * 8));
+ }
+ }
+ }
+ case 0xf:
+ if (!op) {
+ uint64_t bVal = bits(bigData, 6) ? (0x1F) : (0x20);
+ bigData = (bits(bigData, 5, 0) << 19) |
+ (bVal << 25) | (bits(bigData, 7) << 31);
+ bigData |= (bigData << 32);
+ }
+ // Fall through
+ default:
+ panic("Illegal modified SIMD immediate parameters.\n");
+ }
+ return bigData;
+}
+
/**
* Base class for predicated integer operations.