Deleted Added
sdiff udiff text old ( 6250:1cc6e860d95f ) new ( 6253:988a001820f8 )
full compact
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

--- 19 unchanged lines hidden (view full) ---

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 0x01: // L ldmda_l
62 start_addr = (ones << 2) - 4;
63 end_addr = 0;
64 break;
65 case 0x03: // WL ldmda_wl
66 start_addr = (ones << 2) - 4;
67 end_addr = 0;
68 break;
69 case 0x08: // U stmia_u
70 start_addr = 0;
71 end_addr = (ones << 2) - 4;
72 break;
73 case 0x09: // U L ldmia_ul
74 start_addr = 0;
75 end_addr = (ones << 2) - 4;
76 break;
77 case 0x0b: // U WL ldmia
78 start_addr = 0;
79 end_addr = (ones << 2) - 4;
80 break;
81 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
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
90 start_addr = 4;
91 end_addr = (ones << 2) + 4;
92 break;
93 case 0x19: // PU L ldmib
94 start_addr = 4;
95 end_addr = (ones << 2) + 4;
96 break;
97 default:
98 panic("Unhandled Load/Store Multiple Instruction");
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)

--- 16 unchanged lines hidden (view full) ---

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}};