summaryrefslogtreecommitdiff
path: root/aarch64_small/mono-splices/_wMem.sail
blob: 8e37ca649739d0143441da29f50bba4af150146f (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
function _wMem(write_buffer, desc, size, acctype, exclusive, value) = {
  let s = write_buffer.size;
  if s == 0 then {
    struct { acctype = acctype,
      exclusive = exclusive,
      address = (desc.paddress).physicaladdress,
      value = ZeroExtend(value),
      size = size
    }
  } else {
    assert(write_buffer.acctype == acctype);
    assert(write_buffer.exclusive == exclusive);
    assert((write_buffer.address + s) : bits(64) == (desc.paddress).physicaladdress);
  assert((s * 8) + ('N * 8) <= 128);
    value1 : bits(128) = sail_shiftleft(ZeroExtend(value), s * 8);
    value1[((s * 8) - 1) .. 0] = (write_buffer.value)[((s * 8) - 1) .. 0];
    { write_buffer with
      value = value1,
      size = s + size
    }
  }
}

val flush_write_buffer2 : forall 'n, 'n in {1,2,4,8,16}. (write_buffer_type, int('n)) -> unit effect {escape,wmv}

function flush_write_buffer2 (write_buffer, s) ={
  match write_buffer.acctype {
    AccType_NORMAL   => wMem_Val_NORMAL (write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    AccType_STREAM   => wMem_Val_NORMAL (write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    AccType_UNPRIV   => wMem_Val_NORMAL (write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    AccType_ORDERED  => wMem_Val_ORDERED (write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    _  => not_implemented("unrecognised memory access")
  };
}

function flush_write_buffer(write_buffer) = {
  assert(write_buffer.exclusive == false);
  let s : range(0,16) = write_buffer.size;
  assert (s == 1 | s == 2 | s == 4 | s == 8 | s == 16);
  flush_write_buffer2(write_buffer, s);
}

val flush_write_buffer_exclusive2 : forall 'n, 'n in {1,2,4,8,16}. (write_buffer_type, int('n)) -> bool effect {escape, wmv}
function flush_write_buffer_exclusive2(write_buffer, s) = {
  match write_buffer.acctype {
    AccType_ATOMIC   => wMem_Val_ATOMIC(write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    AccType_ORDERED  => wMem_Val_ATOMIC_ORDERED(write_buffer.address, s, (write_buffer.value)[((s * 8) - 1) .. 0]),
    _  => { not_implemented("unrecognised memory access"); false; }
  };
}

function flush_write_buffer_exclusive(write_buffer) = {
  assert(write_buffer.exclusive);
  let s = write_buffer.size;
  assert (s == 1 | s == 2 | s == 4 | s == 8 | s == 16);
  flush_write_buffer_exclusive2(write_buffer, s);
}