@@ -487,85 +487,186 @@ def execute(self, model: Model):
487487class InstructionLR (InstructionAMOType ):
488488 """ Load reserved """
489489 def execute (self , model : Model ):
490- # TODO: implement
491- pass
490+ # Perform a normal load
491+ data = model .state .memory .lw (model .state .intreg [self .rs1 ].unsigned ())
492+ model .state .intreg [self .rd ] = data
493+ # Perform correct lock or release actions
494+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
495+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
492496
493497
494498@isa ("sc" , RV32A , opcode = 0b0101111 , funct5 = 0b00011 , funct3 = 0b010 )
495499class InstructionSC (InstructionAMOType ):
496500 """ Store conditional """
497501 def execute (self , model : Model ):
498- # TODO: implement
499- pass
502+ # Check if this address is reserved
503+ if model .state .atomic_reserved (model .state .intreg [self .rs1 ]):
504+ model .state .memory .sw (
505+ model .state .intreg [self .rs1 ].unsigned (),
506+ model .state .intreg [self .rs2 ]
507+ )
508+ model .state .intreg [self .rd ] = 0
509+ else :
510+ model .state .intreg [self .rd ] = 1
511+ # Perform correct lock or release actions
512+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
513+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
500514
501515
502516@isa ("amoadd" , RV32A , opcode = 0b0101111 , funct5 = 0b00000 , funct3 = 0b010 )
503517class InstructionAMOADD (InstructionAMOType ):
504- """ Atomic swap operation """
518+ """ Atomic add operation """
505519 def execute (self , model : Model ):
506- # TODO: implement
507- pass
520+ # This models a single HART with 1 stage pipeline, so will always succeed
521+ model .state .intreg [self .rd ] = model .state .memory .lw (
522+ model .state .intreg [self .rs1 ].unsigned ()
523+ )
524+ model .state .memory .sw (
525+ model .state .intreg [self .rs1 ].unsigned (),
526+ (model .state .intreg [self .rs2 ] + model .state .intreg [self .rd ])
527+ )
528+ # Perform correct lock or release actions
529+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
530+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
508531
509532
510533@isa ("amoxor" , RV32A , opcode = 0b0101111 , funct5 = 0b00100 , funct3 = 0b010 )
511534class InstructionAMOXOR (InstructionAMOType ):
512- """ Atomic swap operation """
535+ """ Atomic XOR operation """
513536 def execute (self , model : Model ):
514- # TODO: implement
515- pass
537+ # This models a single HART with 1 stage pipeline, so will always succeed
538+ model .state .intreg [self .rd ] = model .state .memory .lw (
539+ model .state .intreg [self .rs1 ].unsigned ()
540+ )
541+ model .state .memory .sw (
542+ model .state .intreg [self .rs1 ].unsigned (),
543+ (model .state .intreg [self .rs2 ] ^ model .state .intreg [self .rd ])
544+ )
545+ # Perform correct lock or release actions
546+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
547+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
516548
517549
518550@isa ("amoor" , RV32A , opcode = 0b0101111 , funct5 = 0b01000 , funct3 = 0b010 )
519551class InstructionAMOOR (InstructionAMOType ):
520- """ Atomic swap operation """
552+ """ Atomic OR operation """
521553 def execute (self , model : Model ):
522- # TODO: implement
523- pass
554+ # This models a single HART with 1 stage pipeline, so will always succeed
555+ model .state .intreg [self .rd ] = model .state .memory .lw (
556+ model .state .intreg [self .rs1 ].unsigned ()
557+ )
558+ model .state .memory .sw (
559+ model .state .intreg [self .rs1 ].unsigned (),
560+ (model .state .intreg [self .rs2 ] | model .state .intreg [self .rd ])
561+ )
562+ # Perform correct lock or release actions
563+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
564+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
524565
525566
526567@isa ("amoand" , RV32A , opcode = 0b0101111 , funct5 = 0b01100 , funct3 = 0b010 )
527568class InstructionAMOAND (InstructionAMOType ):
528- """ Atomic swap operation """
569+ """ Atomic AND operation """
529570 def execute (self , model : Model ):
530- # TODO: implement
531- pass
571+ # This models a single HART with 1 stage pipeline, so will always succeed
572+ model .state .intreg [self .rd ] = model .state .memory .lw (
573+ model .state .intreg [self .rs1 ].unsigned ()
574+ )
575+ model .state .memory .sw (
576+ model .state .intreg [self .rs1 ].unsigned (),
577+ (model .state .intreg [self .rs2 ] & model .state .intreg [self .rd ])
578+ )
579+ # Perform correct lock or release actions
580+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
581+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
532582
533583
534584@isa ("amomin" , RV32A , opcode = 0b0101111 , funct5 = 0b10000 , funct3 = 0b010 )
535585class InstructionAMOMIN (InstructionAMOType ):
536- """ Atomic swap operation """
586+ """ Atomic minimum operation """
537587 def execute (self , model : Model ):
538- # TODO: implement
539- pass
588+ # This models a single HART with 1 stage pipeline, so will always succeed
589+ model .state .intreg [self .rd ] = model .state .memory .lw (
590+ model .state .intreg [self .rs1 ].unsigned ()
591+ )
592+ model .state .memory .sw (
593+ model .state .intreg [self .rs1 ].unsigned (),
594+ min (model .state .intreg [self .rs2 ], model .state .intreg [self .rd ])
595+ )
596+ # Perform correct lock or release actions
597+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
598+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
540599
541600
542601@isa ("amomax" , RV32A , opcode = 0b0101111 , funct5 = 0b10100 , funct3 = 0b010 )
543602class InstructionAMOMAX (InstructionAMOType ):
544- """ Atomic swap operation """
603+ """ Atomic maximum operation """
545604 def execute (self , model : Model ):
546- # TODO: implement
547- pass
605+ # This models a single HART with 1 stage pipeline, so will always succeed
606+ model .state .intreg [self .rd ] = model .state .memory .lw (
607+ model .state .intreg [self .rs1 ].unsigned ()
608+ )
609+ model .state .memory .sw (
610+ model .state .intreg [self .rs1 ].unsigned (),
611+ max (model .state .intreg [self .rs2 ], model .state .intreg [self .rd ])
612+ )
613+ # Perform correct lock or release actions
614+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
615+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
548616
549617
550618@isa ("amominu" , RV32A , opcode = 0b0101111 , funct5 = 0b11000 , funct3 = 0b010 )
551619class InstructionAMOMINU (InstructionAMOType ):
552- """ Atomic swap operation """
553- def execute (self , model : Model ):
554- # TODO: implement
555- pass
620+ """ Atomic unsigned minimum operation """
621+ def execute (self , model : Model ):
622+ # This models a single HART with 1 stage pipeline, so will always succeed
623+ model .state .intreg [self .rd ] = model .state .memory .lw (
624+ model .state .intreg [self .rs1 ].unsigned ()
625+ )
626+ model .state .memory .sw (
627+ model .state .intreg [self .rs1 ].unsigned (),
628+ min (
629+ model .state .intreg [self .rs2 ].unsigned (),
630+ model .state .intreg [self .rd ].unsigned ()
631+ )
632+ )
633+ # Perform correct lock or release actions
634+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
635+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
556636
557637
558638@isa ("amomaxu" , RV32A , opcode = 0b0101111 , funct5 = 0b11100 , funct3 = 0b010 )
559639class InstructionAMOMAXU (InstructionAMOType ):
560- """ Atomic swap operation """
561- def execute (self , model : Model ):
562- # TODO: implement
563- pass
640+ """ Atomic unsigned maximum operation """
641+ def execute (self , model : Model ):
642+ # This models a single HART with 1 stage pipeline, so will always succeed
643+ model .state .intreg [self .rd ] = model .state .memory .lw (
644+ model .state .intreg [self .rs1 ].unsigned ()
645+ )
646+ model .state .memory .sw (
647+ model .state .intreg [self .rs1 ].unsigned (),
648+ max (
649+ model .state .intreg [self .rs2 ].unsigned (),
650+ model .state .intreg [self .rd ].unsigned ()
651+ )
652+ )
653+ # Perform correct lock or release actions
654+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
655+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
564656
565657
566658@isa ("amoswap" , RV32A , opcode = 0b0101111 , funct5 = 0b00001 , funct3 = 0b010 )
567659class InstructionAMOSWAP (InstructionAMOType ):
568660 """ Atomic swap operation """
569661 def execute (self , model : Model ):
570- # TODO: implement
571- pass
662+ # This models a single HART with 1 stage pipeline, so will always succeed
663+ model .state .intreg [self .rd ] = model .state .memory .lw (
664+ model .state .intreg [self .rs1 ].unsigned ()
665+ )
666+ model .state .memory .sw (
667+ model .state .intreg [self .rs1 ].unsigned (),
668+ model .state .intreg [self .rs2 ]
669+ )
670+ # Perform correct lock or release actions
671+ if self .rl : model .state .atomic_release (model .state .intreg [self .rs1 ])
672+ elif self .aq : model .state .atomic_acquire (model .state .intreg [self .rs1 ])
0 commit comments