public inbox for cgen@sourceware.org
 help / color / mirror / Atom feed
* Simulator: base_insn and insn in decode.c
@ 2006-07-31 11:58 Ronald Hecht
  2006-08-03 21:55 ` Dave Brolley
  0 siblings, 1 reply; 9+ messages in thread
From: Ronald Hecht @ 2006-07-31 11:58 UTC (permalink / raw)
  To: cgen

Hello again,

i found another problem in decode. c. As I have variable instruction 
size, decode.c does not handle base_insn and insn in the right way. The 
file looks like this:

const IDESC *
proc8bf_decode (SIM_CPU *current_cpu, IADDR pc,
              CGEN_INSN_INT base_insn, CGEN_INSN_INT entire_insn,
              ARGBUF *abuf)
{
  /* Result of decoder.  */
  PROC8BF_INSN_TYPE itype;

  {
    CGEN_INSN_INT insn = base_insn;

    {
      unsigned int val = (((insn >> 0) & (63 << 0)));
      switch (val)
      {
      case 0 :
        if ((entire_insn & 0xff) == 0x0)
          { itype = PROC8BF_INSN_NOP; goto extract_sfmt_nop; }
        itype = PROC8BF_INSN_X_INVALID; goto extract_sfmt_empty;
      case 1 :
        if ((entire_insn & 0xff) == 0x1)
          { itype = PROC8BF_INSN_LDA; goto extract_sfmt_lda; }
        itype = PROC8BF_INSN_X_INVALID; goto extract_sfmt_empty;
      case 2 :
        if ((entire_insn & 0xff) == 0x2)
          { itype = PROC8BF_INSN_LDC; goto extract_sfmt_ldc; }
        itype = PROC8BF_INSN_X_INVALID; goto extract_sfmt_empty;
 
<snip>

I have given the first instruction byte as base_insn and entire_insn is 
the complete instruction. The location of the base instruction depends 
on the instruction size. So the calculation

      unsigned int val = (((insn >> 0) & (63 << 0)));

is not correct. If I remove the if-statement around the goto 
extract_sfmt_<insn> everything works correct. The simulatior does the 
right things.

By the way: I found it a bit confusing to write mloop.in. It was 
difficult to handle different size instructions. I did it this way:

xextract-pbb)

# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
# Outputs: sc, pc
# sc must be left pointing past the last created entry.
# pc must be left pointing past the last created entry.
# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
# to record the vpc of the cti insn.
# SET_INSN_COUNT(n) must be called to record number of real insns.

cat <<EOF
{
  const IDESC *idesc;
  int icount = 0;

  while (max_insns > 0)
    {
      CGEN_INSN_INT insn;
      CGEN_INSN_INT base_insn = GETIMEMUQI (current_cpu, pc);
      idesc = @cpu@_decode(current_cpu, pc, base_insn, base_insn, 
&sc->argbuf);
      switch (idesc->length) {
      case 1 : break;
      case 2 :
    insn = base_insn * 256 + GETIMEMUQI (current_cpu, pc + 1);
    break;
      case 3 :
    insn = base_insn * 256 * 256 + GETIMEMUQI (current_cpu, pc + 1) * 
256 + GETIMEMUQI (current_cpu, pc + 2);
    break;
      }
      idesc = @cpu@_decode(current_cpu, pc, base_insn, insn, &sc->argbuf);
      @cpu@_fill_argbuf (current_cpu, &sc->argbuf, idesc, pc, FAST_P);
      if (! FAST_P) {
    int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
    int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
    @cpu@_fill_argbuf_tp (current_cpu, &sc->argbuf, trace_p, profile_p);
      }
      ++sc;
      --max_insns;
      ++icount;
      pc += idesc->length;
      if (IDESC_CTI_P (idesc))
    {
      SET_CTI_VPC (sc - 1);
      break;
    }
    }
 
 Finish:
  SET_INSN_COUNT (icount);
}
EOF

;;

Is there an easier way to write this down?

Ronald

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-07-31 11:58 Simulator: base_insn and insn in decode.c Ronald Hecht
@ 2006-08-03 21:55 ` Dave Brolley
  2006-08-03 22:08   ` Dave Brolley
  2006-08-04  8:51   ` Ronald Hecht
  0 siblings, 2 replies; 9+ messages in thread
