2 * Simulator of microcontrollers (stack.cc)
4 * Copyright (C) 2000,00 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
37 static class cl_stack_error_registry stack_error_registry;
39 cl_stack_op::cl_stack_op(enum stack_op op,
41 t_addr iSP_before, t_addr iSP_after):
48 SP_before= iSP_before;
52 cl_stack_op::~cl_stack_op(void)
58 cl_stack_op::mk_copy(void)
60 class cl_stack_op *so= new cl_stack_op(*this);
65 cl_stack_op::info_head(class cl_console_base *con)
67 con->dd_printf("OP SP before-after L DATA/ADDR INSTRUCTION\n");
71 cl_stack_op::info(class cl_console_base *con, class cl_uc *uc)
73 con->dd_printf("%-4s 0x%06"_A_"x-0x%06"_A_"x %d ",
74 get_op_name(), SP_before, SP_after, abs(SP_before-SP_after));
77 uc->print_disass(PC, con);
78 //con->dd_printf("\n");
82 cl_stack_op::get_op_name(void)
88 cl_stack_op::print_info(class cl_console_base *con)
94 cl_stack_op::sp_increased(void)
96 if (operation & stack_write_operation)
97 return(SP_after > SP_before);
98 else // read operation
99 return(SP_after < SP_before);
103 cl_stack_op::data_size(void)
105 int r= SP_after - SP_before;
111 cl_stack_op::match(class cl_stack_op *op)
117 cl_stack_op::can_removed(class cl_stack_op *op)
119 bool incr= sp_increased(); // FIXME
120 bool op_incr= op->sp_increased(); // FIXME
122 if ((incr && !op_incr) ||
125 printf("BIGBIG ERROR!\n");
130 t_mem opa= op->get_after();
131 return(SP_before >= opa);
135 t_mem opa= op->get_after();
136 return(SP_before <= opa);
142 * CALL operation on stack
145 cl_stack_call::cl_stack_call(t_addr iPC, t_addr called, t_addr pushed,
146 t_addr iSP_before, t_addr iSP_after):
147 cl_stack_op(stack_call, iPC, iSP_before, iSP_after)
154 cl_stack_call::mk_copy(void)
156 class cl_stack_call *so= new cl_stack_call(*this);
161 cl_stack_call::get_op_name(void)
167 cl_stack_call::print_info(class cl_console_base *con)
169 con->dd_printf("0x%06"_A_"x", called_addr);
173 cl_stack_call::get_matching_name(void)
179 cl_stack_call::get_matching_op(void)
185 cl_stack_call::match(class cl_stack_op *op)
187 return(op->get_op() == stack_ret);
192 * INTERRUPT operation (call) on stack
195 cl_stack_intr::cl_stack_intr(t_addr iPC, t_addr called, t_addr pushed,
196 t_addr iSP_before, t_addr iSP_after):
197 cl_stack_call(iPC, called, pushed, iSP_before, iSP_after)
199 //called_addr= called;
200 //pushed_addr= pushed;
201 operation= stack_intr;
205 cl_stack_intr::mk_copy(void)
207 class cl_stack_intr *so= new cl_stack_intr(*this);
212 cl_stack_intr::get_op_name(void)
218 cl_stack_intr::print_info(class cl_console_base *con)
220 con->dd_printf("0x%06"_A_"x", called_addr);
224 cl_stack_intr::get_matching_name(void)
230 cl_stack_intr::get_matching_op(void)
236 cl_stack_intr::match(class cl_stack_op *op)
238 return(op->get_op() == stack_iret);
243 * PUSH operation on stack
246 cl_stack_push::cl_stack_push(t_addr iPC, t_mem idata,
247 t_addr iSP_before, t_addr iSP_after):
248 cl_stack_op(stack_push, iPC, iSP_before, iSP_after)
254 cl_stack_push::mk_copy(void)
256 class cl_stack_push *so= new cl_stack_push(*this);
261 cl_stack_push::get_op_name(void)
267 cl_stack_push::get_matching_name(void)
273 cl_stack_push::get_matching_op(void)
279 cl_stack_push::print_info(class cl_console_base *con)
282 con->dd_printf("0x%06"_A_"x", d);
286 cl_stack_push::match(class cl_stack_op *op)
288 return(op->get_op() == stack_pop);
293 * RETURN operation on stack
296 cl_stack_ret::cl_stack_ret(t_addr iPC, t_addr iaddr,
297 t_addr iSP_before, t_addr iSP_after):
298 cl_stack_call(iPC, iaddr, 0, iSP_before, iSP_after)
300 operation= stack_ret;
304 cl_stack_ret::mk_copy(void)
306 class cl_stack_ret *so= new cl_stack_ret(*this);
311 cl_stack_ret::get_op_name(void)
317 cl_stack_ret::get_matching_name(void)
323 cl_stack_ret::get_matching_op(void)
329 cl_stack_ret::match(class cl_stack_op *op)
331 return(op->get_op() == stack_call);
336 * RETURN from interrupt operation on stack
339 cl_stack_iret::cl_stack_iret(t_addr iPC, t_addr iaddr,
340 t_addr iSP_before, t_addr iSP_after):
341 cl_stack_ret(iPC, iaddr, iSP_before, iSP_after)
343 operation= stack_iret;
347 cl_stack_iret::mk_copy(void)
349 class cl_stack_iret *so= new cl_stack_iret(*this);
354 cl_stack_iret::get_op_name(void)
360 cl_stack_iret::get_matching_name(void)
366 cl_stack_iret::get_matching_op(void)
372 cl_stack_iret::match(class cl_stack_op *op)
374 return(op->get_op() == stack_intr);
379 * POP operation on stack
382 cl_stack_pop::cl_stack_pop(t_addr iPC, t_mem idata,
383 t_addr iSP_before, t_addr iSP_after):
384 cl_stack_push(iPC, idata, iSP_before, iSP_after)
386 operation= stack_pop;
390 cl_stack_pop::mk_copy(void)
392 class cl_stack_pop *so= new cl_stack_pop(*this);
397 cl_stack_pop::get_op_name(void)
403 cl_stack_pop::get_matching_name(void)
409 cl_stack_pop::get_matching_op(void)
415 cl_stack_pop::match(class cl_stack_op *op)
417 return(op->get_op() == stack_push);
425 cl_error_stack::cl_error_stack(void)
427 classification = stack_error_registry.find("stack");
430 /* Stack Tracker Errors */
432 cl_error_stack_tracker::cl_error_stack_tracker(void)
434 classification = stack_error_registry.find("stack_tracker");
437 /* Stack Tracker: wrong handle */
439 cl_error_stack_tracker_wrong_handle::cl_error_stack_tracker_wrong_handle(bool write_op):
440 cl_error_stack_tracker()
442 write_operation= write_op;
443 classification = stack_error_registry.find("stack_tracker_wrong_handle");
447 cl_error_stack_tracker_wrong_handle::print(class cl_commander_base *c)
449 c->dd_printf("%s: wrong stack tracker handle called for %s operation\n",
450 get_type_name(), write_operation?"write":"read");
453 /* Stack Tracker: operation on empty stack */
455 cl_error_stack_tracker_empty::
456 cl_error_stack_tracker_empty(class cl_stack_op *op):
457 cl_error_stack_tracker()
459 operation= op->mk_copy();
460 classification = stack_error_registry.find("operation_on_empty_stack");
463 cl_error_stack_tracker_empty::~cl_error_stack_tracker_empty(void)
469 cl_error_stack_tracker_empty::print(class cl_commander_base *c)
471 c->dd_printf("%s(0x%06"_A_"x: %s on empty stack, PC="
472 "0x06"_A_"x, SP=0x%06"_A_"x->0x%06"_A_"x\n",
473 get_type_name(), operation->get_pc(), operation->get_op_name(),
474 operation->get_before(), operation->get_after());
477 /* Stack Tracker: operation on empty stack */
479 cl_error_stack_tracker_unmatch::
480 cl_error_stack_tracker_unmatch(class cl_stack_op *Top, class cl_stack_op *op):
481 cl_error_stack_tracker()
484 operation= op->mk_copy();
485 classification = stack_error_registry.find("stack_operation_unmatched_to_top_of_stack");
488 cl_error_stack_tracker_unmatch::~cl_error_stack_tracker_unmatch(void)
495 cl_error_stack_tracker_unmatch::print(class cl_commander_base *c)
497 c->dd_printf("%s(0x%06"_A_"x): %s when %s expected, "
498 "SP=0x%06"_A_"x->0x%06"_A_"x\n",
499 get_type_name(), operation->get_pc(),
500 operation->get_op_name(), top->get_matching_name(),
501 operation->get_before(), operation->get_after());
504 /* Stack Tracker: stack is inconsistent */
506 cl_error_stack_tracker_inconsistent::
507 cl_error_stack_tracker_inconsistent(class cl_stack_op *op,
508 int the_unread_data_size)
510 operation= op->mk_copy();
511 unread_data_size= the_unread_data_size;
512 classification = stack_error_registry.find("stack_looks_corrupted");
515 cl_error_stack_tracker_inconsistent::~cl_error_stack_tracker_inconsistent(void)
521 cl_error_stack_tracker_inconsistent::print(class cl_commander_base *c)
523 c->dd_printf("%s(0x%06"_A_"x): %d byte(s) unread from the stack\n",
524 get_type_name(), operation->get_pc(),
528 cl_stack_error_registry::cl_stack_error_registry(void)
530 class cl_error_class *prev = stack_error_registry.find("non-classified");
531 prev = register_error(new cl_error_class(err_error, "stack", prev, ERROR_OFF));
532 prev = register_error(new cl_error_class(err_error, "stack_tracker", prev));
533 prev = register_error(new cl_error_class(err_error, "stack_tracker_wrong_handle", prev));
534 prev = register_error(new cl_error_class(err_error, "operation_on_empty_stack", prev));
535 prev = register_error(new cl_error_class(err_warning, "stack_operation_unmatched_to_top_of_stack", prev));
536 prev = register_error(new cl_error_class(err_warning, "stack_looks_corrupted", prev));
540 /* End of sim.src/stack.cc */