summaryrefslogtreecommitdiff
path: root/risc-v/riscv_regfp.sail
blob: 602f0becae28f9014260eb6c0bcf6cd6b28546ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
let (vector <0, 32, inc, string >) GPRstr =
  [ "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10",
  "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20",
  "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"
  ]

let CIA_fp = RFull("CIA")
let NIA_fp = RFull("NIA")

function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis (instr) = {
  iR := [|| ||];
  oR := [|| ||];
  aR := [|| ||];
  ik := IK_simple;
  Nias := [|| NIAFP_successor ||];
  Dia := DIAFP_none;

  switch instr {
     case (EBREAK) -> ()
     case (UTYPE ( imm, rd, op)) -> {
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (JAL ( imm, rd)) -> {
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
            let (bit[64]) offset = EXTS(imm) in
            Nias := [|| NIAFP_concrete_address (PC + offset) ||]
     }
     case (JALR ( imm, rs, rd)) -> {
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
            let (bit[64]) offset = EXTS(imm) in
            Nias := [|| NIAFP_register (RFull(GPRstr[rs])) ||];
     }
     case (BTYPE ( imm, rs2, rs1, op)) -> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            ik := IK_cond_branch;
            let (bit[64]) offset = EXTS(imm) in
            Nias := NIAFP_concrete_address(PC + offset) :: Nias;
     }
     case (ITYPE ( imm, rs, rd, op)) -> {
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (SHIFTIOP ( imm, rs, rd, op)) -> {
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (RTYPE ( rs2, rs1, rd, op)) -> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (LOAD ( imm, rs, rd, unsign, width, aq, rl)) -> { (* XXX "unsigned" causes name conflict in lem shallow embedding... *)
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
            aR := iR;
            ik :=
              switch (aq, rl) {
                case (false, false) -> IK_mem_read (Read_plain)
                case (true,  false) -> IK_mem_read (Read_RISCV_acquire)
                case (false, true)  -> exit "not implemented"
                case (true,  true)  -> IK_mem_read (Read_RISCV_strong_acquire)
              };
     }
     case (STORE( imm, rs2, rs1, width, aq, rl)) -> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR;
            ik :=
              switch (aq, rl) {
                case (false, false) -> IK_mem_write (Write_plain)
                case (true,  false) -> exit "not implemented"
                case (false, true)  -> IK_mem_write (Write_RISCV_release)
                case (true,  true)  -> IK_mem_write (Write_RISCV_strong_release)
              };
     }
     case (ADDIW ( imm, rs, rd)) -> {
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (SHIFTW ( imm, rs, rd, op)) -> {
            if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     } 
     case (RTYPEW ( rs2, rs1, rd, op))-> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
     }
     case (FENCE(pred, succ)) -> {
            ik :=
              switch(pred, succ) {
                case (0b0011, 0b0011) -> IK_barrier (Barrier_RISCV_rw_rw)
                case (0b0010, 0b0011) -> IK_barrier (Barrier_RISCV_r_rw)
                case (0b0011, 0b0001) -> IK_barrier (Barrier_RISCV_rw_w)
                case (0b0001, 0b0001) -> IK_barrier (Barrier_RISCV_w_w)
                case _ -> exit "not implemented"
              };
     }
     case (FENCEI) -> {
            ik := IK_barrier (Barrier_RISCV_i);
     }
     case (LOADRES ( aq, rl, rs1, width, rd)) -> {
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;
            aR := iR;
            ik := switch (aq, rl) {
              case (false, false) -> IK_mem_read (Read_RISCV_reserved)
              case (true,  false) -> IK_mem_read (Read_RISCV_reserved_acquire)
              case (false, true)  -> exit "not implemented"
              case (true,  true)  -> IK_mem_read (Read_RISCV_reserved_strong_acquire)
            };
     }
     case (STORECON( aq, rl, rs2, rs1, width, rd)) -> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;

            ik := switch (aq, rl) {
              case (false, false) -> IK_mem_write (Write_RISCV_conditional)
              case (false, true)  -> IK_mem_write (Write_RISCV_conditional_release)
              case (true,  _)     -> exit "not implemented"
            };
     }
     case (AMO( op, aq, rl, rs2, rs1, width, rd)) -> {
            if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR;
            if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR;
            if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR;
            if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR;

            ik := switch (aq, rl) {
              case (false, false) -> IK_mem_rmw (Read_RISCV_reserved, Write_RISCV_conditional)
              case (false, true)  -> IK_mem_rmw (Read_RISCV_reserved, Write_RISCV_conditional_release)
              case (true,  false) -> IK_mem_rmw (Read_RISCV_reserved_acquire,
                                                                      Write_RISCV_conditional)
              case (true,  true)  -> IK_mem_rmw (Read_RISCV_reserved_strong_acquire,
                                                                      Write_RISCV_conditional_strong_release)
            };
     }
  };
  (iR,oR,aR,Nias,Dia,ik)
}