From: Dave Brolley @ 2006-08-03 21:55 UTC (permalink / raw)
  To: Ronald Hecht; +Cc: cgen

Ronald Hecht wrote:

> Hello again,
>
> i found another problem in decode. c. As I have variable instruction 
> size, decode.c does not handle base_insn and insn in the right way. 
> The file looks like this:
>
> const IDESC *
> proc8bf_decode (SIM_CPU *current_cpu, IADDR pc,
>              CGEN_INSN_INT base_insn, CGEN_INSN_INT entire_insn,
>              ARGBUF *abuf)
> {
>  /* Result of decoder.  */
>  PROC8BF_INSN_TYPE itype;
>
>  {
>    CGEN_INSN_INT insn = base_insn;
>
>    {
>      unsigned int val = (((insn >> 0) & (63 << 0)));
>      switch (val)
>      {
>      case 0 :
>        if ((entire_insn & 0xff) == 0x0)
>          { itype = PROC8BF_INSN_NOP; goto extract_sfmt_nop; }
>        itype = PROC8BF_INSN_X_INVALID; goto extract_sfmt_empty;

The generated decoder expects base_insn to be the first base-insn-size 
bits of the insn shifted as far right as possible. What you have 
specified is correct and the (((insn >> 0) & (63 << 0))) test us 
correct. It is looking at the low order 6 bits of the base_insn which 
are the only significant ones (according to your cpu file.

The generated decoder expects entire_insn to the all of the insn bits, 
also shifted as far right as possible.

The test around the goto is intended to make sure that the untested 
base_insn bits are as expected. It needs to be there, otherwise, invalid 
insns get recognized as valid ones. However, it would seem that the test 
should be against base_insn and not against entire_insn. I'll have a 
look at some other cgen simulators, including those which use SID to 
make sure that this assertion holds water. It probably hasn't come up 
until now, since most sims I have seen are able to pass the same value 
for base_insn and entire_insn.

Dave

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-03 21:55 ` Dave Brolley
@ 2006-08-03 22:08   ` Dave Brolley
  2006-08-07 14:39     ` Ronald Hecht
  2006-08-07 14:53     ` Ronald Hecht
  2006-08-04  8:51   ` Ronald Hecht
  1 sibling, 2 replies; 9+ messages in thread
From: Dave Brolley @ 2006-08-03 22:08 UTC (permalink / raw)
  To: Ronald Hecht; +Cc: cgen

I forgot to address your other question which was about the difficulty 
of setting entire_insn before decoding. It's a bit of a chicken and egg 
situation isnt'y it? You can't set entire insn properly until you know 
something about the insn, but you can't call decode without setting 
entire_insn properly.

Your method of calling decode twice won't work because of this.

Most existing ports determine the insn length by looking at a few bits 
in base_insn and use this information to fill entire_insn.

I'm wondering if the decoder shouldn't be redesigned so that all it 
takes is base_insn, which should be all that is necessary to identify 
the insn. The extractors for each format would then read any additional 
bytes as needed. There is already support for this for ISAs with insns 
which are longer than an insn word.

Dave

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-03 21:55 ` Dave Brolley
  2006-08-03 22:08   ` Dave Brolley
@ 2006-08-04  8:51   ` Ronald Hecht
  2006-08-14 20:34     ` Dave Brolley
  1 sibling, 1 reply; 9+ messages in thread
From: Ronald Hecht @ 2006-08-04  8:51 UTC (permalink / raw)
  To: Dave Brolley; +Cc: cgen

Dave Brolley wrote:

> Ronald Hecht wrote:
>
>> Hello again,
>>
>> i found another problem in decode. c. As I have variable instruction 
>> size, decode.c does not handle base_insn and insn in the right way. 
>> The file looks like this:
>>
>> const IDESC *
>> proc8bf_decode (SIM_CPU *current_cpu, IADDR pc,
>>              CGEN_INSN_INT base_insn, CGEN_INSN_INT entire_insn,
>>              ARGBUF *abuf)
>> {
>>  /* Result of decoder.  */
>>  PROC8BF_INSN_TYPE itype;
>>
>>  {
>>    CGEN_INSN_INT insn = base_insn;
>>
>>    {
>>      unsigned int val = (((insn >> 0) & (63 << 0)));
>>      switch (val)
>>      {
>>      case 0 :
>>        if ((entire_insn & 0xff) == 0x0)
>>          { itype = PROC8BF_INSN_NOP; goto extract_sfmt_nop; }
>>        itype = PROC8BF_INSN_X_INVALID; goto extract_sfmt_empty;
>
>
> The generated decoder expects base_insn to be the first base-insn-size 
> bits of the insn shifted as far right as possible. What you have 
> specified is correct and the (((insn >> 0) & (63 << 0))) test us 
> correct. It is looking at the low order 6 bits of the base_insn which 
> are the only significant ones (according to your cpu file.


I completely agree with that. This actually works.

>
> The generated decoder expects entire_insn to the all of the insn bits, 
> also shifted as far right as possible.


Yes, but im my case entire instruction starts at bit 23 with the 
instruction opcode. Bit 15 is the start of an 16 Bit operand. In the 
case of a 16 Bit instruction the opcode starts at bit 15 and then comes 
a 8 bit immediate. The decode functionality beneath decodes this correctly:

<snip>
 extract_sfmt_lda:
  {
    const IDESC *idesc = &proc8bf_insn_data[itype];
    CGEN_INSN_INT insn = entire_insn;
#define FLD(f) abuf->fields.sfmt_lda.f
    UINT f_uimm16;

    f_uimm16 = EXTRACT_MSB0_UINT (insn, 24, 8, 16);

  /* Record the fields for the semantic handler.  */
  FLD (f_uimm16) = f_uimm16;
</snip>

or

<snip>
 extract_sfmt_ldc:
  {
    const IDESC *idesc = &proc8bf_insn_data[itype];
    CGEN_INSN_INT insn = entire_insn;
#define FLD(f) abuf->fields.sfmt_ldc.f
    UINT f_uimm8;

    f_uimm8 = EXTRACT_MSB0_UINT (insn, 16, 8, 8);

  /* Record the fields for the semantic handler.  */
  FLD (f_uimm8) = f_uimm8;
</snip>

So this is correct, but the if clauses in the case statement should use 
the correct bits to double-check. As I mentioned, when I remove the if 
clauses, everything works fine. The simulator works as expected.

>
> The test around the goto is intended to make sure that the untested 
> base_insn bits are as expected. It needs to be there, otherwise, 
> invalid insns get recognized as valid ones. However, it would seem 
> that the test should be against base_insn and not against entire_insn. 
> I'll have a look at some other cgen simulators, including those which 
> use SID to make sure that this assertion holds water. It probably 
> hasn't come up until now, since most sims I have seen are able to pass 
> the same value for base_insn and entire_insn.
>
> Dave
>

I agreee. The test should be against base_insn. But then it still seems 
to be double-checking against the same, or not?

By the way, I'm preparing a website holding the stuff about the 
processor and the tools port. It was pretty difficult to find some 
useful information about how to port the GNU tools starting from a very 
simple example. So I decided to put this information on this website.

http://www-md.e-technik.uni-rostock.de/lehre/vlsi_i/proc8/

Ronald

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-03 22:08   ` Dave Brolley
@ 2006-08-07 14:39     ` Ronald Hecht
  2006-08-07 14:53     ` Ronald Hecht
  1 sibling, 0 replies; 9+ messages in thread
From: Ronald Hecht @ 2006-08-07 14:39 UTC (permalink / raw)
  To: cgen

Dave Brolley wrote:

> I forgot to address your other question which was about the difficulty 
> of setting entire_insn before decoding. It's a bit of a chicken and 
> egg situation isnt'y it? You can't set entire insn properly until you 
> know something about the insn, but you can't call decode without 
> setting entire_insn properly.



I agree, that's always the case.

>
> Your method of calling decode twice won't work because of this.
>
> Most existing ports determine the insn length by looking at a few bits 
> in base_insn and use this information to fill entire_insn.
>
> I'm wondering if the decoder shouldn't be redesigned so that all it 
> takes is base_insn, which should be all that is necessary to identify 
> the insn. The extractors for each format would then read any 
> additional bytes as needed. There is already support for this for ISAs 
> with insns which are longer than an insn word.



That sounds good. Actually, I'm wondering a bit why the disassembler in 
src/opcodes works so great and the simulator port only under certain 
circumstances.  Anyway. CGEN is great stuff. It helps a lot. Whould you 
say that SID is a better choice? Does it work with gdb as SIM does?

Ronald

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-03 22:08   ` Dave Brolley
  2006-08-07 14:39     ` Ronald Hecht
@ 2006-08-07 14:53     ` Ronald Hecht
  2006-08-14 21:19       ` Dave Brolley
  1 sibling, 1 reply; 9+ messages in thread
From: Ronald Hecht @ 2006-08-07 14:53 UTC (permalink / raw)
  To: Dave Brolley; +Cc: cgen

I switched to the SID framework. I found it easier to create a new 
target. The disassemby works better as it calls this disassembler code 
in src/opcodes. But I'm still in trouble with decode.cxx. It looks the 
same as in sim. I'n my opinion the entire_insn should alwasy be left 
aligned and not right_aligned as it is now. Base_insn should have the 
same alignment. I think this way it is easier to support variable sized 
instructions.

Best Regards
Ronald

Dave Brolley wrote:

> I forgot to address your other question which was about the difficulty 
> of setting entire_insn before decoding. It's a bit of a chicken and 
> egg situation isnt'y it? You can't set entire insn properly until you 
> know something about the insn, but you can't call decode without 
> setting entire_insn properly.
>
> Your method of calling decode twice won't work because of this.
>
> Most existing ports determine the insn length by looking at a few bits 
> in base_insn and use this information to fill entire_insn.
>
> I'm wondering if the decoder shouldn't be redesigned so that all it 
> takes is base_insn, which should be all that is necessary to identify 
> the insn. The extractors for each format would then read any 
> additional bytes as needed. There is already support for this for ISAs 
> with insns which are longer than an insn word.
>
> Dave
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-04  8:51   ` Ronald Hecht
@ 2006-08-14 20:34     ` Dave Brolley
  0 siblings, 0 replies; 9+ messages in thread
From: Dave Brolley @ 2006-08-14 20:34 UTC (permalink / raw)
  To: Ronald Hecht; +Cc: cgen

I've been on vacation....

Ronald Hecht wrote:

>> The test around the goto is intended to make sure that the untested 
>> base_insn bits are as expected. It needs to be there, otherwise, 
>> invalid insns get recognized as valid ones. However, it would seem 
>> that the test should be against base_insn and not against 
>> entire_insn. I'll have a look at some other cgen simulators, 
>> including those which use SID to make sure that this assertion holds 
>> water. It probably hasn't come up until now, since most sims I have 
>> seen are able to pass the same value for base_insn and entire_insn.
>>
>> Dave
>>
>
>
> I agreee. The test should be against base_insn. But then it still 
> seems to be double-checking against the same, or not?

No it's not a redundant test. The decoder only tests enough bits in the 
switch to uniquely separate the valid insns. There may be invalid bit 
patterns (i.e. unused opcodes) that still match. The secondary test 
makes sure that *all* of the opcode bits in the insn are tested.

Dave

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-07 14:53     ` Ronald Hecht
@ 2006-08-14 21:19       ` Dave Brolley
  2006-08-15  8:39         ` Ronald Hecht
  0 siblings, 1 reply; 9+ messages in thread
From: Dave Brolley @ 2006-08-14 21:19 UTC (permalink / raw)
  To: Ronald Hecht; +Cc: cgen

Ronald Hecht wrote:

> I switched to the SID framework. I found it easier to create a new 
> target. The disassemby works better as it calls this disassembler code 
> in src/opcodes. But I'm still in trouble with decode.cxx. It looks the 
> same as in sim. I'n my opinion the entire_insn should alwasy be left 
> aligned and not right_aligned as it is now. Base_insn should have the 
> same alignment. I think this way it is easier to support variable 
> sized instructions.
>
I've been looking at what other ports do and it seems that most are able 
to pass the same value base_insn and entire_insn because the opcode bits 
are scattered throughout the insns. The ones which aren't so lucky do 
one of two things:

1) Write some ugly code which examines the base_insn bits in order to 
decide how to position entire_insn.

2) Set base-insn-bitsize in the define-isa of the .cpu file to be the 
size of the largest insn. For SID, base_insn and entire_insn can then be 
passed identically as the insn bits aligned at the 'base-insn-bitsize' 
bit. For example, in your case, the max insn length appears to be 24, so 
you could simply read 3 bytes individually (to avoid endianness 
problems) and place them sequentially in the low order bytes of 
base_insn and entire_insn.

Barring some redesign of the interface as has been discussed, I don't 
see any other options for you.

Dave

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Simulator: base_insn and insn in decode.c
  2006-08-14 21:19       ` Dave Brolley
@ 2006-08-15  8:39         ` Ronald Hecht
  0 siblings, 0 replies; 9+ messages in thread
From: Ronald Hecht @ 2006-08-15  8:39 UTC (permalink / raw)
  To: Dave Brolley; +Cc: cgen

Dave Brolley wrote:

> I've been looking at what other ports do and it seems that most are 
> able to pass the same value base_insn and entire_insn because the 
> opcode bits are scattered throughout the insns. The ones which aren't 
> so lucky do one of two things:
>
> 1) Write some ugly code which examines the base_insn bits in order to 
> decide how to position entire_insn.


This sounds good, but it would be helpful to have the instruction size 
in the automatically generated instruction descriptor table. I say this 
in the disassembler code. This way a lookup would be easier. The 
instruction size may be also used in the <cpu>-sem.cxx code.

>
> 2) Set base-insn-bitsize in the define-isa of the .cpu file to be the 
> size of the largest insn. For SID, base_insn and entire_insn can then 
> be passed identically as the insn bits aligned at the 
> 'base-insn-bitsize' bit. For example, in your case, the max insn 
> length appears to be 24, so you could simply read 3 bytes individually 
> (to avoid endianness problems) and place them sequentially in the low 
> order bytes of base_insn and entire_insn.
>

This actually works for me! Thanks alot for the help. Now, my code looks 
like this:

      try
        {
          // Fetch 24-bit pieces separately, so endianness
          // conversions can be done on this chunk size.
          UQI insn0 = this->GETIMEMQI (pc, pc);
          UQI insn1 = this->GETIMEMQI (pc, pc+1);
          UQI insn2 = this->GETIMEMQI (pc, pc+2);
          USI insn = (insn0 << 16) | (insn1 << 8) | insn2;

          sem->decode (this, pc, insn, insn);

        }
      catch (cpu_memory_fault& t)
        {
          this->memory_trap (t);
          break;
        }

The file can be found on 
http://www-md.e-technik.uni-rostock.de/lehre/vlsi_i/proc8/src/sid/component/cgen-cpu/proc8/proc8bf.cxx
The simulator also works with gdb except for a "Memory access error 
while loading section .text." occuring some times. But I suspect, this 
is out of the scope of this mailing list.

Thanks again
Ronald

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-08-15  8:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-31 11:58 Simulator: base_insn and insn in decode.c Ronald Hecht
2006-08-03 21:55 ` Dave Brolley
2006-08-03 22:08   ` Dave Brolley
2006-08-07 14:39     ` Ronald Hecht
2006-08-07 14:53     ` Ronald Hecht
2006-08-14 21:19       ` Dave Brolley
2006-08-15  8:39         ` Ronald Hecht
2006-08-04  8:51   ` Ronald Hecht
2006-08-14 20:34     ` Dave Brolley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).