public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: Andrew Burgess <aburgess@redhat.com>,
	"gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [PATCH] sim: riscv: Fix some issues with class-a instructions
Date: Mon, 22 Apr 2024 18:25:32 +0200	[thread overview]
Message-ID: <AS8P193MB12850F2C5102506A4E5ED8E7E4122@AS8P193MB1285.EURP193.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <87ttjtfnlf.fsf@redhat.com>

On 4/22/24 17:01, Andrew Burgess wrote:
> Bernd Edlinger <bernd.edlinger@hotmail.de> writes:
> 
>> This fixes some issues with atomic instruction handling.  First the
>> instructions may have AQ and/or RL bits set, but the emulator has no
>> such concept, so we have to ignore those.
>>
>> According to the spec the memory must be naturally aligned, otherwise
>> an exception shall be thrown, so do the sim_core read/write aligned.
>> In the case of riscv64 target, there were the LR_D and SC_D
>> 64bit load and store instructions missing, so add those.
>>
>> Also the AMOMIN/AMOMAX[U]_W instructions were not correct for riscv64
>> because the upper half word of the input registers were not ignored
>> as they should, so use explicit type-casts to uint32_t and int32_t
>> for those.
>>
>> And finally make the class-a instruction set only executable if a
>> riscv cpu model with A extension is selected.
>> ---
>>  sim/riscv/sim-main.c | 72 ++++++++++++++++++++++++++++++++------------
>>  1 file changed, 53 insertions(+), 19 deletions(-)
>>
>> diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c
>> index e4b15b533ba..be38baa2f93 100644
>> --- a/sim/riscv/sim-main.c
>> +++ b/sim/riscv/sim-main.c
>> @@ -841,6 +841,9 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>  static sim_cia
>>  execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>  {
>> +  unsigned_word mask_aq = OP_MASK_AQ << OP_SH_AQ;
>> +  unsigned_word mask_rl = OP_MASK_RL << OP_SH_RL;
>> +  unsigned_word mask_aqrl = mask_aq | mask_rl;
>>    struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
>>    SIM_DESC sd = CPU_STATE (cpu);
>>    struct riscv_sim_state *state = RISCV_SIM_STATE (sd);
>> @@ -855,13 +858,18 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>    sim_cia pc = riscv_cpu->pc + 4;
>>  
>>    /* Handle these two load/store operations specifically.  */
>> -  switch (op->match)
>> +  switch (op->match & ~mask_aqrl)
> 
> Given the aq/rl bits are not handled, maybe we should be issuing a 1
> time warning if we encounter an instruction with these bits set?  Or
> maybe it's not relevant for the simulator?  I think more detail about
> what the thinking is here would help: Is this safe to ignore, or is this
> something we're putting off for the future?
> 

No, these bits mean "acquire" and "release" memory ordering, they are only
noise for a software simulator engine, they would have a meaning when the
memory accesses are executing in parallel to the instruction pipeline.

The issue is, that they are very commonly generated whenever a C++ try/catch
construct is used, and of course also when atomic builtin functions are used.


Thanks
Bernd.

>>      {
>> +    case MATCH_LR_D:
>>      case MATCH_LR_W:
>>        TRACE_INSN (cpu, "%s %s, (%s);", op->name, rd_name, rs1_name);
>> -      store_rd (cpu, rd,
>> -	sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
>> -				   riscv_cpu->regs[rs1]));
>> +      if (op->xlen_requirement == 64)
>> +	tmp = sim_core_read_aligned_8 (cpu, riscv_cpu->pc, read_map,
>> +				       riscv_cpu->regs[rs1]);
>> +      else
>> +	tmp = EXTEND32 (sim_core_read_aligned_4 (cpu, riscv_cpu->pc, read_map,
>> +						 riscv_cpu->regs[rs1]));
> 
> I might be completely off the mark here, but I'm unsure about this
> change from using 'unaligned' to 'aligned' here.
> 
> From my reading of common/sim-n-core.h, I believe the aligned/unaligned
> refers to the callers knowledge of the address.  So calling
> sim_core_read_aligned_* means that the common code should assume that
> the address is correctly aligned.  While sim_core_read_unaligned_*
> handles the case that the address might not be aligned, and raises the
> exception.
> 
> Please remember: I might be completely wrong here, and you just need to
> explain to me what's going on better.
> 
> 
> 
>> +      store_rd (cpu, rd, tmp);
>>  
>>        /* Walk the reservation list to find an existing match.  */
>>        amo_curr = state->amo_reserved_list;
>> @@ -878,6 +886,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>        amo_curr->next = state->amo_reserved_list;
>>        state->amo_reserved_list = amo_curr;
>>        goto done;
>> +    case MATCH_SC_D:
>>      case MATCH_SC_W:
>>        TRACE_INSN (cpu, "%s %s, %s, (%s);", op->name, rd_name, rs2_name,
>>  		  rs1_name);
>> @@ -889,7 +898,12 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>  	  if (amo_curr->addr == riscv_cpu->regs[rs1])
>>  	    {
>>  	      /* We found a reservation, so operate it.  */
>> -	      sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
>> +	      if (op->xlen_requirement == 64)
>> +		sim_core_write_aligned_8 (cpu, riscv_cpu->pc, write_map,
>> +					  riscv_cpu->regs[rs1],
>> +					  riscv_cpu->regs[rs2]);
>> +	      else
>> +		sim_core_write_aligned_4 (cpu, riscv_cpu->pc, write_map,
>>  					  riscv_cpu->regs[rs1],
>>  					  riscv_cpu->regs[rs2]);
>>  	      store_rd (cpu, rd, 0);
>> @@ -913,14 +927,14 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>    TRACE_INSN (cpu, "%s %s, %s, (%s);",
>>  	      op->name, rd_name, rs2_name, rs1_name);
>>    if (op->xlen_requirement == 64)
>> -    tmp = sim_core_read_unaligned_8 (cpu, riscv_cpu->pc, read_map,
>> -				     riscv_cpu->regs[rs1]);
>> +    tmp = sim_core_read_aligned_8 (cpu, riscv_cpu->pc, read_map,
>> +				   riscv_cpu->regs[rs1]);
>>    else
>> -    tmp = EXTEND32 (sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
>> -					       riscv_cpu->regs[rs1]));
>> +    tmp = EXTEND32 (sim_core_read_aligned_4 (cpu, riscv_cpu->pc, read_map,
>> +					     riscv_cpu->regs[rs1]));
>>    store_rd (cpu, rd, tmp);
>>  
>> -  switch (op->match)
>> +  switch (op->match & ~mask_aqrl)
>>      {
>>      case MATCH_AMOADD_D:
>>      case MATCH_AMOADD_W:
>> @@ -931,25 +945,37 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>        tmp = riscv_cpu->regs[rd] & riscv_cpu->regs[rs2];
>>        break;
>>      case MATCH_AMOMAX_D:
>> -    case MATCH_AMOMAX_W:
>>        tmp = max ((signed_word) riscv_cpu->regs[rd],
>>  		 (signed_word) riscv_cpu->regs[rs2]);
>>        break;
>> +    case MATCH_AMOMAX_W:
>> +      tmp = max ((int32_t) riscv_cpu->regs[rd],
>> +		 (int32_t) riscv_cpu->regs[rs2]);
> 
> I wonder if we should use EXTEND32 here?  There seems to be a mix of
> styles throughout the file.
> 
>> +      break;
>>      case MATCH_AMOMAXU_D:
>> -    case MATCH_AMOMAXU_W:
>>        tmp = max ((unsigned_word) riscv_cpu->regs[rd],
>>  		 (unsigned_word) riscv_cpu->regs[rs2]);
>>        break;
>> +    case MATCH_AMOMAXU_W:
>> +      tmp = max ((uint32_t) riscv_cpu->regs[rd],
>> +		 (uint32_t) riscv_cpu->regs[rs2]);
> 
> And maybe EXTEND32 again here, but I guess we'd still need the cast to
> unsigned_word.
> 
>> +      break;
>>      case MATCH_AMOMIN_D:
>> -    case MATCH_AMOMIN_W:
>>        tmp = min ((signed_word) riscv_cpu->regs[rd],
>>  		 (signed_word) riscv_cpu->regs[rs2]);
>>        break;
>> +    case MATCH_AMOMIN_W:
>> +      tmp = min ((int32_t) riscv_cpu->regs[rd],
>> +		 (int32_t) riscv_cpu->regs[rs2]);
> 
> Same question as above.
> 
>> +      break;
>>      case MATCH_AMOMINU_D:
>> -    case MATCH_AMOMINU_W:
>>        tmp = min ((unsigned_word) riscv_cpu->regs[rd],
>>  		 (unsigned_word) riscv_cpu->regs[rs2]);
>>        break;
>> +    case MATCH_AMOMINU_W:
>> +      tmp = min ((uint32_t) riscv_cpu->regs[rd],
>> +		 (uint32_t) riscv_cpu->regs[rs2]);
> 
> Same question as above.
> 
>> +      break;
>>      case MATCH_AMOOR_D:
>>      case MATCH_AMOOR_W:
>>        tmp = riscv_cpu->regs[rd] | riscv_cpu->regs[rs2];
>> @@ -968,11 +994,11 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>      }
>>  
>>    if (op->xlen_requirement == 64)
>> -    sim_core_write_unaligned_8 (cpu, riscv_cpu->pc, write_map,
>> -				riscv_cpu->regs[rs1], tmp);
>> +    sim_core_write_aligned_8 (cpu, riscv_cpu->pc, write_map,
>> +			      riscv_cpu->regs[rs1], tmp);
>>    else
>> -    sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
>> -				riscv_cpu->regs[rs1], tmp);
>> +    sim_core_write_aligned_4 (cpu, riscv_cpu->pc, write_map,
>> +			      riscv_cpu->regs[rs1], tmp);
>>  
>>   done:
>>    return pc;
>> @@ -1307,7 +1333,15 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
>>    switch (op->insn_class)
>>      {
>>      case INSN_CLASS_A:
>> -      return execute_a (cpu, iw, op);
>> +      /* Check whether model with A extension is selected.  */
>> +      if (riscv_cpu->csr.misa & 1)
>> +	return execute_a (cpu, iw, op);
>> +      else
>> +	{
>> +	  TRACE_INSN (cpu, "UNHANDLED EXTENSION: %d", op->insn_class);
>> +	  sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled,
>> +			   SIM_SIGILL);
>> +	}
> 
> Thanks,
> Andrew
> 
>>      case INSN_CLASS_C:
>>        /* Check whether model with C extension is selected.  */
>>        if (riscv_cpu->csr.misa & 4)
>> -- 
>> 2.39.2
> 

  reply	other threads:[~2024-04-22 16:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-22  9:45 Bernd Edlinger
2024-04-22 15:01 ` Andrew Burgess
2024-04-22 16:25   ` Bernd Edlinger [this message]
2024-04-23 13:56   ` Bernd Edlinger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8P193MB12850F2C5102506A4E5ED8E7E4122@AS8P193MB1285.EURP193.PROD.OUTLOOK.COM \
    --to=bernd.edlinger@hotmail.de \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).