1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// Macro Memory-format instructions 34// 35 36def template MacroStoreDeclare {{ 37/** 38 * Static instructions class for a store multiple instruction 39 */ 40class %(class_name)s : public %(base_class)s 41{ 42 public: 43 // Constructor 44 %(class_name)s(ExtMachInst machInst); 45 %(BasicExecDeclare)s 46}; 47}}; 48 49def template MacroStoreConstructor {{ 50inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 51 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 52{ 53 %(constructor)s; 54 uint32_t regs_to_handle = reglist; 55 uint32_t j = 0, 56 start_addr = 0, 57 end_addr = 0; 58 59 switch (puswl) 60 {
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// Macro Memory-format instructions 34// 35 36def template MacroStoreDeclare {{ 37/** 38 * Static instructions class for a store multiple instruction 39 */ 40class %(class_name)s : public %(base_class)s 41{ 42 public: 43 // Constructor 44 %(class_name)s(ExtMachInst machInst); 45 %(BasicExecDeclare)s 46}; 47}}; 48 49def template MacroStoreConstructor {{ 50inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 51 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 52{ 53 %(constructor)s; 54 uint32_t regs_to_handle = reglist; 55 uint32_t j = 0, 56 start_addr = 0, 57 end_addr = 0; 58 59 switch (puswl) 60 {
|
| 61 case 0x00: // stmda
|
61 case 0x01: // L ldmda_l
| 62 case 0x01: // L ldmda_l
|
62 start_addr = (ones << 2) - 4; 63 end_addr = 0; 64 break;
| 63 case 0x02: // W stmda_w
|
65 case 0x03: // WL ldmda_wl 66 start_addr = (ones << 2) - 4; 67 end_addr = 0; 68 break; 69 case 0x08: // U stmia_u
| 64 case 0x03: // WL ldmda_wl 65 start_addr = (ones << 2) - 4; 66 end_addr = 0; 67 break; 68 case 0x08: // U stmia_u
|
70 start_addr = 0; 71 end_addr = (ones << 2) - 4; 72 break;
| |
73 case 0x09: // U L ldmia_ul
| 69 case 0x09: // U L ldmia_ul
|
74 start_addr = 0; 75 end_addr = (ones << 2) - 4; 76 break;
| 70 case 0x0a: // U W stmia
|
77 case 0x0b: // U WL ldmia 78 start_addr = 0; 79 end_addr = (ones << 2) - 4; 80 break;
| 71 case 0x0b: // U WL ldmia 72 start_addr = 0; 73 end_addr = (ones << 2) - 4; 74 break;
|
| 75 case 0x10: // P stmdb
|
81 case 0x11: // P L ldmdb
| 76 case 0x11: // P L ldmdb
|
82 start_addr = (ones << 2); // U-bit is already 0 for subtract 83 end_addr = 4; // negative 4 84 break;
| |
85 case 0x12: // P W stmdb
| 77 case 0x12: // P W stmdb
|
| 78 case 0x13: // P WL ldmdb
|
86 start_addr = (ones << 2); // U-bit is already 0 for subtract 87 end_addr = 4; // negative 4 88 break; 89 case 0x18: // PU stmib
| 79 start_addr = (ones << 2); // U-bit is already 0 for subtract 80 end_addr = 4; // negative 4 81 break; 82 case 0x18: // PU stmib
|
90 start_addr = 4; 91 end_addr = (ones << 2) + 4; 92 break;
| |
93 case 0x19: // PU L ldmib
| 83 case 0x19: // PU L ldmib
|
| 84 case 0x1a: // PU W stmib 85 case 0x1b: // PU WL ldmib
|
94 start_addr = 4; 95 end_addr = (ones << 2) + 4; 96 break; 97 default:
| 86 start_addr = 4; 87 end_addr = (ones << 2) + 4; 88 break; 89 default:
|
98 panic("Unhandled Load/Store Multiple Instruction");
| 90 panic("Unhandled Load/Store Multiple Instruction, " 91 "puswl = 0x%x", (unsigned) puswl);
|
99 break; 100 } 101 102 //TODO - Add addi_uop/subi_uop here to create starting addresses 103 //Just using addi with 0 offset makes a "copy" of Rn for our use 104 uint32_t newMachInst = 0; 105 newMachInst = machInst & 0xffff0000; 106 microOps[0] = new Addi_uop(newMachInst); 107 108 for (int i = 1; i < ones+1; i++) 109 { 110 // Get next available bit for transfer 111 while (! ( regs_to_handle & (1<<j))) 112 j++; 113 regs_to_handle &= ~(1<<j); 114 115 microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); 116 117 if (up) 118 start_addr += 4; 119 else 120 start_addr -= 4; 121 } 122 123 /* TODO: Take a look at how these 2 values should meet together 124 if (start_addr != (end_addr - 4)) 125 { 126 fprintf(stderr, "start_addr: %d\n", start_addr); 127 fprintf(stderr, "end_addr: %d\n", end_addr); 128 panic("start_addr does not meet end_addr"); 129 } 130 */ 131 132 if (writeback) 133 { 134 uint32_t newMachInst = machInst & 0xf0000000; 135 uint32_t rn = (machInst >> 16) & 0x0f; 136 // 3322 2222 2222 1111 1111 11 137 // 1098 7654 3210 9876 5432 1098 7654 3210 138 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 139 // sub rn, rn, imm 140 newMachInst |= 0x02400000; 141 newMachInst |= ((rn << 16) | (rn << 12)); 142 newMachInst |= (ones << 2); 143 if (up) 144 { 145 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 146 } 147 else 148 { 149 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 150 } 151 } 152 microOps[numMicroops-1]->setLastMicroop(); 153} 154 155}}; 156 157def template MacroStoreExecute {{ 158Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 159{ 160 Fault fault = NoFault; 161 162 %(fp_enable_check)s; 163 %(op_decl)s; 164 %(op_rd)s; 165 %(code)s; 166 if (fault == NoFault) 167 { 168 %(op_wb)s; 169 } 170 171 return fault; 172} 173}}; 174 175def template MacroFPAConstructor {{ 176inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 177 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 178{ 179 %(constructor)s; 180 181 uint32_t start_addr = 0; 182 183 if (prepost) 184 start_addr = disp8; 185 else 186 start_addr = 0; 187 188 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr); 189 190 if (writeback) 191 { 192 uint32_t newMachInst = machInst & 0xf0000000; 193 uint32_t rn = (machInst >> 16) & 0x0f; 194 // 3322 2222 2222 1111 1111 11 195 // 1098 7654 3210 9876 5432 1098 7654 3210 196 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 197 // sub rn, rn, imm 198 newMachInst |= 0x02400000; 199 newMachInst |= ((rn << 16) | (rn << 12)); 200 if (up) 201 { 202 newMachInst |= disp8; 203 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 204 } 205 else 206 { 207 newMachInst |= disp8; 208 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 209 } 210 } 211 microOps[numMicroops-1]->setLastMicroop(); 212} 213 214}}; 215 216 217def template MacroFMConstructor {{ 218inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 219 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 220{ 221 %(constructor)s; 222 223 uint32_t start_addr = 0; 224 225 if (prepost) 226 start_addr = disp8; 227 else 228 start_addr = 0; 229 230 for (int i = 0; i < count; i++) 231 { 232 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); 233 } 234 235 if (writeback) 236 { 237 uint32_t newMachInst = machInst & 0xf0000000; 238 uint32_t rn = (machInst >> 16) & 0x0f; 239 // 3322 2222 2222 1111 1111 11 240 // 1098 7654 3210 9876 5432 1098 7654 3210 241 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 242 // sub rn, rn, imm 243 newMachInst |= 0x02400000; 244 newMachInst |= ((rn << 16) | (rn << 12)); 245 if (up) 246 { 247 newMachInst |= disp8; 248 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 249 } 250 else 251 { 252 newMachInst |= disp8; 253 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 254 } 255 } 256 microOps[numMicroops-1]->setLastMicroop(); 257} 258}}; 259 260 261def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 262 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags) 263 header_output = MacroStoreDeclare.subst(iop) 264 decoder_output = MacroStoreConstructor.subst(iop) 265 decode_block = BasicDecode.subst(iop) 266 exec_output = MacroStoreExecute.subst(iop) 267}}; 268 269def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 270 iop = InstObjParams(name, Name, 'ArmMacroFPAOp', 271 {"code": code, 272 "predicate_test": predicateTest}, 273 opt_flags) 274 header_output = BasicDeclare.subst(iop) 275 decoder_output = MacroFPAConstructor.subst(iop) 276 decode_block = BasicDecode.subst(iop) 277 exec_output = PredOpExecute.subst(iop) 278}}; 279 280def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 281 iop = InstObjParams(name, Name, 'ArmMacroFMOp', 282 {"code": code, 283 "predicate_test": predicateTest}, 284 opt_flags) 285 header_output = BasicDeclare.subst(iop) 286 decoder_output = MacroFMConstructor.subst(iop) 287 decode_block = BasicDecode.subst(iop) 288 exec_output = PredOpExecute.subst(iop) 289}};
| 92 break; 93 } 94 95 //TODO - Add addi_uop/subi_uop here to create starting addresses 96 //Just using addi with 0 offset makes a "copy" of Rn for our use 97 uint32_t newMachInst = 0; 98 newMachInst = machInst & 0xffff0000; 99 microOps[0] = new Addi_uop(newMachInst); 100 101 for (int i = 1; i < ones+1; i++) 102 { 103 // Get next available bit for transfer 104 while (! ( regs_to_handle & (1<<j))) 105 j++; 106 regs_to_handle &= ~(1<<j); 107 108 microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); 109 110 if (up) 111 start_addr += 4; 112 else 113 start_addr -= 4; 114 } 115 116 /* TODO: Take a look at how these 2 values should meet together 117 if (start_addr != (end_addr - 4)) 118 { 119 fprintf(stderr, "start_addr: %d\n", start_addr); 120 fprintf(stderr, "end_addr: %d\n", end_addr); 121 panic("start_addr does not meet end_addr"); 122 } 123 */ 124 125 if (writeback) 126 { 127 uint32_t newMachInst = machInst & 0xf0000000; 128 uint32_t rn = (machInst >> 16) & 0x0f; 129 // 3322 2222 2222 1111 1111 11 130 // 1098 7654 3210 9876 5432 1098 7654 3210 131 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 132 // sub rn, rn, imm 133 newMachInst |= 0x02400000; 134 newMachInst |= ((rn << 16) | (rn << 12)); 135 newMachInst |= (ones << 2); 136 if (up) 137 { 138 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 139 } 140 else 141 { 142 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 143 } 144 } 145 microOps[numMicroops-1]->setLastMicroop(); 146} 147 148}}; 149 150def template MacroStoreExecute {{ 151Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 152{ 153 Fault fault = NoFault; 154 155 %(fp_enable_check)s; 156 %(op_decl)s; 157 %(op_rd)s; 158 %(code)s; 159 if (fault == NoFault) 160 { 161 %(op_wb)s; 162 } 163 164 return fault; 165} 166}}; 167 168def template MacroFPAConstructor {{ 169inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 170 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 171{ 172 %(constructor)s; 173 174 uint32_t start_addr = 0; 175 176 if (prepost) 177 start_addr = disp8; 178 else 179 start_addr = 0; 180 181 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr); 182 183 if (writeback) 184 { 185 uint32_t newMachInst = machInst & 0xf0000000; 186 uint32_t rn = (machInst >> 16) & 0x0f; 187 // 3322 2222 2222 1111 1111 11 188 // 1098 7654 3210 9876 5432 1098 7654 3210 189 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 190 // sub rn, rn, imm 191 newMachInst |= 0x02400000; 192 newMachInst |= ((rn << 16) | (rn << 12)); 193 if (up) 194 { 195 newMachInst |= disp8; 196 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 197 } 198 else 199 { 200 newMachInst |= disp8; 201 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 202 } 203 } 204 microOps[numMicroops-1]->setLastMicroop(); 205} 206 207}}; 208 209 210def template MacroFMConstructor {{ 211inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 212 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 213{ 214 %(constructor)s; 215 216 uint32_t start_addr = 0; 217 218 if (prepost) 219 start_addr = disp8; 220 else 221 start_addr = 0; 222 223 for (int i = 0; i < count; i++) 224 { 225 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); 226 } 227 228 if (writeback) 229 { 230 uint32_t newMachInst = machInst & 0xf0000000; 231 uint32_t rn = (machInst >> 16) & 0x0f; 232 // 3322 2222 2222 1111 1111 11 233 // 1098 7654 3210 9876 5432 1098 7654 3210 234 // COND 0010 0100 [RN] [RD] 0000 [ IMM ] 235 // sub rn, rn, imm 236 newMachInst |= 0x02400000; 237 newMachInst |= ((rn << 16) | (rn << 12)); 238 if (up) 239 { 240 newMachInst |= disp8; 241 microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); 242 } 243 else 244 { 245 newMachInst |= disp8; 246 microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); 247 } 248 } 249 microOps[numMicroops-1]->setLastMicroop(); 250} 251}}; 252 253 254def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 255 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags) 256 header_output = MacroStoreDeclare.subst(iop) 257 decoder_output = MacroStoreConstructor.subst(iop) 258 decode_block = BasicDecode.subst(iop) 259 exec_output = MacroStoreExecute.subst(iop) 260}}; 261 262def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 263 iop = InstObjParams(name, Name, 'ArmMacroFPAOp', 264 {"code": code, 265 "predicate_test": predicateTest}, 266 opt_flags) 267 header_output = BasicDeclare.subst(iop) 268 decoder_output = MacroFPAConstructor.subst(iop) 269 decode_block = BasicDecode.subst(iop) 270 exec_output = PredOpExecute.subst(iop) 271}}; 272 273def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ 274 iop = InstObjParams(name, Name, 'ArmMacroFMOp', 275 {"code": code, 276 "predicate_test": predicateTest}, 277 opt_flags) 278 header_output = BasicDeclare.subst(iop) 279 decoder_output = MacroFMConstructor.subst(iop) 280 decode_block = BasicDecode.subst(iop) 281 exec_output = PredOpExecute.subst(iop) 282}};
|