branch.isa revision 7605
12968SN/A// -*- mode:c++ -*- 22968SN/A 35520SN/A// Copyright (c) 2010 ARM Limited 45520SN/A// All rights reserved 58721SN/A// 68721SN/A// The license below extends only to copyright in the software and shall 79079SAli.Saidi@ARM.com// not be construed as granting a license to any other intellectual 89079SAli.Saidi@ARM.com// property including but not limited to intellectual property relating 99079SAli.Saidi@ARM.com// to a hardware implementation of the functionality of the software 109079SAli.Saidi@ARM.com// licensed hereunder. You may use the software subject to the license 119079SAli.Saidi@ARM.com// terms below provided that you ensure that this notice is replicated 128721SN/A// unmodified and in its entirety in all distributions of the software, 138835SAli.Saidi@ARM.com// modified or unmodified, in source code or in binary form. 149079SAli.Saidi@ARM.com// 159079SAli.Saidi@ARM.com// Copyright (c) 2007-2008 The Florida State University 169055Ssaidi@eecs.umich.edu// All rights reserved. 179079SAli.Saidi@ARM.com// 189079SAli.Saidi@ARM.com// Redistribution and use in source and binary forms, with or without 199079SAli.Saidi@ARM.com// modification, are permitted provided that the following conditions are 209079SAli.Saidi@ARM.com// met: redistributions of source code must retain the above copyright 219079SAli.Saidi@ARM.com// notice, this list of conditions and the following disclaimer; 229079SAli.Saidi@ARM.com// redistributions in binary form must reproduce the above copyright 239079SAli.Saidi@ARM.com// notice, this list of conditions and the following disclaimer in the 249079SAli.Saidi@ARM.com// documentation and/or other materials provided with the distribution; 259079SAli.Saidi@ARM.com// neither the name of the copyright holders nor the names of its 269079SAli.Saidi@ARM.com// contributors may be used to endorse or promote products derived from 279055Ssaidi@eecs.umich.edu// this software without specific prior written permission. 289079SAli.Saidi@ARM.com// 299079SAli.Saidi@ARM.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 309079SAli.Saidi@ARM.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 319079SAli.Saidi@ARM.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 329079SAli.Saidi@ARM.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 339079SAli.Saidi@ARM.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 349079SAli.Saidi@ARM.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 359055Ssaidi@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 369079SAli.Saidi@ARM.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 379079SAli.Saidi@ARM.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 389079SAli.Saidi@ARM.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 399079SAli.Saidi@ARM.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 409079SAli.Saidi@ARM.com// 419079SAli.Saidi@ARM.com// Authors: Stephen Hines 429079SAli.Saidi@ARM.com 439079SAli.Saidi@ARM.com//////////////////////////////////////////////////////////////////// 449079SAli.Saidi@ARM.com// 459079SAli.Saidi@ARM.com// Control transfer instructions 469079SAli.Saidi@ARM.com// 479055Ssaidi@eecs.umich.edu 489079SAli.Saidi@ARM.comdef format ArmBBlxImm() {{ 499079SAli.Saidi@ARM.com decode_block = ''' 509079SAli.Saidi@ARM.com if (machInst.condCode == 0xF) { 519079SAli.Saidi@ARM.com int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) | 529079SAli.Saidi@ARM.com (bits(machInst, 24) << 1); 539079SAli.Saidi@ARM.com return new BlxImm(machInst, imm, COND_UC); 549079SAli.Saidi@ARM.com } else { 559079SAli.Saidi@ARM.com return new B(machInst, sext<26>(bits(machInst, 23, 0) << 2), 569079SAli.Saidi@ARM.com (ConditionCode)(uint32_t)machInst.condCode); 579079SAli.Saidi@ARM.com } 589079SAli.Saidi@ARM.com ''' 599079SAli.Saidi@ARM.com}}; 609079SAli.Saidi@ARM.com 619079SAli.Saidi@ARM.comdef format ArmBlBlxImm() {{ 629079SAli.Saidi@ARM.com decode_block = ''' 639079SAli.Saidi@ARM.com if (machInst.condCode == 0xF) { 649079SAli.Saidi@ARM.com int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) | 659079SAli.Saidi@ARM.com (bits(machInst, 24) << 1); 669079SAli.Saidi@ARM.com return new BlxImm(machInst, imm, COND_UC); 679079SAli.Saidi@ARM.com } else { 689079SAli.Saidi@ARM.com return new Bl(machInst, sext<26>(bits(machInst, 23, 0) << 2), 699079SAli.Saidi@ARM.com (ConditionCode)(uint32_t)machInst.condCode); 709079SAli.Saidi@ARM.com } 719079SAli.Saidi@ARM.com ''' 729079SAli.Saidi@ARM.com}}; 739079SAli.Saidi@ARM.com 749079SAli.Saidi@ARM.comdef format ArmBxClz() {{ 759079SAli.Saidi@ARM.com decode_block = ''' 769079SAli.Saidi@ARM.com { 779079SAli.Saidi@ARM.com const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 789079SAli.Saidi@ARM.com const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 798835SAli.Saidi@ARM.com if (OPCODE == 0x9) { 809079SAli.Saidi@ARM.com return new BxReg(machInst, rm, 819079SAli.Saidi@ARM.com (ConditionCode)(uint32_t)machInst.condCode); 829079SAli.Saidi@ARM.com } else if (OPCODE == 0xb) { 839079SAli.Saidi@ARM.com return new Clz(machInst, rd, rm); 849079SAli.Saidi@ARM.com } else { 859079SAli.Saidi@ARM.com return new Unknown(machInst); 869079SAli.Saidi@ARM.com } 879079SAli.Saidi@ARM.com } 889079SAli.Saidi@ARM.com ''' 899079SAli.Saidi@ARM.com}}; 909079SAli.Saidi@ARM.com 919079SAli.Saidi@ARM.comdef format ArmBlxReg() {{ 929079SAli.Saidi@ARM.com decode_block = ''' 939079SAli.Saidi@ARM.com return new BlxReg(machInst, (IntRegIndex)(uint32_t)bits(machInst, 3, 0), 949079SAli.Saidi@ARM.com (ConditionCode)(uint32_t)machInst.condCode); 959079SAli.Saidi@ARM.com ''' 969079SAli.Saidi@ARM.com}}; 979079SAli.Saidi@ARM.com 989079SAli.Saidi@ARM.comdef format Thumb16CondBranchAndSvc() {{ 999079SAli.Saidi@ARM.com decode_block = ''' 1009079SAli.Saidi@ARM.com if (bits(machInst, 11, 9) != 0x7) { 1019079SAli.Saidi@ARM.com return new B(machInst, sext<9>(bits(machInst, 7, 0) << 1), 1028835SAli.Saidi@ARM.com (ConditionCode)(uint32_t)bits(machInst, 11, 8)); 1039079SAli.Saidi@ARM.com } else if (bits(machInst, 8)) { 1049079SAli.Saidi@ARM.com return new Svc(machInst); 1059079SAli.Saidi@ARM.com } else { 1069079SAli.Saidi@ARM.com // This space will not be allocated in the future. 1079079SAli.Saidi@ARM.com return new Unknown(machInst); 1089079SAli.Saidi@ARM.com } 1099079SAli.Saidi@ARM.com ''' 1109079SAli.Saidi@ARM.com}}; 1119079SAli.Saidi@ARM.com 1129079SAli.Saidi@ARM.comdef format Thumb16UncondBranch() {{ 1139079SAli.Saidi@ARM.com decode_block = ''' 1149079SAli.Saidi@ARM.com return new B(machInst, sext<12>(bits(machInst, 10, 0) << 1), COND_UC); 1159079SAli.Saidi@ARM.com ''' 1169079SAli.Saidi@ARM.com}}; 1179079SAli.Saidi@ARM.com 1188835SAli.Saidi@ARM.comdef format Thumb32BranchesAndMiscCtrl() {{ 1199079SAli.Saidi@ARM.com decode_block = ''' 1208835SAli.Saidi@ARM.com { 1219079SAli.Saidi@ARM.com const uint32_t op = bits(machInst, 26, 20); 1229079SAli.Saidi@ARM.com const uint32_t op1 = bits(machInst, 14, 12); 1239079SAli.Saidi@ARM.com switch (op1 & 0x5) { 1249079SAli.Saidi@ARM.com case 0x0: 1258835SAli.Saidi@ARM.com if (op == 127) { 1268835SAli.Saidi@ARM.com if (op1 & 0x2) { 1278721SN/A // Permanently undefined. 1289079SAli.Saidi@ARM.com return new Unknown(machInst); 1299079SAli.Saidi@ARM.com } else { 1309079SAli.Saidi@ARM.com return new WarnUnimplemented("smc", machInst); 1319079SAli.Saidi@ARM.com } 1329079SAli.Saidi@ARM.com } else if ((op & 0x38) != 0x38) { 1339079SAli.Saidi@ARM.com const uint32_t s = bits(machInst, 26); 1348835SAli.Saidi@ARM.com const uint32_t j1 = bits(machInst, 13); 1359079SAli.Saidi@ARM.com const uint32_t j2 = bits(machInst, 11); 1368835SAli.Saidi@ARM.com const uint32_t imm6 = bits(machInst, 21, 16); 1379079SAli.Saidi@ARM.com const uint32_t imm11 = bits(machInst, 10, 0); 1389079SAli.Saidi@ARM.com const int32_t imm = sext<21>((s << 20) | 1398835SAli.Saidi@ARM.com (j2 << 19) | (j1 << 18) | 1409079SAli.Saidi@ARM.com (imm6 << 12) | (imm11 << 1)); 1418835SAli.Saidi@ARM.com return new B(machInst, imm, 1429079SAli.Saidi@ARM.com (ConditionCode)(uint32_t)bits(machInst, 25, 22)); 1439079SAli.Saidi@ARM.com } else { 1449079SAli.Saidi@ARM.com switch (op) { 1459079SAli.Saidi@ARM.com case 0x38: 1469079SAli.Saidi@ARM.com { 1479079SAli.Saidi@ARM.com const IntRegIndex rn = 1489079SAli.Saidi@ARM.com (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1499079SAli.Saidi@ARM.com const uint8_t byteMask = bits(machInst, 11, 8); 1509079SAli.Saidi@ARM.com return new MsrCpsrReg(machInst, rn, byteMask); 1519079SAli.Saidi@ARM.com } 1529079SAli.Saidi@ARM.com case 0x39: 1539079SAli.Saidi@ARM.com { 1549079SAli.Saidi@ARM.com const IntRegIndex rn = 1559079SAli.Saidi@ARM.com (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1569079SAli.Saidi@ARM.com const uint8_t byteMask = bits(machInst, 11, 8); 1579079SAli.Saidi@ARM.com return new MsrSpsrReg(machInst, rn, byteMask); 1589079SAli.Saidi@ARM.com } 1599079SAli.Saidi@ARM.com case 0x3a: 1609079SAli.Saidi@ARM.com { 1619079SAli.Saidi@ARM.com const uint32_t op1 = bits(machInst, 10, 8); 1629079SAli.Saidi@ARM.com const uint32_t op2 = bits(machInst, 7, 0); 1639079SAli.Saidi@ARM.com if (op1 != 0) { 1649079SAli.Saidi@ARM.com const bool enable = bits(machInst, 10, 9) == 0x2; 1659079SAli.Saidi@ARM.com const uint32_t mods = bits(machInst, 8, 0) | 1669079SAli.Saidi@ARM.com ((enable ? 1 : 0) << 9); 1679079SAli.Saidi@ARM.com return new Cps(machInst, mods); 1688721SN/A } else if ((op2 & 0xf0) == 0xf0) { 1698721SN/A return new WarnUnimplemented("dbg", machInst); 1708721SN/A } else { 1718721SN/A switch (op2) { 1728983Snate@binkert.org case 0x0: 1738983Snate@binkert.org return new NopInst(machInst); 1748721SN/A case 0x1: 1758721SN/A return new YieldInst(machInst); 1769079SAli.Saidi@ARM.com case 0x2: 1779079SAli.Saidi@ARM.com return new WfeInst(machInst); 1788721SN/A case 0x3: 1798721SN/A return new WfiInst(machInst); 1808721SN/A case 0x4: 1818721SN/A return new SevInst(machInst); 1828721SN/A default: 1838721SN/A break; 1848721SN/A } 1858835SAli.Saidi@ARM.com } 1868835SAli.Saidi@ARM.com break; 1878835SAli.Saidi@ARM.com } 1888835SAli.Saidi@ARM.com case 0x3b: 1898721SN/A { 1908835SAli.Saidi@ARM.com const uint32_t op = bits(machInst, 7, 4); 1918721SN/A switch (op) { 1928835SAli.Saidi@ARM.com case 0x0: 1938721SN/A return new Leavex(machInst); 1948835SAli.Saidi@ARM.com case 0x1: 1958721SN/A return new Enterx(machInst); 1968835SAli.Saidi@ARM.com case 0x2: 1978721SN/A return new Clrex(machInst); 1988835SAli.Saidi@ARM.com case 0x4: 1998721SN/A return new Dsb(machInst); 2008835SAli.Saidi@ARM.com case 0x5: 2018721SN/A return new Dmb(machInst); 2028835SAli.Saidi@ARM.com case 0x6: 2038721SN/A return new Isb(machInst); 2048835SAli.Saidi@ARM.com default: 2059055Ssaidi@eecs.umich.edu break; 2068835SAli.Saidi@ARM.com } 2079055Ssaidi@eecs.umich.edu break; 2088835SAli.Saidi@ARM.com } 2099055Ssaidi@eecs.umich.edu case 0x3c: 2108835SAli.Saidi@ARM.com { 2119055Ssaidi@eecs.umich.edu // On systems that don't support bxj, bxj == bx 2128721SN/A return new BxReg(machInst, 2138721SN/A (IntRegIndex)(uint32_t)bits(machInst, 19, 16), 2148721SN/A COND_UC); 2158721SN/A } 2168983Snate@binkert.org case 0x3d: 2178983Snate@binkert.org { 2188721SN/A const uint32_t imm32 = bits(machInst, 7, 0); 2198721SN/A return new SubsImmPclr(machInst, INTREG_PC, INTREG_LR, 2208835SAli.Saidi@ARM.com imm32, false); 2218835SAli.Saidi@ARM.com } 2228721SN/A case 0x3e: 2238721SN/A { 2248721SN/A const IntRegIndex rd = 2258721SN/A (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 2268721SN/A return new MrsCpsr(machInst, rd); 2278721SN/A } 2288721SN/A case 0x3f: 2298721SN/A { 2308721SN/A const IntRegIndex rd = 2318721SN/A (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 2328721SN/A return new MrsSpsr(machInst, rd); 2338721SN/A } 2348721SN/A } 2358721SN/A break; 2368721SN/A } 2378721SN/A case 0x1: 2388721SN/A { 2398721SN/A ConditionCode condCode; 2408721SN/A if(machInst.itstateMask) { 2418721SN/A condCode = (ConditionCode)(uint8_t)machInst.itstateCond; 2428721SN/A } else { 2438721SN/A condCode = COND_UC; 2448721SN/A } 2458721SN/A 2468721SN/A const uint32_t s = bits(machInst, 26); 2476024SN/A const uint32_t i1 = !(bits(machInst, 13) ^ s); 2486024SN/A const uint32_t i2 = !(bits(machInst, 11) ^ s); 2498721SN/A const uint32_t imm10 = bits(machInst, 25, 16); 2508721SN/A const uint32_t imm11 = bits(machInst, 10, 0); 2518721SN/A const int32_t imm = sext<25>((s << 24) | 2528721SN/A (i1 << 23) | (i2 << 22) | 2538721SN/A (imm10 << 12) | (imm11 << 1)); 2548721SN/A return new B(machInst, imm, condCode); 2558721SN/A } 2568721SN/A case 0x4: 2578721SN/A { 2588721SN/A if (bits(machInst, 0) == 1) { 2598721SN/A return new Unknown(machInst); 2608721SN/A } 2618721SN/A ConditionCode condCode; 2628721SN/A if(machInst.itstateMask) { 2636024SN/A condCode = (ConditionCode)(uint8_t)machInst.itstateCond; 2646024SN/A } else { 2658721SN/A condCode = COND_UC; 2668721SN/A } 2678721SN/A const uint32_t s = bits(machInst, 26); 2688721SN/A const uint32_t i1 = !(bits(machInst, 13) ^ s); 2698721SN/A const uint32_t i2 = !(bits(machInst, 11) ^ s); 2708835SAli.Saidi@ARM.com const uint32_t imm10h = bits(machInst, 25, 16); 2718835SAli.Saidi@ARM.com const uint32_t imm10l = bits(machInst, 10, 1); 2728721SN/A const int32_t imm = sext<25>((s << 24) | 2738721SN/A (i1 << 23) | (i2 << 22) | 2748721SN/A (imm10h << 12) | (imm10l << 2)); 2758721SN/A return new BlxImm(machInst, imm, condCode); 2768721SN/A } 2778721SN/A case 0x5: 2788721SN/A { 2798721SN/A ConditionCode condCode; 2808721SN/A if(machInst.itstateMask) { 2818721SN/A condCode = (ConditionCode)(uint8_t)machInst.itstateCond; 2828721SN/A } else { 2838721SN/A condCode = COND_UC; 2848721SN/A } 2858721SN/A const uint32_t s = bits(machInst, 26); 2868721SN/A const uint32_t i1 = !(bits(machInst, 13) ^ s); 2878721SN/A const uint32_t i2 = !(bits(machInst, 11) ^ s); 2888721SN/A const uint32_t imm10 = bits(machInst, 25, 16); 2892968SN/A const uint32_t imm11 = bits(machInst, 10, 0); 2908721SN/A const int32_t imm = sext<25>((s << 24) | 2915778SN/A (i1 << 23) | (i2 << 22) | 2926291SN/A (imm10 << 12) | (imm11 << 1)); 2936291SN/A return new Bl(machInst, imm, condCode); 2946291SN/A } 2956291SN/A default: 2966291SN/A break; 2976127SN/A } 2986291SN/A return new Unknown(machInst); 2996291SN/A } 3006291SN/A ''' 3016291SN/A}}; 3026291SN/A