/* Simulator for TI MSP430 and MSP430X
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+ Copyright (C) 2013-2021 Free Software Foundation, Inc.
Contributed by Red Hat.
Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
/* Initialise the simulator. */
- if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+ if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
{
sim_state_free (sd);
return 0;
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x500, 1) == 0)
- sim_do_commandf (sd, "memory-region 0x500,0xfa00"); /* RAM and/or ROM */
+ sim_do_commandf (sd, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
{
MSP430_Opcode_Operand *op = opc->op + n;
- int rv;
+ int rv = 0;
int addr;
unsigned char buf[4];
int incval = 0;
put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
{
MSP430_Opcode_Operand *op = opc->op + n;
- int rv;
+ int rv = 0;
int addr;
unsigned char buf[4];
int incval = 0;
switch (HWMULT (sd, hwmult_type))
{
case UNSIGN_32:
- HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
- HWMULT (sd, hwmult_signed_result) = (signed) HWMULT (sd, hwmult_result);
+ a = HWMULT (sd, hwmult_op1);
+ b = HWMULT (sd, hwmult_op2);
+ /* For unsigned 32-bit multiplication of 16-bit operands, an
+ explicit cast is required to prevent any implicit
+ sign-extension. */
+ HWMULT (sd, hwmult_result) = (unsigned32) a * (unsigned32) b;
+ HWMULT (sd, hwmult_signed_result) = a * b;
HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
break;
a = sign_ext (HWMULT (sd, hwmult_op1), 16);
b = sign_ext (HWMULT (sd, hwmult_op2), 16);
HWMULT (sd, hwmult_signed_result) = a * b;
- HWMULT (sd, hwmult_result) = (unsigned) HWMULT (sd, hwmult_signed_result);
+ HWMULT (sd, hwmult_result) = (unsigned32) a * (unsigned32) b;
HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
break;
case UNSIGN_MAC_32:
- HWMULT (sd, hwmult_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
- HWMULT (sd, hwmult_signed_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
+ a = HWMULT (sd, hwmult_op1);
+ b = HWMULT (sd, hwmult_op2);
+ HWMULT (sd, hwmult_accumulator)
+ += (unsigned32) a * (unsigned32) b;
+ HWMULT (sd, hwmult_signed_accumulator) += a * b;
HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
break;
case SIGN_MAC_32:
a = sign_ext (HWMULT (sd, hwmult_op1), 16);
b = sign_ext (HWMULT (sd, hwmult_op2), 16);
- HWMULT (sd, hwmult_accumulator) += a * b;
+ HWMULT (sd, hwmult_accumulator)
+ += (unsigned32) a * (unsigned32) b;
HWMULT (sd, hwmult_signed_accumulator) += a * b;
HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
switch (HWMULT (sd, hw32mult_type))
{
case UNSIGN_64:
- HWMULT (sd, hw32mult_result) = HWMULT (sd, hw32mult_op1) * HWMULT (sd, hw32mult_op2);
+ HWMULT (sd, hw32mult_result)
+ = (unsigned64) HWMULT (sd, hw32mult_op1)
+ * (unsigned64) HWMULT (sd, hw32mult_op2);
break;
case SIGN_64:
- HWMULT (sd, hw32mult_result) = sign_ext (HWMULT (sd, hw32mult_op1), 32)
+ HWMULT (sd, hw32mult_result)
+ = sign_ext (HWMULT (sd, hw32mult_op1), 32)
* sign_ext (HWMULT (sd, hw32mult_op2), 32);
break;
}
if ((call_addr & ~0x3f) == 0x00180)
{
/* Syscall! */
+ int arg1, arg2, arg3, arg4;
int syscall_num = call_addr & 0x3f;
- int arg1 = MSP430_CPU (sd)->state.regs[12];
- int arg2 = MSP430_CPU (sd)->state.regs[13];
- int arg3 = MSP430_CPU (sd)->state.regs[14];
- int arg4 = MSP430_CPU (sd)->state.regs[15];
+
+ /* syscall_num == 2 is used for the variadic function "open".
+ The arguments are set up differently for variadic functions.
+ See slaa534.pdf distributed by TI. */
+ if (syscall_num == 2)
+ {
+ arg1 = MSP430_CPU (sd)->state.regs[12];
+ arg2 = mem_get_val (sd, SP, 16);
+ arg3 = mem_get_val (sd, SP + 2, 16);
+ arg4 = mem_get_val (sd, SP + 4, 16);
+ }
+ else
+ {
+ arg1 = MSP430_CPU (sd)->state.regs[12];
+ arg2 = MSP430_CPU (sd)->state.regs[13];
+ arg3 = MSP430_CPU (sd)->state.regs[14];
+ arg4 = MSP430_CPU (sd)->state.regs[15];
+ }
MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd),
syscall_num, arg1, arg2,
MSP430_Opcode_Decoded opcode_buf;
MSP430_Opcode_Decoded *opcode = &opcode_buf;
int s1, s2, result;
- int u1, u2, uresult;
- int c, reg;
+ int u1 = 0, u2, uresult;
+ int c = 0, reg;
int sp;
int carry_to_use;
int n_repeats;
int rept;
- int op_bytes, op_bits;
+ int op_bytes = 0, op_bits;
PC &= 0xfffff;
opcode_pc = PC;
if (TRACE_ANY_P (MSP430_CPU (sd)))
trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
- TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, "");
+ TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, " ");
TRACE_DISASM (MSP430_CPU (sd), opcode_pc);
u1 = SRC;
carry_to_use = u1 & 1;
uresult = u1 >> 1;
- if (SR & MSP430_FLAG_C)
- uresult |= (1 << (opcode->size - 1));
+ /* If the ZC bit of the opcode is set, it means we are synthesizing
+ RRUX, so the carry bit must be ignored. */
+ if (opcode->zc == 0 && (SR & MSP430_FLAG_C))
+ uresult |= (1 << (opcode->size - 1));
TRACE_ALU (MSP430_CPU (sd), "RRC: %#x >>= %#x",
u1, uresult);
DEST (uresult);