This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] H8 sim, enhancements for mova


This will make mova work with pretty much all addressing modes.
Test to follow separately.


2003-07-18  Michael Snyder  <msnyder@redhat.com>

	* include/opcode/h8sx.h (DO_MOVA1, DO_MOVA2): Reformatting.

2003-07-18  Michael Snyder  <msnyder@redhat.com>

	* compile.c (decode): Enhancements for mova.
	Initialize cst, reg, and rdisp inside the loop, for each
	new instruction.  Defer correction of the disp2 values until
	later, and then adjust them by the size of the first operand,
	rather than the size of the instruction.
	(sim_resume): For mova, adjust the size of the second operand
	according to the type of the first operand (INDEXB vs. INDEXW).
	In cases where there is only one operand, the other two must
	both be composed on the fly.

Index: include/opcode/h8300.h
===================================================================
RCS file: /cvs/src/src/include/opcode/h8300.h,v
retrieving revision 1.18
diff -p -r1.18 h8300.h
*** include/opcode/h8300.h	25 Jun 2003 15:31:57 -0000	1.18
--- include/opcode/h8300.h	22 Jul 2003 19:21:08 -0000
*************** struct h8_opcode h8_opcodes[] = 
*** 1627,1643 ****
    DO_MOVA1 (RDPOSTDEC, 0xA, B30 | RDPOSTDEC),
    DO_MOVA1 (RDPREINC,  0x9, B30 | RDPREINC),
    DO_MOVA1 (RDPREDEC,  0xB, B30 | RDPREDEC),
