The bitbang driver leaves the TCK 0 when in idle
[openocd.git] / src / target / arm_simulator.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "target.h"
25 #include "armv4_5.h"
26 #include "arm_disassembler.h"
27 #include "arm_simulator.h"
28 #include "log.h"
29 #include "binarybuffer.h"
30
31 #include <string.h>
32
33 u32 arm_shift(u8 shift, u32 Rm, u32 shift_amount, u8 *carry)
34 {
35 u32 return_value = 0;
36 shift_amount &= 0xff;
37
38 if (shift == 0x0) /* LSL */
39 {
40 if ((shift_amount > 0) && (shift_amount <= 32))
41 {
42 return_value = Rm << shift_amount;
43 *carry = Rm >> (32 - shift_amount);
44 }
45 else if (shift_amount > 32)
46 {
47 return_value = 0x0;
48 *carry = 0x0;
49 }
50 else /* (shift_amount == 0) */
51 {
52 return_value = Rm;
53 }
54 }
55 else if (shift == 0x1) /* LSR */
56 {
57 if ((shift_amount > 0) && (shift_amount <= 32))
58 {
59 return_value = Rm >> shift_amount;
60 *carry = (Rm >> (shift_amount - 1)) & 1;
61 }
62 else if (shift_amount > 32)
63 {
64 return_value = 0x0;
65 *carry = 0x0;
66 }
67 else /* (shift_amount == 0) */
68 {
69 return_value = Rm;
70 }
71 }
72 else if (shift == 0x2) /* ASR */
73 {
74 if ((shift_amount > 0) && (shift_amount <= 32))
75 {
76 /* right shifts of unsigned values are guaranteed to be logical (shift in zeroes)
77 * simulate an arithmetic shift (shift in signed-bit) by adding the signed-bit manually */
78 return_value = Rm >> shift_amount;
79 if (Rm & 0x80000000)
80 return_value |= 0xffffffff << (32 - shift_amount);
81 }
82 else if (shift_amount > 32)
83 {
84 if (Rm & 0x80000000)
85 {
86 return_value = 0xffffffff;
87 *carry = 0x1;
88 }
89 else
90 {
91 return_value = 0x0;
92 *carry = 0x0;
93 }
94 }
95 else /* (shift_amount == 0) */
96 {
97 return_value = Rm;
98 }
99 }
100 else if (shift == 0x3) /* ROR */
101 {
102 if (shift_amount == 0)
103 {
104 return_value = Rm;
105 }
106 else
107 {
108 shift_amount = shift_amount % 32;
109 return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount));
110 *carry = (return_value >> 31) & 0x1;
111 }
112 }
113 else if (shift == 0x4) /* RRX */
114 {
115 return_value = Rm >> 1;
116 if (*carry)
117 Rm |= 0x80000000;
118 *carry = Rm & 0x1;
119 }
120
121 return return_value;
122 }
123
124 u32 arm_shifter_operand(armv4_5_common_t *armv4_5, int variant, union arm_shifter_operand shifter_operand, u8 *shifter_carry_out)
125 {
126 u32 return_value;
127 int instruction_size;
128
129 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
130 instruction_size = 4;
131 else
132 instruction_size = 2;
133
134 *shifter_carry_out = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
135
136 if (variant == 0) /* 32-bit immediate */
137 {
138 return_value = shifter_operand.immediate.immediate;
139 }
140 else if (variant == 1) /* immediate shift */
141 {
142 u32 Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.immediate_shift.Rm).value, 0, 32);
143
144 /* adjust RM in case the PC is being read */
145 if (shifter_operand.immediate_shift.Rm == 15)
146 Rm += 2 * instruction_size;
147
148 return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, shifter_operand.immediate_shift.shift_imm, shifter_carry_out);
149 }
150 else if (variant == 2) /* register shift */
151 {
152 u32 Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rm).value, 0, 32);
153 u32 Rs = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rs).value, 0, 32);
154
155 /* adjust RM in case the PC is being read */
156 if (shifter_operand.register_shift.Rm == 15)
157 Rm += 2 * instruction_size;
158
159 return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, Rs, shifter_carry_out);
160 }
161 else
162 {
163 ERROR("BUG: shifter_operand.variant not 0, 1 or 2");
164 return_value = 0xffffffff;
165 }
166
167 return return_value;
168 }
169
170 int pass_condition(u32 cpsr, u32 opcode)
171 {
172 switch ((opcode & 0xf0000000) >> 28)
173 {
174 case 0x0: /* EQ */
175 if (cpsr & 0x40000000)
176 return 1;
177 else
178 return 0;
179 case 0x1: /* NE */
180 if (!(cpsr & 0x40000000))
181 return 1;
182 else
183 return 0;
184 case 0x2: /* CS */
185 if (cpsr & 0x20000000)
186 return 1;
187 else
188 return 0;
189 case 0x3: /* CC */
190 if (!(cpsr & 0x20000000))
191 return 1;
192 else
193 return 0;
194 case 0x4: /* MI */
195 if (cpsr & 0x80000000)
196 return 1;
197 else
198 return 0;
199 case 0x5: /* PL */
200 if (!(cpsr & 0x80000000))
201 return 1;
202 else
203 return 0;
204 case 0x6: /* VS */
205 if (cpsr & 0x10000000)
206 return 1;
207 else
208 return 0;
209 case 0x7: /* VC */
210 if (!(cpsr & 0x10000000))
211 return 1;
212 else
213 return 0;
214 case 0x8: /* HI */
215 if ((cpsr & 0x20000000) && !(cpsr & 0x40000000))
216 return 1;
217 else
218 return 0;
219 case 0x9: /* LS */
220 if (!(cpsr & 0x20000000) || (cpsr & 0x40000000))
221 return 1;
222 else
223 return 0;
224 case 0xa: /* GE */
225 if (((cpsr & 0x80000000) && (cpsr & 0x10000000))
226 || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000)))
227 return 1;
228 else
229 return 0;
230 case 0xb: /* LT */
231 if (((cpsr & 0x80000000) && !(cpsr & 0x10000000))
232 || (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))
233 return 1;
234 else
235 return 0;
236 case 0xc: /* GT */
237 if (!(cpsr & 0x40000000) &&
238 (((cpsr & 0x80000000) && (cpsr & 0x10000000))
239 || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000))))
240 return 1;
241 else
242 return 0;
243 case 0xd: /* LE */
244 if ((cpsr & 0x40000000) &&
245 (((cpsr & 0x80000000) && !(cpsr & 0x10000000))
246 || (!(cpsr & 0x80000000) && (cpsr & 0x10000000))))
247 return 1;
248 else
249 return 0;
250 case 0xe:
251 case 0xf:
252 return 1;
253
254 }
255
256 ERROR("BUG: should never get here");
257 return 0;
258 }
259
260 int thumb_pass_branch_condition(u32 cpsr, u16 opcode)
261 {
262 return pass_condition(cpsr, (opcode & 0x0f00) << 20);
263 }
264
265 /* simulate a single step (if possible)
266 * if the dry_run_pc argument is provided, no state is changed,
267 * but the new pc is stored in the variable pointed at by the argument
268 */
269 int arm_simulate_step(target_t *target, u32 *dry_run_pc)
270 {
271 armv4_5_common_t *armv4_5 = target->arch_info;
272 u32 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
273 arm_instruction_t instruction;
274 int instruction_size;
275
276 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
277 {
278 u32 opcode;
279
280 /* get current instruction, and identify it */
281 target_read_u32(target, current_pc, &opcode);
282 arm_evaluate_opcode(opcode, current_pc, &instruction);
283 instruction_size = 4;
284
285 /* check condition code (for all instructions) */
286 if (!pass_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode))
287 {
288 if (dry_run_pc)
289 {
290 *dry_run_pc = current_pc + instruction_size;
291 }
292 else
293 {
294 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
295 }
296
297 return ERROR_OK;
298 }
299 }
300 else
301 {
302 u16 opcode;
303
304 target_read_u16(target, current_pc, &opcode);
305 thumb_evaluate_opcode(opcode, current_pc, &instruction);
306 instruction_size = 2;
307
308 /* check condition code (only for branch instructions) */
309 if ((!thumb_pass_branch_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode)) &&
310 (instruction.type == ARM_B))
311 {
312 if (dry_run_pc)
313 {
314 *dry_run_pc = current_pc + instruction_size;
315 }
316 else
317 {
318 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
319 }
320
321 return ERROR_OK;
322 }
323 }
324
325 /* examine instruction type */
326
327 /* branch instructions */
328 if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX))
329 {
330 u32 target;
331
332 if (instruction.info.b_bl_bx_blx.reg_operand == -1)
333 {
334 target = instruction.info.b_bl_bx_blx.target_address;
335 }
336 else
337 {
338 target = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.b_bl_bx_blx.reg_operand).value, 0, 32);
339 }
340
341 if (dry_run_pc)
342 {
343 *dry_run_pc = target;
344 return ERROR_OK;
345 }
346 else
347 {
348 if (instruction.type == ARM_B)
349 {
350 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target);
351 }
352 else if (instruction.type == ARM_BL)
353 {
354 u32 old_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
355 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 14).value, 0, 32, old_pc + 4);
356 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target);
357 }
358 else if (instruction.type == ARM_BX)
359 {
360 if (target & 0x1)
361 {
362 armv4_5->core_state = ARMV4_5_STATE_THUMB;
363 }
364 else
365 {
366 armv4_5->core_state = ARMV4_5_STATE_ARM;
367 }
368 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target & 0xfffffffe);
369 }
370 else if (instruction.type == ARM_BLX)
371 {
372 u32 old_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
373 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 14).value, 0, 32, old_pc + 4);
374
375 if (target & 0x1)
376 {
377 armv4_5->core_state = ARMV4_5_STATE_THUMB;
378 }
379 else
380 {
381 armv4_5->core_state = ARMV4_5_STATE_ARM;
382 }
383 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target & 0xfffffffe);
384 }
385
386 return ERROR_OK;
387 }
388 }
389 /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */
390 else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))
391 || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN)))
392 {
393 u32 Rd, Rn, shifter_operand;
394 u8 C = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
395 u8 carry_out;
396
397 Rd = 0x0;
398 Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rn).value, 0, 32);
399 shifter_operand = arm_shifter_operand(armv4_5, instruction.info.data_proc.variant, instruction.info.data_proc.shifter_operand, &carry_out);
400
401 /* adjust Rn in case the PC is being read */
402 if (instruction.info.data_proc.Rn == 15)
403 Rn += 2 * instruction_size;
404
405 if (instruction.type == ARM_AND)
406 Rd = Rn & shifter_operand;
407 else if (instruction.type == ARM_EOR)
408 Rd = Rn ^ shifter_operand;
409 else if (instruction.type == ARM_SUB)
410 Rd = Rn - shifter_operand;
411 else if (instruction.type == ARM_RSB)
412 Rd = shifter_operand - Rn;
413 else if (instruction.type == ARM_ADD)
414 Rd = Rn + shifter_operand;
415 else if (instruction.type == ARM_ADC)
416 Rd = Rn + shifter_operand + (C & 1);
417 else if (instruction.type == ARM_SBC)
418 Rd = Rn - shifter_operand - (C & 1) ? 0 : 1;
419 else if (instruction.type == ARM_RSC)
420 Rd = shifter_operand - Rn - (C & 1) ? 0 : 1;
421 else if (instruction.type == ARM_ORR)
422 Rd = Rn | shifter_operand;
423 else if (instruction.type == ARM_BIC)
424 Rd = Rn & ~(shifter_operand);
425 else if (instruction.type == ARM_MOV)
426 Rd = shifter_operand;
427 else if (instruction.type == ARM_MVN)
428 Rd = ~shifter_operand;
429
430 if (dry_run_pc)
431 {
432 if (instruction.info.data_proc.Rd == 15)
433 {
434 *dry_run_pc = Rd;
435 return ERROR_OK;
436 }
437 else
438 {
439 *dry_run_pc = current_pc + instruction_size;
440 }
441
442 return ERROR_OK;
443 }
444 else
445 {
446 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rd).value, 0, 32, Rd);
447 WARNING("no updating of flags yet");
448
449 if (instruction.info.data_proc.Rd == 15)
450 return ERROR_OK;
451 }
452 }
453 /* compare instructions (CMP, CMN, TST, TEQ) */
454 else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN))
455 {
456 if (dry_run_pc)
457 {
458 *dry_run_pc = current_pc + instruction_size;
459 return ERROR_OK;
460 }
461 else
462 {
463 WARNING("no updating of flags yet");
464 }
465 }
466 /* load register instructions */
467 else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
468 {
469 u32 load_address = 0, modified_address = 0, load_value;
470 u32 Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32);
471
472 /* adjust Rn in case the PC is being read */
473 if (instruction.info.load_store.Rn == 15)
474 Rn += 2 * instruction_size;
475
476 if (instruction.info.load_store.offset_mode == 0)
477 {
478 if (instruction.info.load_store.U)
479 modified_address = Rn + instruction.info.load_store.offset.offset;
480 else
481 modified_address = Rn - instruction.info.load_store.offset.offset;
482 }
483 else if (instruction.info.load_store.offset_mode == 1)
484 {
485 u32 offset;
486 u32 Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.offset.reg.Rm).value, 0, 32);
487 u8 shift = instruction.info.load_store.offset.reg.shift;
488 u8 shift_imm = instruction.info.load_store.offset.reg.shift_imm;
489 u8 carry = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
490
491 offset = arm_shift(shift, Rm, shift_imm, &carry);
492
493 if (instruction.info.load_store.U)
494 modified_address = Rn + offset;
495 else
496 modified_address = Rn - offset;
497 }
498 else
499 {
500 ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
501 }
502
503 if (instruction.info.load_store.index_mode == 0)
504 {
505 /* offset mode
506 * we load from the modified address, but don't change the base address register */
507 load_address = modified_address;
508 modified_address = Rn;
509 }
510 else if (instruction.info.load_store.index_mode == 1)
511 {
512 /* pre-indexed mode
513 * we load from the modified address, and write it back to the base address register */
514 load_address = modified_address;
515 }
516 else if (instruction.info.load_store.index_mode == 2)
517 {
518 /* post-indexed mode
519 * we load from the unmodified address, and write the modified address back */
520 load_address = Rn;
521 }
522
523 target_read_u32(target, load_address, &load_value);
524
525 if (dry_run_pc)
526 {
527 if (instruction.info.load_store.Rd == 15)
528 {
529 *dry_run_pc = load_value;
530 return ERROR_OK;
531 }
532 else
533 {
534 *dry_run_pc = current_pc + instruction_size;
535 }
536
537 return ERROR_OK;
538 }
539 else
540 {
541 if ((instruction.info.load_store.index_mode == 1) ||
542 (instruction.info.load_store.index_mode == 2))
543 {
544 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32, modified_address);
545 }
546 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rd).value, 0, 32, load_value);
547
548 if (instruction.info.load_store.Rd == 15)
549 return ERROR_OK;
550 }
551 }
552 /* load multiple instruction */
553 else if (instruction.type == ARM_LDM)
554 {
555 int i;
556 u32 Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32);
557 u32 load_values[16];
558 int bits_set = 0;
559
560 for (i = 0; i < 16; i++)
561 {
562 if (instruction.info.load_store_multiple.register_list & (1 << i))
563 bits_set++;
564 }
565
566 switch (instruction.info.load_store_multiple.addressing_mode)
567 {
568 case 0: /* Increment after */
569 Rn = Rn;
570 break;
571 case 1: /* Increment before */
572 Rn = Rn + 4;
573 break;
574 case 2: /* Decrement after */
575 Rn = Rn - (bits_set * 4) + 4;
576 break;
577 case 3: /* Decrement before */
578 Rn = Rn - (bits_set * 4);
579 break;
580 }
581
582 for (i = 0; i < 16; i++)
583 {
584 if (instruction.info.load_store_multiple.register_list & (1 << i))
585 {
586 target_read_u32(target, Rn, &load_values[i]);
587 Rn += 4;
588 }
589 }
590
591 if (dry_run_pc)
592 {
593 if (instruction.info.load_store_multiple.register_list & 0x8000)
594 {
595 *dry_run_pc = load_values[15];
596 return ERROR_OK;
597 }
598 }
599 else
600 {
601 enum armv4_5_mode mode = armv4_5->core_mode;
602 int update_cpsr = 0;
603
604 if (instruction.info.load_store_multiple.S)
605 {
606 if (instruction.info.load_store_multiple.register_list & 0x8000)
607 update_cpsr = 1;
608 else
609 mode = ARMV4_5_MODE_USR;
610 }
611
612 for (i = 0; i < 16; i++)
613 {
614 if (instruction.info.load_store_multiple.register_list & (1 << i))
615 {
616 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, i).value, 0, 32, load_values[i]);
617 }
618 }
619
620 if (update_cpsr)
621 {
622 u32 spsr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32);
623 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, spsr);
624 }
625
626 /* base register writeback */
627 if (instruction.info.load_store_multiple.W)
628 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
629
630 if (instruction.info.load_store_multiple.register_list & 0x8000)
631 return ERROR_OK;
632 }
633 }
634 /* store multiple instruction */
635 else if (instruction.type == ARM_STM)
636 {
637 int i;
638
639 if (dry_run_pc)
640 {
641 /* STM wont affect PC (advance by instruction size */
642 }
643 else
644 {
645 u32 Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32);
646 int bits_set = 0;
647 enum armv4_5_mode mode = armv4_5->core_mode;
648
649 for (i = 0; i < 16; i++)
650 {
651 if (instruction.info.load_store_multiple.register_list & (1 << i))
652 bits_set++;
653 }
654
655 if (instruction.info.load_store_multiple.S)
656 {
657 mode = ARMV4_5_MODE_USR;
658 }
659
660 switch (instruction.info.load_store_multiple.addressing_mode)
661 {
662 case 0: /* Increment after */
663 Rn = Rn;
664 break;
665 case 1: /* Increment before */
666 Rn = Rn + 4;
667 break;
668 case 2: /* Decrement after */
669 Rn = Rn - (bits_set * 4) + 4;
670 break;
671 case 3: /* Decrement before */
672 Rn = Rn - (bits_set * 4);
673 break;
674 }
675
676 for (i = 0; i < 16; i++)
677 {
678 if (instruction.info.load_store_multiple.register_list & (1 << i))
679 {
680 target_write_u32(target, Rn, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32));
681 Rn += 4;
682 }
683 }
684
685 /* base register writeback */
686 if (instruction.info.load_store_multiple.W)
687 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
688
689 }
690 }
691 else if (!dry_run_pc)
692 {
693 /* the instruction wasn't handled, but we're supposed to simulate it
694 */
695 return ERROR_ARM_SIMULATOR_NOT_IMPLEMENTED;
696 }
697
698 if (dry_run_pc)
699 {
700 *dry_run_pc = current_pc + instruction_size;
701 return ERROR_OK;
702 }
703 else
704 {
705 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
706 return ERROR_OK;
707 }
708
709 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)