this it the piece of C that has the issue
basen_result_t basen_value_to_ascii
(
uint32_t value,
uint8_t ascii_value[],
uint8_t mybase,
uint32_t format_len
)
{
basen_result_t ans;
uint32_t evaluated_digits_len;
uint32_t required_format_len;
uint32_t digits_offset;
uint32_t An;
uint32_t i;
uint32_t j;
uint32_t k;
uint8_t ch;
ans.is_valid = False;
ans.value = value;
ans.status = basen_result_ok;
if (mybase <= 16)
{
/* early evaluate of required format len */
required_format_len = format_len;
if (required_format_len>0)
{
required_format_len--;
}
/* evaluate of digit len */
An = value;
i = 0;
while ((An != 0)) // logicalAnd (i < basen_digit_n))
{
i++;
An = An / mybase;
}
if ((required_format_len < string_safe_len)logicalAnd(i < string_safe_len))
{
evaluated_digits_len = i;
/* check required_format_len */
if (evaluated_digits_len >= required_format_len)
{
/*
* fix1
*/
required_format_len = evaluated_digits_len;
}
/* evaluate format offset */
if (required_format_len > 0)
{
/*
* offset case A
* do format digits
*/
digits_offset = required_format_len - evaluated_digits_len;
}
else
{
/*
* offset case B
* do not format digits
*/
/* do not format digits */
digits_offset = 0;
}
/* zero stuffing */
for (i = 0; i < required_format_len; i++)
{
ascii_value[i] = '0';
}
ascii_value[i] = '\0';
/* evaluate */
An = value;
i = 0;
do
{
/*
* is the mips1 bug here ???
*/
j = (evaluated_digits_len - i) + digits_offset;
k = (An % mybase);
ch=basen_digit[k];
ascii_value[j] = ch;
An = An / mybase;
i++; // <-------------------- unexpected behavior happens here, i++ is not i incremented correctly
} while (An != 0);
j = (evaluated_digits_len + digits_offset + 1);
ascii_value[j] = '\0';
ans.is_valid = True;
}
else
{
/*
* failure1
*/
ascii_value[0] = '\0';
ans.status = basen_result_not_defined;
}
}
else
{
/*
* failure2
*/
ascii_value[0] = '\0';
ans.status = basen_result_unsupported_base;
}
return ans;
}
this is the gcc-mips ENV used in the build up
MY_CC=mips-elf-gcc -G0 -fPIE -O0 -mips1 -N -mno-check-zero-division -mdivide-breaks -mno-gpopt
MY_CC=mips-elf-gcc -G0 -fPIE -O1 -mips1 -N -mno-check-zero-division -mdivide-breaks -mno-gpopt
MY_CC=mips-elf-gcc -G0 -fPIE -O2 -mips1 -N -mno-check-zero-division -mdivide-breaks -mno-gpopt
this is the assembly with -O0, no unexpected behavior
basen_value_to_ascii:
.frame $fp,56,$31 # vars= 48, regs= 1/0, args= 0, gp= 0
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-56
sw $fp,52($sp)
move $fp,$sp
move $2,$4
sw $5,60($fp)
sw $6,64($fp)
move $3,$7
sb $3,68($fp)
sw $0,32($fp)
lw $3,60($fp)
nop
sw $3,36($fp)
li $3,1 # 0x1
sw $3,40($fp)
lbu $3,68($fp)
nop
sltu $3,$3,17
beq $3,$0,$L40
nop
lw $3,72($fp)
nop
sw $3,24($fp)
lw $3,24($fp)
nop
beq $3,$0,$L41
nop
lw $3,24($fp)
nop
addiu $3,$3,-1
sw $3,24($fp)
$L41:
lw $3,60($fp)
nop
sw $3,16($fp)
sw $0,12($fp)
b $L42
nop
$L43:
lw $3,12($fp)
nop
addiu $3,$3,1
sw $3,12($fp)
lbu $3,68($fp)
lw $4,16($fp)
nop
divu $0,$4,$3
mfhi $4
mflo $3
sw $3,16($fp)
$L42:
lw $3,16($fp)
nop
bne $3,$0,$L43
nop
lw $3,24($fp)
nop
sltu $3,$3,40
beq $3,$0,$L44
nop
lw $3,12($fp)
nop
sltu $3,$3,40
beq $3,$0,$L44
nop
lw $3,12($fp)
nop
sw $3,28($fp)
lw $4,28($fp)
lw $3,24($fp)
nop
sltu $3,$4,$3
bne $3,$0,$L45
nop
lw $3,28($fp)
nop
sw $3,24($fp)
$L45:
lw $3,24($fp)
nop
beq $3,$0,$L46
nop
lw $4,24($fp)
lw $3,28($fp)
nop
subu $3,$4,$3
sw $3,20($fp)
b $L47
nop
$L46:
sw $0,20($fp)
$L47:
sw $0,12($fp)
b $L48
nop
$L49:
lw $4,64($fp)
lw $3,12($fp)
nop
addu $3,$4,$3
li $4,48 # 0x30
sb $4,0($3)
lw $3,12($fp)
nop
addiu $3,$3,1
sw $3,12($fp)
$L48:
lw $4,12($fp)
lw $3,24($fp)
nop
sltu $3,$4,$3
bne $3,$0,$L49
nop
lw $4,64($fp)
lw $3,12($fp)
nop
addu $3,$4,$3
sb $0,0($3)
lw $3,60($fp)
nop
sw $3,16($fp)
sw $0,12($fp)
$L50:
lw $4,28($fp)
lw $3,12($fp)
nop
subu $4,$4,$3
lw $3,20($fp)
nop
addu $3,$4,$3
sw $3,8($fp)
lbu $3,68($fp)
lw $4,16($fp)
nop
divu $0,$4,$3
mfhi $3
sw $3,4($fp)
lw $4,4($fp)
lui $3,%hi(basen_digit)
addiu $3,$3,%lo(basen_digit)
addu $3,$4,$3
lb $3,0($3)
nop
sb $3,0($fp)
lw $4,64($fp)
lw $3,8($fp)
nop
addu $3,$4,$3
lbu $4,0($fp)
nop
sb $4,0($3)
lbu $3,68($fp)
lw $4,16($fp)
nop
divu $0,$4,$3
mfhi $4
mflo $3
sw $3,16($fp)
lw $3,12($fp)
nop
addiu $3,$3,1
sw $3,12($fp)
lw $3,16($fp)
nop
bne $3,$0,$L50
nop
lw $4,28($fp)
lw $3,20($fp)
nop
addu $3,$4,$3
addiu $3,$3,1
sw $3,8($fp)
lw $4,64($fp)
lw $3,8($fp)
nop
addu $3,$4,$3
sb $0,0($3)
li $3,1 # 0x1
sw $3,32($fp)
nop
b $L52
nop
$L44:
lw $3,64($fp)
nop
sb $0,0($3)
sw $0,40($fp)
b $L52
nop
$L40:
lw $3,64($fp)
nop
sb $0,0($3)
li $3,32 # 0x20
sw $3,40($fp)
$L52:
lw $5,32($fp)
lw $4,36($fp)
lw $3,40($fp)
sw $5,0($2)
sw $4,4($2)
sw $3,8($2)
move $sp,$fp
lw $fp,52($sp)
addiu $sp,$sp,56
j $31
nop
this is the assembly with -O1, no unexpected behavior
basen_value_to_ascii:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
move $2,$4
lw $3,16($sp)
andi $7,$7,0x00ff
sltu $4,$7,17
beq $4,$0,$L43
nop
beq $3,$0,$L45
move $8,$3
addiu $8,$3,-1
$L45:
beq $5,$0,$L47
move $3,$0
move $9,$5
$L48:
divu $0,$9,$7
mflo $9
bne $9,$0,$L48
addiu $3,$3,1
$L47:
sltu $4,$8,40
beq $4,$0,$L49
nop
sltu $4,$3,40
beq $4,$0,$L49
nop
sltu $4,$3,$8
beq $4,$0,$L50
move $9,$3
move $9,$8
$L50:
beq $9,$0,$L52
move $10,$0
move $4,$0
li $10,48 # 0x30
addu $8,$6,$4
$L60:
sb $10,0($8)
addiu $4,$4,1
sltu $8,$4,$9
bne $8,$0,$L60
addu $8,$6,$4
subu $10,$9,$3
$L52:
addu $9,$6,$9
sb $0,0($9)
addu $4,$10,$3
addu $4,$6,$4
move $8,$5
lui $9,%hi(basen_digit)
addiu $9,$9,%lo(basen_digit)
$L54:
divu $0,$8,$7
mfhi $8
addu $8,$8,$9
lbu $8,0($8)
nop
sb $8,0($4)
mflo $8
bne $8,$0,$L54
addiu $4,$4,-1
addu $6,$6,$3
addu $10,$6,$10
sb $0,1($10)
li $3,1 # 0x1
b $L55
li $4,1 # 0x1
$L49:
sb $0,0($6)
move $3,$0
b $L55
move $4,$0
$L43:
sb $0,0($6)
move $3,$0
li $4,32 # 0x20
$L55:
sw $4,8($2)
sw $5,4($2)
j $31
sw $3,0($2)
this is the assembly with -O2, unexpected behavior, the local variable is out of range
basen_value_to_ascii:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
andi $7,$7,0x00ff
sltu $3,$7,17
lw $8,16($sp)
beq $3,$0,$L47
move $2,$4
beq $8,$0,$L49
nop
addiu $8,$8,-1
$L49:
beq $5,$0,$L51
move $3,$0
move $9,$5
$L52:
divu $0,$9,$7
mflo $9
bne $9,$0,$L52
addiu $3,$3,1
$L51:
sltu $4,$8,40
beq $4,$0,$L53
sltu $4,$3,40
beq $4,$0,$L53
sltu $4,$3,$8
beq $4,$0,$L54
subu $10,$8,$3
$L55:
move $4,$0
li $12,48 # 0x30
$L58:
addu $11,$6,$4
addiu $4,$4,1
sltu $9,$4,$8
bne $9,$0,$L58
sb $12,0($11)
$L57:
addu $8,$6,$8
addu $4,$10,$3
lui $9,%hi(basen_digit)
sb $0,0($8)
addu $4,$6,$4
addiu $9,$9,%lo(basen_digit)
move $8,$5
$L59:
divu $0,$8,$7
mfhi $8
addu $8,$9,$8
lbu $11,0($8)
mflo $8
sb $11,0($4)
bne $8,$0,$L59
addiu $4,$4,-1
addu $3,$6,$3
addu $10,$3,$10
li $4,1 # 0x1
li $3,1 # 0x1
sb $0,1($10)
sw $4,8($2)
sw $5,4($2)
j $31
sw $3,0($2)
$L47:
move $3,$0
li $4,32 # 0x20
sb $0,0($6)
sw $4,8($2)
sw $5,4($2)
j $31
sw $3,0($2)
$L53:
move $3,$0
move $4,$0
sb $0,0($6)
sw $4,8($2)
sw $5,4($2)
j $31
sw $3,0($2)
$L54:
bne $3,$0,$L56
nop
move $8,$0
b $L57
move $10,$0
$L56:
move $8,$3
b $L55
move $10,$0