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 cl_stack_op::cl_stack_op(enum stack_op op,
39 t_addr iSP_before, t_addr iSP_after):
46 SP_before= iSP_before;
50 cl_stack_op::~cl_stack_op(void)
56 cl_stack_op::mk_copy(void)
58 class cl_stack_op *so= new cl_stack_op(*this);
63 cl_stack_op::info_head(class cl_console *con)
65 con->dd_printf("OP SP before-after L DATA/ADDR INSTRUCTION\n");
69 cl_stack_op::info(class cl_console *con, class cl_uc *uc)
71 con->dd_printf("%-4s 0x%06"_A_"x-0x%06"_A_"x %d ",
72 get_op_name(), SP_before, SP_after, abs(SP_before-SP_after));
75 uc->print_disass(PC, con);
76 //con->dd_printf("\n");
80 cl_stack_op::get_op_name(void)
86 cl_stack_op::print_info(class cl_console *con)
92 cl_stack_op::sp_increased(void)
94 if (operation & stack_write_operation)
95 return(SP_after > SP_before);
96 else // read operation
97 return(SP_after < SP_before);
101 cl_stack_op::data_size(void)
103 int r= SP_after - SP_before;
109 cl_stack_op::match(class cl_stack_op *op)
115 cl_stack_op::can_removed(class cl_stack_op *op)
117 bool incr= sp_increased(); // FIXME
118 bool op_incr= op->sp_increased(); // FIXME
120 if ((incr && !op_incr) ||
123 printf("BIGBIG ERROR!\n");
128 t_mem opa= op->get_after();
129 return(SP_before >= opa);
133 t_mem opa= op->get_after();
134 return(SP_before <= opa);
140 * CALL operation on stack
143 cl_stack_call::cl_stack_call(t_addr iPC, t_addr called, t_addr pushed,
144 t_addr iSP_before, t_addr iSP_after):
145 cl_stack_op(stack_call, iPC, iSP_before, iSP_after)
152 cl_stack_call::mk_copy(void)
154 class cl_stack_call *so= new cl_stack_call(*this);
159 cl_stack_call::get_op_name(void)
165 cl_stack_call::print_info(class cl_console *con)
167 con->dd_printf("0x%06"_A_"x", called_addr);
171 cl_stack_call::get_matching_name(void)
177 cl_stack_call::get_matching_op(void)
183 cl_stack_call::match(class cl_stack_op *op)
185 return(op->get_op() == stack_ret);
190 * INTERRUPT operation (call) on stack
193 cl_stack_intr::cl_stack_intr(t_addr iPC, t_addr called, t_addr pushed,
194 t_addr iSP_before, t_addr iSP_after):
195 cl_stack_call(iPC, called, pushed, iSP_before, iSP_after)
197 //called_addr= called;
198 //pushed_addr= pushed;
199 operation= stack_intr;
203 cl_stack_intr::mk_copy(void)
205 class cl_stack_intr *so= new cl_stack_intr(*this);
210 cl_stack_intr::get_op_name(void)
216 cl_stack_intr::print_info(class cl_console *con)
218 con->dd_printf("0x%06"_A_"x", called_addr);
222 cl_stack_intr::get_matching_name(void)
228 cl_stack_intr::get_matching_op(void)
234 cl_stack_intr::match(class cl_stack_op *op)
236 return(op->get_op() == stack_iret);
241 * PUSH operation on stack
244 cl_stack_push::cl_stack_push(t_addr iPC, t_mem idata,
245 t_addr iSP_before, t_addr iSP_after):
246 cl_stack_op(stack_push, iPC, iSP_before, iSP_after)
252 cl_stack_push::mk_copy(void)
254 class cl_stack_push *so= new cl_stack_push(*this);
259 cl_stack_push::get_op_name(void)
265 cl_stack_push::get_matching_name(void)
271 cl_stack_push::get_matching_op(void)
277 cl_stack_push::print_info(class cl_console *con)
280 con->dd_printf("0x%06"_A_"x", d);
284 cl_stack_push::match(class cl_stack_op *op)
286 return(op->get_op() == stack_pop);
291 * RETURN operation on stack
294 cl_stack_ret::cl_stack_ret(t_addr iPC, t_addr iaddr,
295 t_addr iSP_before, t_addr iSP_after):
296 cl_stack_call(iPC, iaddr, 0, iSP_before, iSP_after)
298 operation= stack_ret;
302 cl_stack_ret::mk_copy(void)
304 class cl_stack_ret *so= new cl_stack_ret(*this);
309 cl_stack_ret::get_op_name(void)
315 cl_stack_ret::get_matching_name(void)
321 cl_stack_ret::get_matching_op(void)
327 cl_stack_ret::match(class cl_stack_op *op)
329 return(op->get_op() == stack_call);
334 * RETURN from interrupt operation on stack
337 cl_stack_iret::cl_stack_iret(t_addr iPC, t_addr iaddr,
338 t_addr iSP_before, t_addr iSP_after):
339 cl_stack_ret(iPC, iaddr, iSP_before, iSP_after)
341 operation= stack_iret;
345 cl_stack_iret::mk_copy(void)
347 class cl_stack_iret *so= new cl_stack_iret(*this);
352 cl_stack_iret::get_op_name(void)
358 cl_stack_iret::get_matching_name(void)
364 cl_stack_iret::get_matching_op(void)
370 cl_stack_iret::match(class cl_stack_op *op)
372 return(op->get_op() == stack_intr);
377 * POP operation on stack
380 cl_stack_pop::cl_stack_pop(t_addr iPC, t_mem idata,
381 t_addr iSP_before, t_addr iSP_after):
382 cl_stack_push(iPC, idata, iSP_before, iSP_after)
384 operation= stack_pop;
388 cl_stack_pop::mk_copy(void)
390 class cl_stack_pop *so= new cl_stack_pop(*this);
395 cl_stack_pop::get_op_name(void)
401 cl_stack_pop::get_matching_name(void)
407 cl_stack_pop::get_matching_op(void)
413 cl_stack_pop::match(class cl_stack_op *op)
415 return(op->get_op() == stack_push);
423 class cl_error_class *cl_error_stack::error_stack_class;
425 cl_error_stack::cl_error_stack(void)
427 if (NULL == error_stack_class)
428 error_stack_class= new cl_error_class(err_error, "stack", classification, ERROR_OFF);
429 classification= error_stack_class;
432 /* Stack Tracker Errors */
434 class cl_error_class *cl_error_stack_tracker::error_stack_tracker_class;
436 cl_error_stack_tracker::cl_error_stack_tracker(void)
438 // cl_error_class *error_stack_tracker_class = new cl_error_class(err_error, "stack_tracker", error_stack_class, ERROR_OFF);
439 // classification= &error_stack_tracker_class;
440 if (NULL == error_stack_tracker_class)
441 error_stack_tracker_class= new cl_error_class(err_error, "stack_tracker", classification);
442 classification= error_stack_tracker_class;
445 /* Stack Tracker: wrong handle */
447 class cl_error_class *cl_error_stack_tracker_wrong_handle::error_stack_tracker_wrong_handle_class;
449 cl_error_stack_tracker_wrong_handle::cl_error_stack_tracker_wrong_handle(bool write_op):
450 cl_error_stack_tracker()
452 write_operation= write_op;
453 if (NULL == error_stack_tracker_wrong_handle_class)
454 error_stack_tracker_wrong_handle_class= new cl_error_class(err_error, "stack_tracker_wrong_handle", classification);
455 classification= error_stack_tracker_wrong_handle_class;
459 cl_error_stack_tracker_wrong_handle::print(class cl_commander *c)
461 c->dd_printf("%s: wrong stack tracker handle called for %s operation\n",
462 get_type_name(), write_operation?"write":"read");
465 /* Stack Tracker: operation on empty stack */
467 class cl_error_class *cl_error_stack_tracker_empty::error_stack_tracker_empty_class;
469 cl_error_stack_tracker_empty::
470 cl_error_stack_tracker_empty(class cl_stack_op *op):
471 cl_error_stack_tracker()
473 operation= op->mk_copy();
474 if (NULL == error_stack_tracker_empty_class)
475 error_stack_tracker_empty_class= new cl_error_class(err_error, "operation_on_empty_stack", classification);
476 classification= error_stack_tracker_empty_class;
479 cl_error_stack_tracker_empty::~cl_error_stack_tracker_empty(void)
485 cl_error_stack_tracker_empty::print(class cl_commander *c)
487 c->dd_printf("%s(0x%06"_A_"x: %s on empty stack, PC="
488 "0x06"_A_"x, SP=0x%06"_A_"x->0x%06"_A_"x\n",
489 get_type_name(), operation->get_pc(), operation->get_op_name(),
490 operation->get_before(), operation->get_after());
493 /* Stack Tracker: operation on empty stack */
495 class cl_error_class *cl_error_stack_tracker_unmatch::error_stack_tracker_unmatch_class;
497 cl_error_stack_tracker_unmatch::
498 cl_error_stack_tracker_unmatch(class cl_stack_op *Top, class cl_stack_op *op):
499 cl_error_stack_tracker()
502 operation= op->mk_copy();
503 if (NULL == error_stack_tracker_unmatch_class)
504 error_stack_tracker_unmatch_class= new cl_error_class(err_warning, "stack_operation_unmatched_to_top_of_stack", classification);
505 classification= error_stack_tracker_unmatch_class;
508 cl_error_stack_tracker_unmatch::~cl_error_stack_tracker_unmatch(void)
515 cl_error_stack_tracker_unmatch::print(class cl_commander *c)
517 c->dd_printf("%s(0x%06"_A_"x): %s when %s expected, "
518 "SP=0x%06"_A_"x->0x%06"_A_"x\n",
519 get_type_name(), operation->get_pc(),
520 operation->get_op_name(), top->get_matching_name(),
521 operation->get_before(), operation->get_after());
524 /* Stack Tracker: stack is inconsistent */
526 class cl_error_class *cl_error_stack_tracker_inconsistent::error_stack_tracker_inconsistent_class;
528 cl_error_stack_tracker_inconsistent::
529 cl_error_stack_tracker_inconsistent(class cl_stack_op *op,
530 int the_unread_data_size)
532 operation= op->mk_copy();
533 unread_data_size= the_unread_data_size;
534 if (NULL == error_stack_tracker_inconsistent_class)
535 error_stack_tracker_inconsistent_class= new cl_error_class(err_warning, "stack_looks_corrupted", classification);
536 classification= error_stack_tracker_inconsistent_class;
539 cl_error_stack_tracker_inconsistent::~cl_error_stack_tracker_inconsistent(void)
545 cl_error_stack_tracker_inconsistent::print(class cl_commander *c)
547 c->dd_printf("%s(0x%06"_A_"x): %d byte(s) unread from the stack\n",
548 get_type_name(), operation->get_pc(),
553 /* End of sim.src/stack.cc */