.section .text

/*
 * unsigned long unaligned_read(void *addr, void *value, unsigned long n, bool sign)
 *
 * a0: addr
 * a1: value
 * a2: n
 * a3: sign
 */
.global _unaligned_read
_unaligned_read:
	beqz	$a2, 5f

	li.w	$t2, 0
	addi.d	$t0, $a2, -1
	slli.d	$t1, $t0, 3
	add.d 	$a0, $a0, $t0

	beqz	$a3, 2f
1:	ld.b	$t3, $a0, 0
	b	3f

2:	ld.bu	$t3, $a0, 0
3:	sll.d	$t3, $t3, $t1
	or	$t2, $t2, $t3
	addi.d	$t1, $t1, -8
	addi.d	$a0, $a0, -1
	addi.d	$a2, $a2, -1
	bgtz	$a2, 2b
4:	st.d	$t2, $a1, 0

	move	$a0, $a2
	jr	$ra

5:	li.w    $a0, -1
	jr	$ra

	_asm_extable 1b, 5b
	_asm_extable 2b, 5b
	_asm_extable 4b, 5b

/*
 * unsigned long unaligned_write(void *addr, unsigned long value, unsigned long n)
 *
 * a0: addr
 * a1: value
 * a2: n
 */
.global _unaligned_write
_unaligned_write:
	beqz	$a2, $3f

	li.w	$t0, 0
1:	srl.d	$t1, $a1, $t0
2:	st.b	$t1, $a0, 0
	addi.d	$t0, $t0, 8
	addi.d	$a2, $a2, -1
	addi.d	$a0, $a0, 1
	bgtz	$a2, 1b

	move	$a0, $a2
	jr	$ra

3:	li.w    $a0, -1
	jr	$ra

	_asm_extable 2b, 3b
