}
 
 // encodeR encodes an R-type RISC-V instruction.
-func encodeR(as obj.As, rs1, rs2, rd, funct3 uint32) uint32 {
+func encodeR(as obj.As, rs1, rs2, rd, funct3, funct7 uint32) uint32 {
        enc := encode(as)
        if enc == nil {
                panic("encodeR: could not encode instruction")
        if enc.rs2 != 0 && rs2 != 0 {
                panic("encodeR: instruction uses rs2, but rs2 was nonzero")
        }
-       return enc.funct7<<25 | enc.rs2<<20 | rs2<<20 | rs1<<15 | enc.funct3<<12 | funct3<<12 | rd<<7 | enc.opcode
+       return funct7<<25 | enc.funct7<<25 | enc.rs2<<20 | rs2<<20 | rs1<<15 | enc.funct3<<12 | funct3<<12 | rd<<7 | enc.opcode
 }
 
 func encodeRIII(ins *instruction) uint32 {
-       return encodeR(ins.as, regI(ins.rs1), regI(ins.rs2), regI(ins.rd), ins.funct3)
+       return encodeR(ins.as, regI(ins.rs1), regI(ins.rs2), regI(ins.rd), ins.funct3, ins.funct7)
 }
 
 func encodeRFFF(ins *instruction) uint32 {
-       return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regF(ins.rd), ins.funct3)
+       return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regF(ins.rd), ins.funct3, ins.funct7)
 }
 
 func encodeRFFI(ins *instruction) uint32 {
-       return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regI(ins.rd), ins.funct3)
+       return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regI(ins.rd), ins.funct3, ins.funct7)
 }
 
 func encodeRFI(ins *instruction) uint32 {
-       return encodeR(ins.as, regF(ins.rs2), 0, regI(ins.rd), ins.funct3)
+       return encodeR(ins.as, regF(ins.rs2), 0, regI(ins.rd), ins.funct3, ins.funct7)
 }
 
 func encodeRIF(ins *instruction) uint32 {
-       return encodeR(ins.as, regI(ins.rs2), 0, regF(ins.rd), ins.funct3)
+       return encodeR(ins.as, regI(ins.rs2), 0, regF(ins.rd), ins.funct3, ins.funct7)
 }
 
 func encodeRFF(ins *instruction) uint32 {
-       return encodeR(ins.as, regF(ins.rs2), 0, regF(ins.rd), ins.funct3)
+       return encodeR(ins.as, regF(ins.rs2), 0, regF(ins.rd), ins.funct3, ins.funct7)
 }
 
 // encodeI encodes an I-type RISC-V instruction.
        AREMW & obj.AMask:   rIIIEncoding,
        AREMUW & obj.AMask:  rIIIEncoding,
 
+       // 8.2: Load-Reserved/Store-Conditional
+       ALRW & obj.AMask: rIIIEncoding,
+       ALRD & obj.AMask: rIIIEncoding,
+       ASCW & obj.AMask: rIIIEncoding,
+       ASCD & obj.AMask: rIIIEncoding,
+
        // 10.1: Base Counters and Timers
        ARDCYCLE & obj.AMask:   iIEncoding,
        ARDTIME & obj.AMask:    iIEncoding,
        rs2    uint32 // Source register 2
        imm    int64  // Immediate
        funct3 uint32 // Function 3
+       funct7 uint32 // Function 7
 }
 
 func (ins *instruction) encode() (uint32, error) {
                ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
                ins.imm = p.To.Offset
 
+       case ALRW, ALRD:
+               // Set aq to use acquire access ordering, which matches Go's memory requirements.
+               ins.funct7 = 2
+               ins.rs1, ins.rs2 = uint32(p.From.Reg), REG_ZERO
+
+       case ASCW, ASCD:
+               // Set aq to use acquire access ordering, which matches Go's memory requirements.
+               ins.funct7 = 2
+               ins.rd, ins.rs1, ins.rs2 = uint32(p.RegTo2), uint32(p.To.Reg), uint32(p.From.Reg)
+
        case AECALL, AEBREAK, ARDCYCLE, ARDTIME, ARDINSTRET:
                insEnc := encode(p.As)
                if p.To.Type == obj.TYPE_NONE {