> For the complete documentation index, see [llms.txt](https://jupitersim.gitbook.io/jupiter/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jupitersim.gitbook.io/jupiter/es/ensamblador/instrucciones.md).

# Instrucciones

## add

Suma el registro `x[rs2]` al registro `x[rs1]` y escribe el resultado en `x[rd]`. Overflow aritmético ignorado.

* *Add*
* **Operación**: x\[rd] = x\[rs1] + x\[rs2]
* **Tipo**: R

**Uso**

```
add rd, rs1, rs2
```

## addi

Suma el inmediato sign-extended al registro `x[rs1]` y escribe el resultado en `x[rd]`. Overflow aritmético ignorado.

* *Add Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$+$$ sext(immediate)
* **Tipo**: I

**Uso**

```
addi rd, rs1, immediate
```

## and

Calcula el AND a nivel de bits de los registros `x[rs1]` y `x[rs2]` y escribe el resultado en `x[rd]`.

* *AND*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$&$$ x\[rs2]
* **Tipo**: R

**Uso**

```
and rd, rs1, rs2
```

## andi

Calcula el AND a nivel de bits del inmediato sign-extended y el registro `x[rs1]` y escribe el resultado en `x[rd]`.

* *AND Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$&$$ sext(immediate)
* **Tipo**: I

**Uso**

```
andi rd, rs1, immediate
```

## auipc

Suma el inmediato sign-extended de 20 bits, corrido a la izquierda por 12 bits, al `pc`, y escribe el resultado en `x[rd]`.

* *AND Immediate*
* **Operación**: x\[rd] $$=$$ pc $$+$$ sext( immediate\[31:12] $$<<$$ 12 )
* **Tipo**: U

**Uso**

```
auipc rd, immediate
```

## beq

Si el registro `x[rs1]` es igual al registro `x[rs2]`, asignar al `pc` su valor actual más el `offset` sign-extended.

* *Branch if Equal*
* **Operación**: if (rs1 $$==$$ rs2)  then pc $$+=$$ sext(offset)
* **Tipo**: B

**Uso**

```
beq rs1, rs2, offset
```

## bge

Si el registro `x[rs1]` es por lo menos `x[rs2]`, tratando los valores como números de complemento a dos, asignar al `pc` su valor actual más el `offset` sign-extended.

* *Branch if Greater Than or Equal*
* **Operación**: if (rs1 $$≥\_s$$ rs2) pc $$+=$$ sext( offset )
* **Tipo**: B

**Uso**

```
bge rs1, rs2, offset
```

## bgeu

Si el registro `x[rs1]` es por lo menos `x[rs2]`, tratando los valores como números sin signo, asignar al `pc` su valor actual más el `offset` unsign-extended.

* *Branch if Greater Than or Equal, Unsigned*
* **Operación**: if (rs1 $$>\_u$$ rs2) then pc $$+=$$ sext( offset )
* **Tipo**: B

**Uso**

```
bgeu rs1, rs2, offset
```

## blt

Si el registro `x[rs1]` es menor que `x[rs2]`, tratando los valores como números de complemento a dos, asignar al `pc` su valor actual más el `offset` sign-extended

* *Branch if Less Than*
* **Operación**: if (rs1 $$<\_s$$ rs2) then pc $$+=$$ sext( offset )
* **Tipo**: B

**Uso**

```
blt rs1, rs2, offset
```

## bltu

Si el registro `x[rs1]` es menor que `x[rs2]`, tratando los valores como números sin signo, asignar al `pc` su valor actual más el `offset` unsign-extended.

* *Branch if Less Than, Unsigned*
* **Operación**: if (rs1 $$<\_u$$ rs2) then pc $$+=$$sext( offset )
* **Tipo**: B

**Uso**

```
bltu rs1, rs2, offset
```

## bne

Si el registro `x[rs1]` no es igual al registro `x[rs2]`, asignar al `pc` su valor actual más el `offset` sign-extended.

* *Branch if Not Equal*
* **Operación**: if (rs1 $$≠\_s$$rs2) then pc $$+=$$ sext( offset )
* **Tipo**: B

**Uso**

```
bne rs1, rs2, offset
```

## csrrc

Setea en `t` el valor del control and status register `csr`. Escribe el `AND` a nivel de bits de `t` y el complemento a uno de `x[rs1]` en el `csr`, luego escribe `t` en el `x[rd]`.

* *Control and Status Register Read and Clear*
* **Operación**: t $$=$$ CSRs\[csr];  CSRs\[csr] $$=$$ t $$&$$ $$∼$$x\[rs1];  x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
csrrc rd, csr, rs1
```

## csrrci

Setea en `t` el valor del control and status register `csr`. Escribe el `AND` a nivel de bits de `t` y el complemento a uno del inmediato de cinco bits zero-extended `zimm` en el `csr`, luego escribe `t` en el `x[rd]` (Los bits del 5 en adelante en el csr no son modificados).

* *Control and Status Register Read and Clear Immediate*
* **Operación**: t $$=$$ CSRs\[csr]; CSRs\[csr] $$=$$ t  $$&$$ $$∼$$zimm;  x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
csrrci rd, csr, zimm[4:0]
```

## csrrs

Setea en `t` el valor del control and status register `csr`. Escribe el `OR` a nivel de bits de `t` y `x[rs1]` en el `csr`, luego escribe `t` en el `x[rd]`.

* *Control and Status Register Read and Set*
* **Operación**: t $$=$$ CSRs\[csr];  CSRs\[csr] $$=$$ t $$|$$ x\[rs1];  x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
csrrs rd, csr, rs1
```

## csrrsi

Setea en `t` el valor del control and status register `csr`. Escribe el `OR` a nivel de bits de `t` y y el inmediato de cinco bits zero-extended `zimm` en el `csr`, luego escribe `t` en el `x[rd]` . (Los bits del 5 en adelante en el csr no son modificados).

* *Control and Status Register Read and Set Immediate*
* **Operación**: t $$=$$ CSRs\[csr];  CSRs\[csr] $$=$$ t $$|$$ zimm;  x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
csrrsi rd, csr, zimm[4:0]
```

## csrrw

Setea en `t` el valor del control and status register `csr`. Copia el valor de `x[rs1]` en el `csr`, luego escribe el valor de `t` en el `x[rd]`.

* *Control and Status Register Read and Write*
* **Operación**: t $$=$$ CSRs\[csr];  CSRs\[csr]  $$=$$ x\[rs1];  x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
csrrw rd, csr, rs1
```

## csrrwi

Copia el valor del control and status register `csr` en `x[rd]`, luego escribe el inmediato de cinco bits zero-extended `zimm` en el `csr`.

* *Control and Status Register Read and Write Immediate*
* **Operación**: x\[rd] $$=$$ CSRs\[csr];  CSRs\[csr] $$=$$ zimm
* **Tipo**: I

**Uso**

```
csrrwi rd, csr, zimm[4:0]
```

## div

Divide `x[rs1]` entre `x[rs2]`, redondeando hacia cero, tratando los valores como números de complemento a dos, y escribe el cociente en `x[rd]`.

* *Divide*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$÷\_s$$ x\[rs2]
* **Tipo**: R

**Uso**

```
div rd, rs1, rs2
```

## divu

Divide `x[rs1]` entre `x[rs2]`, redondeando hacia cero, tratando los valores como números sin signo, y escribe el cociente en `x[rd]`.

* *Divide, Unsigned*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$÷\_u$$ x\[rs2]
* **Tipo**: R

**Uso**

```
divu rd, rs1, rs2
```

## ebreak

Hace una petición del debugger levantando una excepción de `Breakpoint`.

* *Environment Breakpoint*
* **Operación**: RaiseException(Breakpoint)
* **Tipo**: I

**Uso**

```
ebreak
```

## ecall

Hace una petición del ambiente de ejecución levantando una excepción de `Environment Call`.

* *Environment Call*
* **Operación**: RaiseException(EnvironmentCall)
* **Tipo**: I

**Uso**

```
ecall
```

## fadd.s

Suma los números de punto flotante de precisión simple de los registros `f[rs1]` y `f[rs2]` y escribe la suma redondeada de precisión simple en `f[rd]`.

* *Floating-point Add, Single-Precision*
* **Operación**: f\[rd]$$=$$ f\[rs1] $$+$$ f\[rs2]
* **Tipo**: R

**Uso**

```
fadd.s rd, rs1, rs2
```

## fclass.s

Escribe en `x[rd]` una máscara que indica la clase del número de punto flotante de precisión simple en `f[rs1]`. Exactamente un bit en `x[rd]` es puesto en `1`, de acuerdo a la siguiente tabla:

| Bit en `x[rd]` | Significado                              |
| -------------- | ---------------------------------------- |
| 0              | `f[rs1]` es $$-∞$$                       |
| 1              | `f[rs1]` es un número negativo normal    |
| 2              | `f[rs1]` es un número negativo subnormal |
| 3              | `f[rs1]` es $$-0$$                       |
| 4              | `f[rs1]` es $$+0$$                       |
| 5              | `f[rs1]` es un número positivo subnormal |
| 6              | `f[rs1]` es un número positivo normal    |
| 7              | `f[rs1]` es $$+∞$$                       |
| 8              | `f[rs1]` es un $$NaN$$simple             |

* *Floating-point Classify, Single-Precision*
* **Operación**: x\[rd] = $$classify\_s$$(f\[rs1])
* **Tipo**: R

**Uso**

```
fclass.s rd, rs1, rs2
```

## fcvt.s.w

Convierte el entero de 32 bits de complemento a dos en `x[rs1]` en un número de punto flotante de precisión simple y lo escribe en `f[rd]`.

* *Floating-point Convert to Single from Word*
* **Operación**: f\[rd] $$=$$ f32$$\_{s32}$$ ( x\[rs1] )
* **Tipo**: R

**Uso**

```
fcvt.s.w rd, rs1, rs2
```

## fcvt.s.wu

Convierte el entero de 32 bits sin signo en `x[rs1]` en un número de punto flotante de precisión simple y lo escribe en `f[rd]`.

* *Floating-point Convert to Single from Unsigned Word*
* **Operación**: f\[rd] $$=$$ f32$$\_{u32}$$ ( x\[rs1] )
* **Tipo**: R

**Uso**

```
fcvt.s.wu rd, rs1, rs2
```

## fcvt.w\.s

Convierte el número de punto flotante de precisión simple en el registro `f[rs1]` en un entero de 32 bits de complemento a dos y escribe el resultado sign-extended en `x[rd]`.

* *Floating-point Convert to Word from Single*
* **Operación**: x\[rd] $$=$$ sext( s32 $$\_{f32}$$ ( f\[rs1] ) )
* **Tipo**: R

**Uso**

```
fcvt.w.s rd, rs1, rs2
```

## fcvt.wu.s

Convierte el número de punto flotante de precisión simple en el registro `f[rs1]` en un entero de 32 bits sin signo y escribe el resultado sign-extended en `x[rd]`.

* *Floating-point Convert to Unsigned Word from Single*
* **Operación**: x\[rd] $$=$$ sext( u32$$\_{f32}$$ ( f\[rs1] ) )
* **Tipo**: R

**Uso**

```
fcvt.wu.s rd, rs1, rs2
```

## fdiv.s

Divide el número de punto flotante de precisión simple en el registro `f[rs1]` entre `f[rs2]` y escribe el cociente redondeado de precisión simple en `f[rd]`.

* *Floating-point Divide, Single-Precision*
* **Operación**: f\[rd] $$=$$ f\[rs1] $$÷$$ f\[rs2]
* **Tipo**: R

**Uso**

```
fdiv.s rd, rs1, rs2
```

## fence

Vuelve los accesos previos a memoria e I/O en el conjunto `predecessor` observables a otros threads y dispositivos antes de que los accesos subsiguientes a memoria e I/O en el conjunto `successor` sean observables. Los bits 3, 2, 1 y 0 en estos conjuntos corresponden `device input`, `device output`,  `memory reads` y `memory writes`, respectivamente. La instrucción `fence r, rw` por ejemplo, ordena lecturas más antiguas con lecturas y escrituras más recientes, y se codifica con `pred = 0010` y `suc = 0011`. Si los argumentos son omitidos, se asume un `fence iorw, iorw` completo.

* *Fence Memory and I/O*
* **Operación**: Fence(pred, succ)
* **Tipo**: I

**Uso**

```
fence pred, succ
```

## feq.s

Escribe `1` en `x[rd]` si el número de punto flotante de precisión simple en `f[rs1]` es igual al número en `f[rs2]`, y `0` si no.

* *Floating-point Equals, Single-Precision*
* **Operación**: x\[rd] $$=$$ f\[rs1] $$==$$ f\[rs2]
* **Tipo**: R

**Uso**

```
feq.s rd, rs1, rs2
```

## fle.s

Escribe `1` en `x[rd]` si el número de punto flotante de precisión simple en `f[rs1]` es menor o igual que el número en `f[rs2]`, y `0` si no.

* *Floating-point Less Than or Equal, Single-Precision*
* **Operación**: x\[rd] $$=$$ f\[rs1] $$≤$$ f\[rs2]
* **Tipo**: R

**Uso**

```
fle.s rd, rs1, rs2
```

## flt.s

Escribe `1` en `x[rd]` si el número de punto flotante de precisión simple en `f[rs1]` es menor que el número en `f[rs2]`, y `0` si no.

* *Floating-point Less Than, Single-Precision*
* **Operación**: x\[rd] $$=$$ f\[rs1] $$<$$ f\[rs2]
* **Tipo**: R

**Uso**

```
flt.s rd, rs1, rs2
```

## flw

Carga un número de punto flotante de precisión simple de la dirección de memoria `x[rs1] + sign-extend(offset)` y lo escribe en `f[rd]`.&#x20;

Formas comprimidas: **`c.flwsp`**` ``rd, offset`;  **`c.flw`**` ``rd, offset(rs1)`.

* *Floating-point Load Word*
* **Operación**: f\[rd] $$=$$ M\[ x\[rs1] $$+$$ sext( offset ) ] \[31:0]
* **Tipo**: I

**Uso**

```
flw rd, offset(rs1)
```

## fmadd.s

Multiplica los números de punto flotante de precisión simple en `f[rs1]` y `f[rs2]`, suma el producto sin redondear al número de punto flotante de precisión simple en `f[rs3]`, y escribe el resultado redondeado de precisión simple en `f[rd]`.

* *Floating-point Fused Multiply-Add, Single-Precision*
* **Operación**: f\[rd] $$=$$ f\[rs1] $$×$$ f\[rs2] $$+$$ f\[rs3]
* **Tipo**: R4

**Uso**

```
fmadd.s rd, rs1, rs2, rs3
```

## fmax.s

Copia el mayor de los números de punto flotante de precisión simple de los registros `f[rs1]` y `f[rs2]` a `f[rd]`.

* *Floating-point Maximum, Single-Precision*
* **Operación**: f\[rd] $$=$$ $$max$$( f\[rs1], f\[rs2] )
* **Tipo**: R

**Uso**

```
fmax.s rd, rs1, rs2
```

## fmin.s

Copia el menor de los números de punto flotante de precisión simple de los registros `f[rs1]` y `f[rs2]` a `f[rd]`.

* *Floating-point Minimum, Single-Precision*
* **Operación**: f\[rd] $$=$$ $$min$$( f\[rs1], f\[rs2] )
* **Tipo**: R

**Uso**

```
fmin.s rd, rs1, rs2
```

## fmsub.s

Multiplica los números de punto flotante de precisión simple en `f[rs1]` y `f[rs2]`, resta el número de punto flotante de precisión simple en `f[rs3]` del producto sin redondear, y escribe el resultado redondeado de precisión simple en `f[rd]`.

* *Floating-point Fused Multiply-Subtract, Single-Precision*
* **Operación**: f\[rd] $$=$$ f\[rs1] $$×$$ f\[rs2] $$-$$ f\[rs3]
* **Tipo**: R4

**Uso**

```
fmsub.s rd, rs1, rs2
```

## fmul.s

Multiplica los números de punto flotante de precisión simple en los registros `f[rs1]` y `f[rs2]` y escribe el producto redondeado de precisión simple en `f[rd]`.

* *Floating-point Multiply, Single-Precision*
* **Operación**: f\[rd] $$=$$ f\[rs1] $$×$$ f\[rs2]
* **Tipo**: R

**Uso**

```
fmul.s rd, rs1, rs2
```

## fmv.w\.x

Copia el número de punto flotante de precisión simple en el registro `x[rs1]` a `f[rd]`.

* *Floating-point Move Word from Integer*
* **Operación**: f\[rd] $$=$$ x\[rs1]\[31:0]
* **Tipo**: R

**Uso**

```
fmv.w.x rd, rs1, rs2
```

## fmv.x.w

Copia el número de punto flotante de precisión simple en el registro `f[rs1]` a `x[rd]`, extendiendo en signo el resultado para `RV64F`.

* *Floating-point Move Word to Integer*
* **Operación**: x\[rd] $$=$$ sext( f\[rs1]\[31:0] )
* **Tipo**: R

**Uso**

```
fmv.x.w rd, rs1, rs2
```

## fnmadd.s

Multiplica los números de punto flotante de precisión simple en `f[rs1]` y `f[rs2]`, niega el resultado, suma el número de punto flotante de precisión simple en `f[rs3]` del producto sin redondear, y escribe el resultado redondeado de precisión simple en `f[rd]`.

* *Floating-point Fused Negative Multiply-Add, Single-Precision*
* **Operación**: f\[rd] $$=$$ $$∼$$ f\[rs1] $$×$$ f\[rs2] $$+$$ f\[rs3]
* **Tipo**: R4

**Uso**

```
fnmadd.s rd, rs1, rs2, rs3
```

## fnmsub.s

Multiplica los números de punto flotante de precisión simple en `f[rs1]` y `f[rs2]`, niega el resultado, resta el producto sin redondear al número de punto flotante de precisión simple en `f[rs3]`, y escribe el resultado redondeado de precisión simple en `f[rd]`.

* *Floating-point Fused Negative Multiply-Subtract, Single-Precision*
* **Operación**: f\[rd] = $$∼$$ f\[rs1] $$×$$ f\[rs2] $$-$$ f\[rs3]
* **Tipo**: R4

**Uso**

```
fnmsub.s rd, rs1, rs2, rs3
```

## fsgnj.s

Construye un nuevo número de punto flotante de precisión simple del exponente y significando de `f[rs1]` tomando el signo de `f[rs2]`, y lo escribe en `f[rd]`.

* *Floating-point Sign Inject, Single-Precision*
* **Operación**: f\[rd] $$=$$ { f\[rs2]\[31], f\[rs1]\[30:0] }
* **Tipo**: R

**Uso**

```
fsgnj.s rd, rs1, rs2
```

## fsgnjn.s

Construye un nuevo número de punto flotante de precisión simple del exponente y significando de `f[rs1]` tomando el signo opuesto de `f[rs2]`, y lo escribe en `f[rd]`.

* *Floating-point Sign Inject-Negate, Single-Precision*
* **Operación**: f\[rd] = { $$∼$$f\[rs2]\[31], f\[rs1]\[30:0] }
* **Tipo**: R

**Uso**

```
fsgnjn.s rd, rs1, rs2
```

## fsgnjx.s

Construye un nuevo número de punto flotante de precisión simple del exponente y significando de `f[rs1]` tomando el signo del `XOR` de los signos de `f[rs1]` y `f[rs2]`, y lo escribe en `f[rd]`.

* *Floating-point Sign Inject-XOR, Single-Precision*
* **Operación**: f\[rd] $$=$$ { f\[rs1]\[31] $$ˆ$$ f\[rs2]\[31],  f\[rs1]\[30:0] }
* **Tipo**: R

**Uso**

```
fsgnjx.s rd, rs1, rs2
```

## fsqrt.s

Calcula la raíz cuadrada del número de punto flotante de precisión doble en el registro `f[rs1]` y escribe el resultado redondeado de precisión simple en `f[rd]`.

* *Floating-point Square Root, Single-Precision*
* **Operación**: f\[rd] $$=$$  $$sqrt$${ f\[rs1] }
* **Tipo**: R

**Uso**

```
fsqrt.s rd, rs1, rs2
```

## fsub.s

Resta el número de punto flotante de precisión simple en el registro `f[rs2]` de `f[rs1]` y escribe la diferencia de precisión simple en `f[rd]`.

* *Floating-point Subtract, Single-Precision*
* **Operación**: f\[rd] $$=$$ f\[rs1] $$-$$ f\[rs2]
* **Tipo**: R

**Uso**

```
fsub.s rd, rs1, rs2
```

## fsw

Almacena el número de punto flotante de precisión simple del registro `f[rs2]` a memoria en la dirección `x[rs1] + sign-extend(offset)`.&#x20;

Formas comprimidas: **`c.fswsp`**  `rs2, offset`; **`c.fsw`**`rs2, offset(rs1)`.

* *Floating-point Store Word*
* **Operación**: M\[x\[rs1] $$+$$ sext(offset)] $$=$$ f\[rs2]\[31:0]
* **Tipo**: S

**Uso**

```
fsw rs2, offset(rs1)
```

## jal

Escribe la dirección de la siguiente instrucción `pc+4` en `x[rd]`, luego asigna al `pc` su valor actual más el `offset` extendido en signo. Si `rd` es omitido, se asume `x1`.&#x20;

Formas comprimidas: **`c.j`** `offset`; **`c.jal`** `offset`.

* *Jump and Link*
* **Operación**: x\[rd] $$=$$ pc $$+$$ 4; pc $$+=$$ sext(offset)
* **Tipo**: J

**Uso**

```
jal rd, offset
```

## jalr

Escribe `x[rs1] + sign-extend(offset)` al `pc`, enmascarando a cero el bit menos significativo de la dirección calculada, luego escribe el valor previo del `pc+4` en `x[rd]`. Si `rd` es omitido, se asume `x1`.&#x20;

Formas comprimidas: **`c.jr`** `rs1`; **`c.jalr`** `rs1`.

* *Jump and Link Register*
* **Operación**: t $$=$$ pc $$+$$ 4; pc $$=$$ (x\[rs1] $$+$$ sext(offset)) &  $$∼$$1; x\[rd] $$=$$ t
* **Tipo**: I

**Uso**

```
jalr rd, offset(rs1)
```

## lb

Carga un byte de memoria en la dirección `x[rs1] + sign-extend(offset)` y lo escribe en `x[rd]`, extendiendo en signo el resultado.

* *Load Byte*
* **Operación**: x\[rd] $$=$$ sext( M\[x\[rs1] $$+$$ sext(offset)]\[7:0] )
* **Tipo**: I

**Uso**

```
lb rd, offset(rs1)
```

## lbu

Carga un byte de memoria en la dirección `x[rs1] + sign-extend(offset)` y lo escribe en `x[rd]`, extendiendo con cero el resultado.

* *Load Byte, Unsigned*
* **Operación**: x\[rd] $$=$$ M\[x\[rs1] $$+$$ sext(offset)]\[7:0]
* **Tipo**: I

**Uso**

```
lbu rd, offset(rs1)
```

## lh

Carga dos bytes de memoria en la dirección `x[rs1] + sign-extend(offset)` y los escribe en `x[rd]`, extendiendo en signo el resultado.

* *Load Halfword*
* **Operación**: x\[rd] $$=$$ sext( M\[x\[rs1] $$+$$ sext(offset)]\[15:0] )
* **Tipo**: I

**Uso**

```
lh rd, offset(rs1)
```

## lhu

Carga dos bytes de memoria en la dirección `x[rs1] + sign-extend(offset)` y los escribe en `x[rd]`, extendiendo con cero el resultado.

* *Load Halfword, Unsigned*
* **Operación**: x\[rd] $$=$$ M\[x\[rs1] $$+$$ sext(offset)]\[15:0]
* **Tipo**: I

**Uso**

```
lhu rd, offset(rs1)
```

## lw

Carga cuatro bytes de memoria en la dirección `x[rs1] + sign-extend(offset)` y los escribe en `x[rd]`. Para `RV64I`, el resultado es extendido en signo.&#x20;

Formas comprimidas: **`c.lwsp`** `rd, offset`; **`c.lw`**` ``rd, offset(rs1)`

* *Load Word*
* **Operación**: x\[rd] $$=$$ sext( M\[x\[rs1] $$+$$ sext(offset)]\[31:0] )
* **Tipo**: I

**Uso**

```
lw rd, offset(rs1)
```

## lui

Escribe el `inmediato` de 20 bits extendido en signo, corrido a la izquierda por 12 bits, en `x[rd]`, volviendo cero los 12 bits más bajos.&#x20;

Formas comprimidas: **`c.lui`** `rd, imm`

* *Load Upper Immediate*
* **Operación**: x\[rd] $$=$$ sext(immediate\[31:12] $$<<$$ 12)
* **Tipo**: I

**Uso**

```
lui rd, immediate
```

## mul

Multiplica `x[rs1]` por `x[rs2]` y escribe el producto en `f[rd]`. Overflow aritmético ignorado.

* *Multiply*
* **Operación**: x\[rd] $$=$$ x\[rs1]$$×$$ x\[rs2]
* **Tipo**: R

**Uso**

```
mul rd, rs1, rs2
```

## mulh

Multiplica `x[rs1]` por `x[rs2]`, tratando los valores como números de complemento a dos, y escribe la mitad alta del producto a `f[rd]`.

* *Multiply High*
* **Operación**: x\[rd] = ( x\[rs1] $$\_s × \_s$$ x\[rs2] ) $$>>\_s$$ XLEN
* **Tipo**: R

**Uso**

```
mulh rd, rs1, rs2
```

## mulhsu

Multiplica `x[rs1]` por `x[rs2]`, tratando a `x[rs1]` como un número de complemento a dos, y a `x[rs2]` como un número sin signo, y escribe la mitad alta del producto a `f[rd]`.

* *Multiply High Signed-Unsigned*
* **Operación**: x\[rd] $$=$$ ( x\[rs1] $$\_s × \_u$$ x\[rs2] ) $$>>\_s$$  XLEN
* **Tipo**: R

**Uso**

```
mulhsu rd, rs1, rs2
```

## mulhu

Multiplica `x[rs1]` por `x[rs2]`, tratando los valores como números sin signo, y escribe la mitad alta del producto a `f[rd]`.

* *Multiply High Unsigned*
* **Operación**: x\[rd] $$=$$ ( x\[rs1] $$\_u ×\_u$$ x\[rs2] ) $$>>\_u$$ XLEN
* **Tipo**: R

**Uso**

```
mulhu rd, rs1, rs2
```

## or

Calcula el `OR` inclusivo a nivel de bits de los registros `x[rs1]` y `x[rs2]` y escribe el resultado en `x[rd]`.&#x20;

Formas comprimidas: **`c.or`**`rd, rs2`

* *OR*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$|$$ x\[rs2]
* **Tipo**: R

**Uso**

```
or rd, rs1, rs2
```

## ori

Calcula el `OR` inclusivo a nivel de bits del `inmediato sign-extended` y el registro `x[rs1]` y escribe el resultado en `x[rd]`.

* *OR Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$|$$ sext(immediate)
* **Tipo**: R

**Uso**

```
ori rd, rs1, immediate
```

## rem

Divide$\texttt{`x[rs1]` entre `x[rs2]`, redondeando hacia cero, tratando los valores como números de complemento a dos, y escribe el residuo en `f[rd]`.

* *Remainder*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$%\_s$$ x\[rs2]
* **Tipo**: R

**Uso**

```
rem rd, rs1, rs2
```

## remu

Divide `x[rs1]` entre `x[rs2]`, redondeando hacia cero, tratando los valores como números sin signo, y escribe el residuo en `f[rd]`.

* *Remainder, Unsigned*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$%\_u$$ x\[rs2]
* **Tipo**: R

**Uso**

```
remu rd, rs1, rs2
```

## sb

Almacena el byte menos significativo del registro `x[rs2]` a memoria en la dirección `x[rs1] + sign-extend(offset)`.

* *Store Byte*
* **Operación**: M\[x\[rs1] $$+$$ sext(offset)] $$=$$ x\[rs2]\[7:0]
* **Tipo**: S

**Uso**

```
sb rs2, offset(rs1)
```

## sh

Almacena los dos bytes menos significativos del registro `x[rs2]` a memoria en la dirección `x[rs1] + sign-extend(offset)`.

* *Store Halfword*
* **Operación**: M\[x\[rs1] $$+$$ sext(offset)] $$=$$ x\[rs2]\[15:0]
* **Tipo**: S

**Uso**

```
sh rs2, offset(rs1)
```

## sll

Corre el registro `x[rs1]` a la izquierda por `x[rs2]` posiciones de bits. Los bits liberados son reemplazados por ceros, y el resultado es escrito en `x[rd]`. Los cinco bits menos significativos de `x[rs2]` (o seis bits para `RV64I`) forman la cantidad a correr; los bits altos son ignorados.

* *Shift Left Logical*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<<$$ x\[rs2]
* **Tipo**: R

**Uso**

```
sll rd, rs1, rs2
```

## slli

Corre el registro `x[rs1]` a la izquierda por `shamt` posiciones de bits. Los bits liberados son reemplazados por ceros, y el resultado es escrito en `x[rd]`. Para `RV32I`, la instrucción solo es legal cuando `shamt[5]=0`.&#x20;

Forma comprimida: **`c.slli`** `rd, shamt`

* *Shift Left Logical Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<<$$ shamt
* **Tipo**: I

**Uso**

```
slli rd, rs1, shamt
```

## slt

Compara `x[rs1]` con `x[rs2]` como números de complemento a dos, y escribe  en $\texttt{`x[rd]` si `x[rs1]` es menor, ó `0` si no.

* *Set if Less Than*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<\_s$$ x\[rs2]
* **Tipo**: R

**Uso**

```
slt rd, rs1, rs2
```

## slti

Compara `x[rs1]` con el `immediate sign-extended` como números de complemento a dos, y escribe `1` en `x[rd]` si `x[rs1]` es menor, ó `0` si no.

* *Set if Less Than Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<\_s$$ sext(immediate)
* **Tipo**: I

**Uso**

```
slti rd, rs1, immediate
```

## sltiu

Compara `x[rs1]` con el `immediate sign-extended` como números sin signo, y escribe `1` en `x[rd]` si `x[rs1]` es menor, ó `0` si no.

* *Set if Less Than Immediate, Unsigned*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<\_u$$ sext(immediate)
* **Tipo**: I

**Uso**

```
sltiu rd, rs1, immediate
```

## sltu

Compara `x[rs1]` con `x[rs2]` como números sin signo, y escribe `1` en `x[rd]` si `x[rs1]` es menor, ó `0` si no.

* *Set if Less Than, Unsigned*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$<\_u$$ x\[rs2]
* **Tipo**: R

**Uso**

```
sltu rd, rs1, rs2
```

## sra

Corre el registro `x[rs1]` a la derecha por`x[rs2]` posiciones de bits. Los bits liberados son reemplazados por copias del bit más significativo de `x[rs1]`, y el resultado es escrito en `x[rd]`. Los cinco bits menos significativos de `x[rs2]` (o seis bits para `RV64I`) forman la cantidad a correr; los bits altos son ignorados.

* *Shift Right Arithmetic*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$>>\_s$$ x\[rs2]
* **Tipo**: R

**Uso**

```
sra rd, rs1, rs2
```

## srai

Corre el registro `x[rs1]` a la derecha por `shamt` posiciones de bits. Los bits liberados son reemplazados por copias del bit más significativo de `x[rs1]`, y el resultado es escrito en `x[rd]`. Para `RV32I`, la instrucción solo es legal cuando `shamt[5]=0`.&#x20;

Forma comprimida: **`c.srai`**`rd, shamt`.

* *Shift Right Arithmetic Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$>>\_s$$ shamt
* **Tipo**: I

**Uso**

```
srai rd, rs1, shamt
```

## srl

Corre el registro `x[rs1]` a la derecha por `x[rs2]` posiciones de bits. Los bits liberados son reemplazados por ceros ceros, y el resultado es escrito en `x[rd]`. Los cinco bits menos significativos de `x[rs2]` (o seis bits para `RV64I`) forman la cantidad a correr; los bits altos son ignorados.

* *Shift Right Logical*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$>>\_u$$ x\[rs2]
* **Tipo**: R

**Uso**

```
srl rd, rs1, rs2
```

## srli

Corre el registro `x[rs1]` a la derecha por `shamt` posiciones de bits. Los bits liberados son reemplazados por ceros, y el resultado es escrito en `x[rd]`. Para `RV32I`, la instrucción solo es legal cuando `shamt[5]=0`.&#x20;

Forma comprimida: **`c.srli`** `rd, shamt`.

* *Shift Right Logical Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$>>\_u$$ shamt
* **Tipo**: I

**Uso**

```
srli rd, rs1, shamt
```

## sub

Resta el registro `x[rs2]` del registro `x[rs1]`, trunca el resultado a 32 bits, y escribe el resultado de 32 bits, sign-extended, en `x[rd]`. Overflow aritmético ignorado.&#x20;

Forma comprimida: **`c.sub`** `rd, rs`.

* *Subtract*
* **Operación**: $\texttt{x\[rd] $$=$$ x\[rs1] $$-$$ x\[rs2]
* **Tipo**: R

**Uso**

```
sub rd, rs1, rs2
```

## sw

Almacena los cuatro bytes menos significativos del registro `x[rs2]` a memoria en la dirección `x[rs1] + sign-extend(offset)`.&#x20;

Formas comprimidas: **`c.swsp`** `rs2, offset`; **`c.sw`** `rs2, offset(rs1)`.

* *Store Word*
* **Operación**: M\[x\[rs1] $$+$$ sext(offset)] $$=$$ x\[rs2]\[31:0]
* **Tipo**: S

**Uso**

```
sw rs2, offset(rs1)
```

## xor

Calcula el `OR` exclusivo a nivel de bits de los registros `x[rs1]` y `x[rs2]` y escribe el resultado en `x[rd]`.&#x20;

Forma comprimida: **`c.xor`** `rd, rs2`

* *Exclusive-OR*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$ˆ$$ x\[rs2]
* **Tipo**: R

**Uso**

```
xor rd, rs1, rs2
```

## xori

Calcula el `OR` exclusivo a nivel de bits del `immediate sign-extended` y el registro `x[rs1]` y escribe el resultado en `x[rd]`.

* *Exclusive-OR Immediate*
* **Operación**: x\[rd] $$=$$ x\[rs1] $$ˆ$$ sext(immediate)
* **Tipo**: R

**Uso**

```
xori rd, rs1, immediate
```
