1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating --- 32 unchanged lines hidden (view full) --- 41 42 header_output = "" 43 decoder_output = "" 44 exec_output = "" 45 46 # B, BL 47 for (mnem, link) in (("b", False), ("bl", True)): 48 bCode = ''' |
49 NPC = (uint32_t)(PC + imm); |
50 ''' 51 if (link): 52 bCode += ''' |
53 if (Thumb) 54 LR = PC | 1; |
55 else |
56 LR = PC - 4; |
57 ''' 58 59 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond", 60 {"code": bCode, 61 "predicate_test": predicateTest}) 62 header_output += BranchImmCondDeclare.subst(bIop) 63 decoder_output += BranchImmCondConstructor.subst(bIop) 64 exec_output += PredOpExecute.subst(bIop) 65 66 # BX, BLX 67 blxCode = ''' |
68 %(link)s 69 // Switch modes 70 %(branch)s |
71 ''' 72 73 blxList = (("blx", True, True), 74 ("blx", False, True), 75 ("bx", False, False)) 76 77 for (mnem, imm, link) in blxList: 78 Name = mnem.capitalize() 79 if imm: 80 Name += "Imm" 81 # Since we're switching ISAs, the target ISA will be the opposite |
82 # of the current ISA. Thumb is whether the target is ARM. 83 newPC = '(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))' |
84 base = "BranchImmCond" 85 declare = BranchImmCondDeclare 86 constructor = BranchImmCondConstructor 87 else: 88 Name += "Reg" 89 newPC = 'Op1' 90 base = "BranchRegCond" 91 declare = BranchRegCondDeclare 92 constructor = BranchRegCondConstructor 93 if link and imm: 94 linkStr = ''' 95 // The immediate version of the blx thumb instruction 96 // is 32 bits wide, but "next pc" doesn't reflect that 97 // so we don't want to substract 2 from it at this point |
98 if (Thumb) 99 LR = PC | 1; |
100 else |
101 LR = PC - 4; |
102 ''' 103 elif link: 104 linkStr = ''' |
105 if (Thumb) 106 LR = (PC - 2) | 1; |
107 else |
108 LR = PC - 4; |
109 ''' 110 else: 111 linkStr = "" 112 113 if imm and link: #blx with imm 114 branchStr = ''' |
115 NextThumb = !Thumb; 116 NPC = %(newPC)s; |
117 ''' 118 else: |
119 branchStr = "IWNPC = %(newPC)s;" |
120 branchStr = branchStr % { "newPC" : newPC } 121 122 code = blxCode % {"link": linkStr, 123 "newPC": newPC, 124 "branch": branchStr} 125 blxIop = InstObjParams(mnem, Name, base, 126 {"code": code, 127 "predicate_test": predicateTest}) 128 header_output += declare.subst(blxIop) 129 decoder_output += constructor.subst(blxIop) 130 exec_output += PredOpExecute.subst(blxIop) 131 132 #Ignore BXJ for now 133 134 #CBNZ, CBZ. These are always unconditional as far as predicates 135 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): |
136 code = 'NPC = (uint32_t)(PC + imm);\n' |
137 predTest = "Op1 %(test)s 0" % {"test": test} 138 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg", 139 {"code": code, "predicate_test": predTest}) 140 header_output += BranchImmRegDeclare.subst(iop) 141 decoder_output += BranchImmRegConstructor.subst(iop) 142 exec_output += PredOpExecute.subst(iop) 143 144 #TBB, TBH 145 for isTbh in (0, 1): 146 if isTbh: 147 eaCode = ''' 148 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 149 ArmISA::TLB::AlignHalfWord | 150 ArmISA::TLB::MustBeOne; 151 EA = Op1 + Op2 * 2 152 ''' |
153 accCode = 'NPC = PC + 2 * (Mem.uh);\n' |
154 mnem = "tbh" 155 else: 156 eaCode = ''' 157 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned | 158 ArmISA::TLB::AlignByte | 159 ArmISA::TLB::MustBeOne; 160 EA = Op1 + Op2 161 ''' |
162 accCode = 'NPC = PC + 2 * (Mem.ub)' |
163 mnem = "tbb" 164 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg", 165 {'ea_code': eaCode, 166 'memacc_code': accCode, 167 'predicate_test': predicateTest}) 168 header_output += BranchTableDeclare.subst(iop) 169 decoder_output += BranchRegRegConstructor.subst(iop) 170 exec_output += LoadExecute.subst(iop) + \ 171 LoadInitiateAcc.subst(iop) + \ 172 LoadCompleteAcc.subst(iop) 173}}; |