OK, I think this works:

```
(defun $fsqrt.s (rd rs1)
(fmuldiv #x2C 'x0 rs1 7 rd #x53))
```

It uses the existing **fmuldiv** routine that is set up to handle instructions with these bit fields.

#x2C is just bits 31 to 25 in your definition, but in hexadecimal.

#x53 is just bits 6 to 0 in hexadecimal.

**rm** is the rounding mode. 7 seems to be a default choice.

**rd** and **rs1** are the destination and source registers, and **'x0** is just zero.

Here’s a test, based on my earlier example, but taking the square root at the end and putting the result back in the first element of the list:

```
(defcode square-root (x)
($li 'a2 1)
($fcvt.s.w 'fa1 'a2)
($mv 'a2 'a0)
repeat
($beqz 'a0 finished)
($ld 'a1 0 '(a0))
($flw 'fa0 8 '(a1))
($fmul.s 'fa1 'fa0 'fa1)
($ld 'a0 8 '(a0))
($j repeat)
finished
($ld 'a1 0 '(a2))
($fsqrt.s 'a1 'a1)
($fsw 'fa1 8 '(a1))
($ret))
```

Testing it:

```
> (defvar b '(23.45))
b
> (square-root b)
0
> b
(4.84252)
```

Update: I’ve renamed the routine square-root to avoid a clash with the built-in function.