!   DO_MOVA1 (DISP2DST, B30 | B20 | DISP2DST,  B30 | DSTDISPREG),
!   DO_MOVA2 (DISP16DST, 0xC,      B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (DISP32DST, 0xC,      B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXB16 | DST, 0xD, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXW16 | DST, 0xE, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXL16 | DST, 0xF, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXB32 | DST, 0xD, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXW32 | DST, 0xE, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXL32 | DST, 0xF, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (ABS16DST | DST, 0x4, 0x0,              DSTABS16LIST),
!   DO_MOVA2 (ABS32DST | DST, 0x4, 0x8,              DSTABS32LIST),
  
    {O (O_MOV, SB), AV_H8, 10, "movfpe", {{ABS16SRC, RD8, E}}, {{0x6, 0xA, 0x4, RD8, ABS16SRC, DATA3, E}}},
    {O (O_MOV, SB), AV_H8, 10, "movtpe", {{RS8, ABS16DST, E}}, {{0x6, 0xA, 0xC, RS8, ABS16DST, DATA3, E}}},
--- 1627,1643 ----
    DO_MOVA1 (RDPOSTDEC, 0xA, B30 | RDPOSTDEC),
    DO_MOVA1 (RDPREINC,  0x9, B30 | RDPREINC),
    DO_MOVA1 (RDPREDEC,  0xB, B30 | RDPREDEC),
!   DO_MOVA1 (DISP2DST,  B30 | B20 | DISP2DST,  B30 | DSTDISPREG),
!   DO_MOVA2 (DISP16DST, 0xC, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (DISP32DST, 0xC, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXB16D, 0xD, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXW16D, 0xE, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXL16D, 0xF, B30 | DSTDISPREG, DSTDISP16LIST),
!   DO_MOVA2 (INDEXB32D, 0xD, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXW32D, 0xE, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (INDEXL32D, 0xF, B31 | DSTDISPREG, DSTDISP32LIST),
!   DO_MOVA2 (ABS16DST,  0x4, 0x0,              DSTABS16LIST),
!   DO_MOVA2 (ABS32DST,  0x4, 0x8,              DSTABS32LIST),
  
    {O (O_MOV, SB), AV_H8, 10, "movfpe", {{ABS16SRC, RD8, E}}, {{0x6, 0xA, 0x4, RD8, ABS16SRC, DATA3, E}}},
    {O (O_MOV, SB), AV_H8, 10, "movtpe", {{RS8, ABS16DST, E}}, {{0x6, 0xA, 0xC, RS8, ABS16DST, DATA3, E}}},
Index: sim/h8300/compile.c
===================================================================
RCS file: /cvs/src/src/sim/h8300/compile.c,v
retrieving revision 1.35
diff -p -r1.35 compile.c
*** sim/h8300/compile.c	22 Jul 2003 19:07:30 -0000	1.35
--- sim/h8300/compile.c	22 Jul 2003 19:21:09 -0000
*************** decode (SIM_DESC sd, int addr, unsigned 
*** 606,611 ****
--- 606,615 ----
  	  (q->available == AV_H8H  && !h8300hmode))
  	continue;
  
+       cst[0]   = cst[1]   = cst[2]   = 0;
+       reg[0]   = reg[1]   = reg[2]   = 0;
+       rdisp[0] = rdisp[1] = rdisp[2] = 0;
+ 
        while (1)
  	{
  	  op_type looking_for = *nib;
*************** decode (SIM_DESC sd, int addr, unsigned 
*** 770,795 ****
  		       (looking_for & MODE) == INDEXB ||
  		       (looking_for & MODE) == INDEXW ||
  		       (looking_for & MODE) == INDEXL)
- 
  		{
  		  switch (looking_for & SIZE)
  		    {
  		    case L_2:
  		      cst[opnum] = thisnib & 3;
- 
- 		      /* DISP2 special treatment.  */
- 		      if ((looking_for & MODE) == DISP)
- 			{
- 			  switch (OP_SIZE (q->how)) {
- 			  default: break;
- 			  case SW:
- 			    cst[opnum] *= 2;
- 			    break;
- 			  case SL:
- 			    cst[opnum] *= 4;
- 			    break;
- 			  }
- 			}
  		      break;
  		    case L_8:
  		      cst[opnum] = SEXTCHAR (data[len / 2]);
--- 774,784 ----
*************** decode (SIM_DESC sd, int addr, unsigned 
*** 1072,1102 ****
  			    p->type = X (OP_IMM, SP);
  			    p->literal = cst[opnum];
  			  }
! 			else if ((x & MODE) == INDEXB ||
! 				 (x & MODE) == INDEXW ||
! 				 (x & MODE) == INDEXL ||
! 				 (x & MODE) == DISP)
  			  {
! 			    /* Use the instruction to determine 
! 			       the operand size.  */
! 			    switch (x & MODE) {
! 			    case INDEXB:
! 			      p->type = X (OP_INDEXB, OP_SIZE (q->how));
! 			      break;
! 			    case INDEXW:
! 			      p->type = X (OP_INDEXW, OP_SIZE (q->how));
! 			      break;
! 			    case INDEXL:
! 			      p->type = X (OP_INDEXL, OP_SIZE (q->how));
! 			      break;
! 			    case DISP:
! 			      p->type = X (OP_DISP,   OP_SIZE (q->how));
! 			      break;
! 			    }
! 
  			    p->literal = cst[opnum];
  			    p->reg     = rdisp[opnum];
  			  }
  			else if (x & CTRL)
  			  {
  			    switch (reg[opnum])
--- 1061,1124 ----
  			    p->type = X (OP_IMM, SP);
  			    p->literal = cst[opnum];
  			  }
! 			else if ((x & MODE) == INDEXB)
  			  {
! 			    p->type = X (OP_INDEXB, OP_SIZE (q->how));
! 			    p->literal = cst[opnum];
! 			    p->reg     = rdisp[opnum];
! 			  }
! 			else if ((x & MODE) == INDEXW)
! 			  {
! 			    p->type = X (OP_INDEXW, OP_SIZE (q->how));
! 			    p->literal = cst[opnum];
! 			    p->reg     = rdisp[opnum];
! 			  }
! 			else if ((x & MODE) == INDEXL)
! 			  {
! 			    p->type = X (OP_INDEXL, OP_SIZE (q->how));
  			    p->literal = cst[opnum];
  			    p->reg     = rdisp[opnum];
  			  }
+ 			else if ((x & MODE) == DISP)
+ 			  {
+ 			    /* Yuck -- special for mova args.  */
+ 			    if (strncmp (q->name, "mova", 4) == 0 &&
+ 				(x & SIZE) == L_2)
+ 			      {
+ 				/* Mova can have a DISP2 dest, with an
+ 				   INDEXB or INDEXW src.  The multiplier
+ 				   for the displacement value is determined
+ 				   by the src operand, not by the insn.  */
+ 
+ 				switch (OP_KIND (dst->src.type))
+ 				  {
+ 				  case OP_INDEXB:
+ 				    p->type = X (OP_DISP, SB);
+ 				    p->literal = cst[opnum];
+ 				    break;
+ 				  case OP_INDEXW:
+ 				    p->type = X (OP_DISP, SW);
+ 				    p->literal = cst[opnum] * 2;
+ 				    break;
+ 				  default:
+ 				    goto fail;
+ 				  }
+ 			      }
+ 			    else
+ 			      {
+ 				p->type = X (OP_DISP,   OP_SIZE (q->how));
+ 				p->literal = cst[opnum];
+ 				/* DISP2 is special.  */
+ 				if ((x & SIZE) == L_2)
+ 				  switch (OP_SIZE (q->how))
+ 				    {
+ 				    case SB:                  break;
+ 				    case SW: p->literal *= 2; break;
+ 				    case SL: p->literal *= 4; break;
+ 				    }
+ 			      }
+ 			    p->reg     = rdisp[opnum];
+ 			  }
  			else if (x & CTRL)
  			  {
  			    switch (reg[opnum])
*************** sim_resume (SIM_DESC sd, int step, int s
*** 1979,1986 ****
--- 2001,2044 ----
  	        (mova/b, mova/w, mova/l).
  	     4) Add literal value of 1st argument (src).
  	     5) Store result in 3rd argument (op3).
+ 	  */
  
+ 	  /* Alas, since this is the only instruction with 3 arguments, 
+ 	     decode doesn't handle them very well.  Some fix-up is required.
+ 
+ 	     a) The size of dst is determined by whether src is 
+ 	        INDEXB or INDEXW.  */
+ 
+ 	  if (OP_KIND (code->src.type) == OP_INDEXB)
+ 	    code->dst.type = X (OP_KIND (code->dst.type), SB);
+ 	  else if (OP_KIND (code->src.type) == OP_INDEXW)
+ 	    code->dst.type = X (OP_KIND (code->dst.type), SW);
+ 
+ 	  /* b) If op3 == null, then this is the short form of the insn.
+ 	        Dst is the dispreg of src, and op3 is the 32-bit form
+ 		of the same register.
  	  */
+ 
+ 	  if (code->op3.type == 0)
+ 	    {
+ 	      /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
+ 		 We get to compose dst and op3 as follows:
+ 
+ 		     op3 is a 32-bit register, ID == src.reg.
+ 		     dst is the same register, but 8 or 16 bits
+ 		     depending on whether src is INDEXB or INDEXW.
+ 	      */
+ 
+ 	      code->op3.type = X (OP_REG, SL);
+ 	      code->op3.reg  = code->src.reg;
+ 	      code->op3.literal = 0;
+ 
+ 	      if (OP_KIND (code->src.type) == OP_INDEXB)
+ 		code->dst.type = X (OP_REG, SB);
+ 	      else
+ 		code->dst.type = X (OP_REG, SW);
+ 	    }
+ 
  	  if (fetch (sd, &code->dst, &ea))
  	    goto end;
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]