version 0.5.2
[fw/sdcc] / sim / ucsim / sim.src / stackcl.h
index 6e391abb1ae96b4814d1b5816a2d99c785dff0a4..06e522bc2ecba597a36425df7f96b9590a4a5f12 100644 (file)
@@ -33,26 +33,207 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 
 enum stack_op {
-  stack_call,
-  stack_push,
-  stack_ret,
-  stack_pop
+  stack_call   = 0x01,
+  stack_intr   = 0x02,
+  stack_push   = 0x04,
+  stack_ret    = 0x08,
+  stack_iret   = 0x10,
+  stack_pop    = 0x20
 };
 
+const int stack_write_operation= (stack_call|stack_intr|stack_push);
+const int stack_read_operation = (stack_ret|stack_iret|stack_pop);
+
+/* Abstraction of a stack operation */
 class cl_stack_op: public cl_base
 {
-public:
-  enum stack_op type;
+protected:
+  enum stack_op operation;
   t_addr PC;   // of instruction
-  t_addr addr; // called routine
-  t_mem  data; // pushed data
   t_addr SP_before;
   t_addr SP_after;
 public:
-  cl_stack_op(enum stack_op itype,
-             t_addr iPC, t_addr iaddr, t_mem idata,
-             t_addr iSP_before, t_addr iSP_after);
+  cl_stack_op(enum stack_op op,
+             t_addr iPC, t_addr iSP_before, t_addr iSP_after);
   virtual ~cl_stack_op(void);
+  virtual class cl_stack_op *mk_copy(void);
+  static void info_head(class cl_console *con);
+  virtual void info(class cl_console *con, class cl_uc *uc);
+protected:
+  virtual void print_info(class cl_console *con);
+public:
+  virtual char *get_op_name(void);
+  virtual char *get_matching_name(void) { return("unknown"); }
+  virtual bool sp_increased(void);
+  virtual int data_size(void);
+  virtual bool match(class cl_stack_op *op);
+  virtual enum stack_op get_op(void) { return(operation); }
+  virtual enum stack_op get_matching_op(void) { return(operation); }
+  virtual t_addr get_after(void) { return(SP_after); }
+  virtual t_addr get_before(void) { return(SP_before); }
+  virtual t_addr get_pc(void) { return(PC); }
+  virtual bool can_removed(class cl_stack_op *op);
+};
+
+/* Call of a subrutine, must match with RET */
+class cl_stack_call: public cl_stack_op
+{
+protected:
+  t_addr called_addr; // called routine
+  t_addr pushed_addr;
+public:
+  cl_stack_call(t_addr iPC, t_addr called, t_addr pushed,
+               t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+  virtual void print_info(class cl_console *con);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+/* Call of an ISR, must match with IRET */
+class cl_stack_intr: public cl_stack_call
+{
+public:
+  cl_stack_intr(t_addr iPC, t_addr called, t_addr pushed,
+               t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+  virtual void print_info(class cl_console *con);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+/* Push data to stack, must match with POP */
+class cl_stack_push: public cl_stack_op
+{
+protected:
+  t_mem data;  // pushed data
+public:
+  cl_stack_push(t_addr iPC, t_mem idata, t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+  virtual void print_info(class cl_console *con);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+/* Returning from a subroutine, tos must be CALL */
+class cl_stack_ret: public cl_stack_call
+{
+public:
+  cl_stack_ret(t_addr iPC, t_addr iaddr, t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+/* Returning from an ISR, yos must be INTR */
+class cl_stack_iret: public cl_stack_ret
+{
+public:
+  cl_stack_iret(t_addr iPC, t_addr iaddr, t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+/* Pop out data from stack, tos must be PUSH */
+class cl_stack_pop: public cl_stack_push
+{
+public:
+  cl_stack_pop(t_addr iPC, t_mem idata, t_addr iSP_before, t_addr iSP_after);
+  virtual class cl_stack_op *mk_copy(void);
+protected:
+  virtual char *get_op_name(void);
+public:
+  virtual char *get_matching_name(void);
+  virtual enum stack_op get_matching_op(void);
+  virtual bool match(class cl_stack_op *op);
+};
+
+
+/*
+ * All kind of stack errors
+ */
+//extern class cl_error_class error_stack_class;
+//class cl_error_stack: public cl_error
+ERROR_CLASS_DECL(stack): public cl_error
+{
+public:
+  cl_error_stack(void) { classification= &error_stack_class; }
+};
+
+/*
+ * All kind of stack tracker errors
+ */
+ERROR_CLASS_DECL(stack_tracker): public cl_error_stack
+{
+public:
+  cl_error_stack_tracker(void) { classification= &error_stack_tracker_class; }
+};
+
+ERROR_CLASS_DECL(stack_tracker_wrong_handle): public cl_error_stack_tracker
+{
+public:
+  bool write_operation;
+public:
+  cl_error_stack_tracker_wrong_handle(bool write_op);
+
+  virtual void print(class cl_commander *c);
+};
+
+ERROR_CLASS_DECL(stack_tracker_empty): public cl_error_stack_tracker
+{
+protected:
+  class cl_stack_op *operation;
+public:
+  cl_error_stack_tracker_empty(class cl_stack_op *op);
+  virtual ~cl_error_stack_tracker_empty(void);
+
+  virtual void print(class cl_commander *c);
+};
+
+ERROR_CLASS_DECL(stack_tracker_unmatch): public cl_error_stack_tracker
+{
+protected:
+  class cl_stack_op *top, *operation;
+public:
+  cl_error_stack_tracker_unmatch(class cl_stack_op *Top,
+                                class cl_stack_op *op);
+  virtual ~cl_error_stack_tracker_unmatch(void);
+
+  virtual void print(class cl_commander *c);
+};
+
+ERROR_CLASS_DECL(stack_tracker_inconsistent): public cl_error_stack_tracker
+{
+protected:
+  class cl_stack_op *operation;
+  int unread_data_size;
+public:
+  cl_error_stack_tracker_inconsistent(class cl_stack_op *op,
+                                     int the_unread_data_size);
+  virtual ~cl_error_stack_tracker_inconsistent(void);
+
+  virtual void print(class cl_commander *c);
 };