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