Changeset 740 for Deliverables/D2.2/8051/src/common
- Timestamp:
- Apr 4, 2011, 5:18:15 PM (10 years ago)
- Location:
- Deliverables/D2.2/8051/src/common
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
Deliverables/D2.2/8051/src/common/intValue.ml
r630 r740 79 79 80 80 (** [break i n] cuts [i] in [n] parts. In the resulting list, the first 81 element is the high bits, and the last is the low bits. *) 81 element is the low bits, and the last is the high bits (little endian 82 representation). *) 82 83 val break : t -> int -> t list 83 84 (** [merge l] creates the integer where the first element of [l] is its 84 high bits, etc, and the last element of [l] is its low bits. *) 85 low bits, etc, and the last element of [l] is its high bits (little endian 86 representation). *) 85 87 val merge : t list -> t 86 88 … … 242 244 243 245 (* [break i n] cuts [i] in [n] parts. In the resulting list, the first element 244 is the high bits, and the last is the low bits. *) 246 is the low bits, and the last is the high bits (little endian 247 representation). *) 245 248 let break a n = 246 249 let chunk_size = size / n in … … 252 255 aux ((cast chunk) :: acc) next (i-1) 253 256 in 254 aux [] (cast a) n 255 256 (* [merge l] creates the integer where the first element of [l] is its high 257 bits, etc, and the last element of [l] is its low bits. *) 257 List.rev (aux [] (cast a) n) 258 259 (* [merge l] creates the integer where the first element of [l] is its low 260 bits, etc, and the last element of [l] is its high bits (little endian 261 representation). *) 258 262 let merge = function 259 263 | [] -> zero 260 264 | al -> 261 let al = List.rev al in262 265 let nb_chunks = List.length al in 263 266 let chunk_size = size / nb_chunks in -
Deliverables/D2.2/8051/src/common/memory.ml
r619 r740 4 4 following the memory model of the CompCert compiler. *) 5 5 6 open IntValue 6 (** In the module, every size is expressed in bytes. *) 7 7 8 8 … … 11 11 12 12 13 (* Memory quantities are the size and the type of what can be loaded 14 and stored in memory *) 15 16 type memory_q = 17 | MQ_int8signed | MQ_int8unsigned | MQ_int16signed | MQ_int16unsigned 18 | MQ_int32 | MQ_float32 | MQ_float64 | MQ_pointer | MQ_chunk 19 20 let string_of_memory_q = function 21 | MQ_int8signed -> "int8s" 22 | MQ_int8unsigned -> "int8u" 23 | MQ_int16signed -> "int16s" 24 | MQ_int16unsigned -> "int16u" 25 | MQ_int32 -> "int32" 26 | MQ_float32 -> "float" 27 | MQ_float64 -> "float64" 28 | MQ_pointer -> "ptr" 29 | MQ_chunk -> "chunk" 30 31 let mq_of_data = function 32 | AST.Data_reserve _ -> assert false (* Should not be called on this *) 33 | AST.Data_int8 _ -> MQ_int8signed 34 | AST.Data_int16 _ -> MQ_int16signed 35 | AST.Data_int32 _ -> MQ_int32 36 | AST.Data_float32 _ -> MQ_float32 37 | AST.Data_float64 _ -> MQ_float64 38 39 let type_of_memory_q = function 40 | MQ_int8signed | MQ_int8unsigned | MQ_int16signed | MQ_int16unsigned 41 | MQ_int32 -> AST.Sig_int 42 | MQ_float32 | MQ_float64 -> AST.Sig_float 43 | MQ_pointer -> AST.Sig_ptr 44 | MQ_chunk -> error "Trying to get the type of a pointer chunk." 13 (** Memory quantities is the size and type of what can be loaded or stored in 14 memory. *) 15 16 type quantity = 17 | QInt of int (* Sized integer *) 18 | QPtr (* Pointer *) 19 20 let string_of_quantity = function 21 | QInt i -> string_of_int i 22 | QPtr -> "ptr" 23 24 25 let size_of_data = function 26 | AST.Data_reserve n -> n 27 | AST.Data_int8 _ -> 1 28 | AST.Data_int16 _ -> 2 29 | AST.Data_int32 _ -> 4 30 | AST.Data_float32 _ -> 4 31 | AST.Data_float64 _ -> 8 45 32 46 33 … … 61 48 sig 62 49 63 val mq_of_ptr : memory_q64 50 val int_size : int 65 51 val ptr_size : int 66 52 val alignment : int option 53 54 val size_of_quantity : quantity -> int 67 55 68 56 module Value : Value.S … … 79 67 val empty : 'fun_def memory 80 68 81 (** [alloc mem size] allocates a block of [size] size (in bytes) in the memory82 [mem]. It returns the new memory and a pointer to the beginning of the69 (** [alloc mem size] allocates a block of [size] bytes in the memory [mem]. It 70 returns the new memory and the address of the beginning of the newly 83 71 allocated area. *) 84 val alloc : 'fun_def memory -> int -> 'fun_def memory * Value. t72 val alloc : 'fun_def memory -> int -> 'fun_def memory * Value.address 85 73 86 74 (* Memory free *) 87 75 88 val free : 'fun_def memory -> Value. t-> 'fun_def memory76 val free : 'fun_def memory -> Value.address -> 'fun_def memory 89 77 90 78 (* Memory load and store *) 91 79 92 (** [load mem chunk addr] reads a value of type [chunk] at the address [addr] 93 in memory [mem]. *) 94 val load : 'fun_def memory -> memory_q -> Value.t -> Value.t 95 (** [load2 mem size addr] reads a value of size [size] at the address [addr] 96 in memory [mem]. *) 97 val load2 : 'fun_def memory -> int -> Value.t -> Value.t 98 99 (** [store mem chunk addr v] writes the value [v] interpreted as a value of 100 type [chunk] at address [addr] in memory [mem]. *) 101 val store : 'fun_def memory -> memory_q -> Value.t -> Value.t -> 80 (** [load mem size addr] reads [size] bytes from address [addr] in memory 81 [mem] and returns the value found. *) 82 val load : 'fun_def memory -> int -> Value.address -> Value.t 83 val loadq : 'fun_def memory -> quantity -> Value.address -> Value.t 84 85 (** [store mem size addr v] writes the [size] first bytes (little endian 86 representation) of value [v] at address [addr] in memory [mem]. *) 87 val store : 'fun_def memory -> int -> Value.address -> Value.t -> 102 88 'fun_def memory 103 (** [store mem size addr v] writes the value [v] of size [size] at address 104 [addr] in memory [mem]. *) 105 val store2 : 'fun_def memory -> int -> Value.t -> Value.t -> 89 val storeq : 'fun_def memory -> quantity -> Value.address -> Value.t -> 106 90 'fun_def memory 91 92 (* Globals management *) 107 93 108 94 (** [add_var mem x init_datas] stores the datas [init_datas] in a new block of … … 116 102 val add_fun_def : 'fun_def memory -> AST.ident -> 'fun_def -> 'fun_def memory 117 103 104 val mem_global : 'fun_def memory -> AST.ident -> bool 105 118 106 (** [find_global mem x] returns the address associated with the global symbol 119 107 [x] in memory [mem]. [x] may be a global variable or the name of a 120 108 function. *) 121 val find_global : 'fun_def memory -> AST.ident -> Value. t109 val find_global : 'fun_def memory -> AST.ident -> Value.address 122 110 123 111 (** [find_fun_def mem addr] returns the function definition found at address 124 112 [addr] in memory [mem]. Raises an error if no function definition is 125 113 found. *) 126 val find_fun_def : 'fun_def memory -> Value. t-> 'fun_def114 val find_fun_def : 'fun_def memory -> Value.address -> 'fun_def 127 115 128 116 (** [align off sizes] returns the aligned offsets (starting at [off]) of datas … … 131 119 (int list (* resulting offsets *) * int (* full size *)) 132 120 133 val size_of_datas 121 val size_of_datas : AST.data list -> int 134 122 135 123 (** [offsets_of_datas datas] returns the aligned offsets for the datas … … 137 125 val offsets_of_datas : AST.data list -> (AST.data * int (* offset *)) list 138 126 139 val alloc_datas : 'fun_def memory -> AST.data list -> 140 ('fun_def memory * Value.t) 141 127 val alloc_datas : 'fun_def memory -> AST.data list -> 128 ('fun_def memory * Value.address) 129 130 val to_string : 'fun_def memory -> string 142 131 val print : 'fun_def memory -> unit 143 132 … … 145 134 146 135 147 (** The functor toa memory module. *)136 (** The functor of a memory module. *) 148 137 149 138 module Make (D : DATA_SIZE) = … … 154 143 module Offset = Value.Offset 155 144 156 let mq_of_ptr = MQ_pointer 145 let address_of_block_offset b off = 146 Value.of_mem_address (Value.make_mem_address b off) 157 147 158 148 let int_size = D.int_size … … 160 150 let alignment = D.alignment 161 151 162 163 (* Contents of a variable. *) 164 165 type cell = 166 | Datum of int * Value.t (* the size of the content and its value *) 167 | Cont (* the continuation of a content defined in a 168 previous block *) 152 let size_of_quantity = function 153 | QInt i -> i 154 | QPtr -> ptr_size 169 155 170 156 171 157 module OffsetMap = Map.Make (Offset) 172 type offsetMap = cellOffsetMap.t158 type offsetMap = Value.chunk OffsetMap.t 173 159 type offset = Offset.t 174 160 161 (* Empty cells are interpreted as an undefined byte value. *) 162 175 163 type contents = 176 { low : offset ; 177 high : offset ; 164 { low : offset ; (* inclusive *) 165 high : offset ; (* inclusive *) 178 166 cells : offsetMap } 179 167 … … 181 169 let add_cells contents off v = 182 170 update_cells contents (OffsetMap.add off v contents.cells) 171 let remove_cells contents off = 172 update_cells contents (OffsetMap.remove off contents.cells) 183 173 184 174 (* Alignment *) … … 247 237 248 238 module GlobalMap = Map.Make (String) 249 type globalMap = Value. tGlobalMap.t239 type globalMap = Value.address GlobalMap.t 250 240 251 241 (* The memory. … … 263 253 (* Pretty printing *) 264 254 265 let print mem = 266 let print_cells off = function 267 | Datum (size, v) when Value.eq v Value.undef -> 268 () 269 | Datum (size, v) -> 270 Printf.printf "\n %s: [%d,%s]%!" 271 (Offset.to_string off) size (Value.to_string v) 272 | Cont -> Printf.printf "[Cont]%!" in 273 let print_block b content = 274 Printf.printf "\nBlock %s: %!" (Block.to_string b) ; 275 match content with 255 let to_string mem = 256 let i = ref 0 in 257 let string_of_cell off v s = 258 let s' = if !i mod 4 = 0 then (i := 0 ; "\n ") else "" in 259 i := !i+1 ; 260 let sv = 261 if Value.is_undef_byte v then "" 262 else Printf.sprintf "[%s]: %s" 263 (Offset.to_string off) (Value.string_of_chunk v) in 264 Printf.sprintf "%s%s %s" s s' sv in 265 let string_of_cells cells = OffsetMap.fold string_of_cell cells "" in 266 let string_of_block b content s = 267 (Printf.sprintf "%s\nBlock %s: " s (Block.to_string b)) ^ 268 (match content with 276 269 | Contents contents -> 277 Printf.printf "(%s -> %s)%!" 278 (Offset.to_string contents.low) (Offset.to_string contents.high) ; 279 OffsetMap.iter print_cells contents.cells 280 | Fun_def _ -> Printf.printf "function definition%!" ; 281 in 282 BlockMap.iter print_block mem.blocks ; 283 Printf.printf "\n%!" 270 i := 0 ; 271 Printf.sprintf "(%s -> %s)%s" 272 (Offset.to_string contents.low) 273 (Offset.to_string contents.high) 274 (string_of_cells contents.cells) 275 | Fun_def _ -> "function definition") in 276 Printf.sprintf "%s\n" (BlockMap.fold string_of_block mem.blocks "") 277 278 let print mem = Printf.printf "%s%!" (to_string mem) 284 279 285 280 … … 294 289 (* Memory allocation *) 295 290 296 (** [write_interval contents lo_off hi_off d] writes the cell [d] in the 297 contents [contents] from the offset [lo_off] (inclusive) to the offset 298 [hi_off] (exclusive). *) 299 let rec write_interval contents lo_off hi_off d = 300 if Offset.ge lo_off hi_off then contents 301 else 302 let contents = add_cells contents lo_off d in 303 write_interval contents (Offset.succ lo_off) hi_off d 304 305 (** [alloc2 mem lo hi] allocates in memory [mem] a new block whose readable 306 and writable offsets are the interval [lo] (inclusive) [hi] 307 (exclusive). *) 308 let alloc2 mem lo hi = 291 (** [alloc2 mem low high] allocates in memory [mem] a new block whose readable 292 and writable offsets are the interval [low] (inclusive) [high] 293 (inclusive). *) 294 let alloc2 mem low high = 309 295 let b = mem.next_block in 310 let contents = { low = lo ; high = hi ; cells = OffsetMap.empty } in 311 let contents = write_interval contents lo hi (Datum (1, Value.undef)) in 296 let contents = { low = low ; high = high ; cells = OffsetMap.empty } in 312 297 let blocks = BlockMap.add b (Contents contents) mem.blocks in 313 298 let next_block = Block.succ mem.next_block in 314 299 let mem' = { mem with blocks = blocks ; next_block = next_block } in 315 (mem', Value.of_pointer (b, lo))316 317 (** [alloc mem size] allocates a block of [size] size (in bytes) in the memory318 [mem]. It returns the new memory and a pointer to the beginning of the300 (mem', address_of_block_offset b low) 301 302 (** [alloc mem size] allocates a block of [size] bytes in the memory [mem]. It 303 returns the new memory and the address of the beginning of the newly 319 304 allocated area. *) 320 305 let alloc mem size = 321 alloc2 mem Offset.zero (Offset.of_int size) 322 323 324 let size_of_mq = function 325 | MQ_int8unsigned | MQ_int8signed -> 1 326 | MQ_int16unsigned | MQ_int16signed -> 2 327 | MQ_int32 | MQ_float32 -> 4 328 | MQ_float64 -> 8 329 | MQ_pointer -> D.ptr_size 330 | MQ_chunk -> D.ptr_size/2 331 332 let cast_of_mq = function 333 | MQ_int8unsigned -> Value.cast8unsigned 334 | MQ_int8signed -> Value.cast8signed 335 | MQ_int16unsigned -> Value.cast16unsigned 336 | MQ_int16signed -> Value.cast16signed 337 | MQ_int32 -> Value.cast32 338 | MQ_float32 | MQ_float64 -> error "float not supported." 339 | MQ_pointer | MQ_chunk -> (fun v -> v) 306 if size = 0 then (mem, Value.null) 307 else alloc2 mem Offset.zero (Offset.of_int (size-1)) 308 340 309 341 310 (* The 'safe'-prefixed functions below raise an error when the argument is not 342 311 of the expected form. *) 343 312 344 let safe_to_ pointer msg v =345 if Value.is_ pointer v then Value.to_pointer v313 let safe_to_address msg vs = 314 if Value.is_mem_address vs then Value.to_mem_address vs 346 315 else error msg 347 316 348 let safe_find msgfind a map =317 let safe_find not_found find a map = 349 318 try find a map 350 with Not_found -> error msg 351 352 let safe_find_block msg b mem = safe_find msg BlockMap.find b mem.blocks 319 with Not_found -> not_found () 320 321 let safe_find_err msg = safe_find (fun () -> error msg) 322 323 let safe_find_block msg b mem = safe_find_err msg BlockMap.find b mem.blocks 353 324 354 325 let safe_find_contents msg b mem = match safe_find_block msg b mem with … … 357 328 358 329 let safe_find_offset msg off contents = 359 safe_find msg OffsetMap.find off contents.cells 330 if (Offset.leu contents.low off) && (Offset.leu off contents.high) then 331 safe_find (fun () -> Value.undef_byte) OffsetMap.find off contents.cells 332 else error msg 360 333 361 334 let memory_find msg mem b off = 362 335 safe_find_offset msg off (safe_find_contents msg b mem) 363 336 364 (** [all_are_in_list msg mem b first_off last_off dl] returns [true] iff all 365 the datas found in the block [b] of memory [mem] and between offsets 366 [first_off] (inclusive) and [last_off] (exclusive) are in the list 367 [dl]. *) 368 let all_are_in_list msg mem b first_off last_off dl = 369 let d_eq d d' = match d, d' with 370 | Datum (size, v), Datum (size', v') -> (size = size') && (Value.eq v v') 371 | Cont, Cont -> true 372 | _ -> false in 373 let rec aux d = function 374 | [] -> false 375 | d' :: dl -> (d_eq d d') || (aux d dl) in 376 let dl_mem d = aux d dl in 337 338 (* Memory free *) 339 340 let free mem vs = 341 let addr = safe_to_address "free: invalid memory address." vs in 342 let (b, _) = Value.decompose_mem_address addr in 343 { mem with blocks = BlockMap.remove b mem.blocks } 344 345 346 (* Memory load *) 347 348 (** [load_bytes msg mem b off size] reads [size] bytes from the block [b] and 349 offset [off] in memory [mem] and returns the value found. If an error 350 occurs, [msg] will be printed. *) 351 let load_bytes msg mem b off size = 352 let shift_off n = Offset.add off (Offset.of_int n) in 353 let rec aux n = 354 if n >= size then [] 355 else (memory_find msg mem b (shift_off n)) :: (aux (n+1)) in 356 Value.merge (aux 0) 357 358 (** [load mem size addr] reads [size] bytes from address [addr] in memory 359 [mem] and returns the value found. *) 360 let load mem size vs = 361 let msg = "load: invalid memory access." in 362 let addr = safe_to_address msg vs in 363 let (b, off) = Value.decompose_mem_address addr in 364 if not (is_aligned off size) then 365 error "Alignment constraint violated when loading value." 366 else load_bytes msg mem b off size 367 368 let loadq mem q vs = load mem (size_of_quantity q) vs 369 370 371 (* Memory store *) 372 373 (** [store_chunks msg mem size b off chunks] writes the [size] first chunks of 374 list [chunks] at the offset [off] of the block [b] in the memory [mem]. *) 375 let store_chunks msg mem size b off chunks = 376 let shift_off n = Offset.add off (Offset.of_int n) in 377 let f i contents chunk = 378 let off' = shift_off i in 379 if (Offset.leu contents.low off') && 380 (Offset.leu off' contents.high) then 381 if Value.is_undef_byte chunk then contents 382 else add_cells contents off' chunk 383 else error msg in 377 384 match safe_find_block msg b mem with 378 | Contents contents 379 when (Offset.le contents.low first_off) && 380 (Offset.le last_off contents.high) -> 381 let rec aux off = 382 if Offset.ge off last_off then true 383 else 384 if OffsetMap.mem off contents.cells then 385 let d = OffsetMap.find off contents.cells in 386 (dl_mem d) && (aux (Offset.succ off)) 387 else false 388 in 389 aux first_off 390 | _ -> false 391 392 (** [all_are_undef msg mem b first_off last_off] returns [true] iff all the 393 datas found in the block [b] of memory [mem] and between offsets 394 [first_off] (inclusive) and [last_off] (exclusive) are the undef value. *) 395 let all_are_undef msg mem b first_off last_off = 396 all_are_in_list msg mem b first_off last_off [Datum (1, Value.undef)] 397 398 (** [all_are_undef msg mem b first_off last_off] returns [true] iff all the 399 datas found in the block [b] of memory [mem] and between offsets 400 [first_off] (inclusive) and [last_off] (exclusive) are the undef value or 401 the Cont cell. *) 402 let all_are_undef_or_cont msg mem b first_off last_off = 403 all_are_in_list msg mem b first_off last_off [Datum (1, Value.undef) ; Cont] 404 405 let string_of_alignment = function 406 | None -> "none" 407 | Some alignment -> string_of_int alignment 408 409 (** [write_value msg mem b off size v size'] store the value [v] at the offset 410 [off] of the block [b] in the memory [mem]. [size] is the size of the 411 value [v], and [size'] >= [size] is the number of bytes that are actually 412 written. When [size'] > [size], the undefined value is used to fill the 413 remaining memory cells. *) 414 let write_value msg mem b off size v size' = 385 | Contents contents -> 386 let contents = MiscPottier.foldi_until size f contents chunks in 387 let blocks = BlockMap.add b (Contents contents) mem.blocks in 388 { mem with blocks = blocks } 389 | _ -> error msg 390 391 (** [store mem size addr v] writes the [size] first bytes (little endian 392 representation) of value [v] at address [addr] in memory [mem]. *) 393 let store mem size vs v = 394 let msg = "store: invalid memory access." in 395 let addr = safe_to_address msg vs in 396 let (b, off) = Value.decompose_mem_address addr in 415 397 if not (is_aligned off size) then 416 398 error "Alignment constraint violated when storing value." 417 else 418 let shift_off n = Offset.add off (Offset.of_int n) in 419 match safe_find_block msg b mem with 420 | Contents contents 421 when (Offset.le contents.low off) && 422 (Offset.le (shift_off size) contents.high) -> 423 let contents = add_cells contents off (Datum (size, v)) in 424 let contents = 425 write_interval contents (Offset.succ off) (shift_off size) Cont in 426 let contents = 427 write_interval contents (shift_off size) (shift_off size') 428 (Datum (1, Value.undef)) in 429 let blocks = BlockMap.add b (Contents contents) mem.blocks in 430 { mem with blocks = blocks } 431 | _ -> error msg 432 433 434 (* Memory free *) 435 436 let free mem addr = 437 if Value.is_pointer addr then 438 let (b, _) = Value.to_pointer addr in 439 { mem with blocks = BlockMap.remove b mem.blocks } 440 else error "free: invalid memory address." 441 442 443 (* Memory load and store *) 444 445 (** [load2 mem size addr] reads a value of size [size] at the address [addr] 446 in memory [mem]. *) 447 let load2 mem size addr = 448 let msg = ("load: invalid memory access. ("^(Value.to_string addr)^")") in 449 let (b, off) = safe_to_pointer msg addr in 450 if not (is_aligned off size) then 451 error "Alignment constraint violated when loading value." 452 else 453 match memory_find msg mem b off with 454 | Datum (size', v) when size <= size' -> 455 v 456 (*print_string ("Db: load m "^(string_of_memory_q chunk)^" " 457 ^(Value.to_string addr)^" "^(Value.to_string r)^" (" 458 ^(Value.to_string v)^")\n"); *) 459 | _ -> print mem;error msg 460 461 (** [load mem chunk addr] reads a value of type [chunk] at the address [addr] 462 in memory [mem]. *) 463 let load mem chunk addr = 464 let size = size_of_mq chunk in 465 cast_of_mq chunk (load2 mem size addr) 466 467 468 (** [write_undef_before msg mem b off] replaces with undefined values the 469 value whose last cell is at offset [off] of block [b] in memory 470 [mem]. *) 471 let write_undef_before msg mem b off = 472 let contents = safe_find_contents msg b mem in 473 let d = Datum (1, Value.undef) in 474 let rec aux off contents = 475 if OffsetMap.mem off contents.cells then 476 let contents' = add_cells contents off d in 477 match OffsetMap.find off contents.cells with 478 | Datum _ -> contents' 479 | Cont -> aux (Offset.pred off) contents' 480 else contents 481 in 482 let contents = aux off contents in 483 { mem with blocks = BlockMap.add b (Contents contents) mem.blocks } 484 485 (** [store2 mem size addr v] writes the value [v] of size [size] at address 486 [addr] in memory [mem]. *) 487 let store2 mem size addr v = 488 let msg = "store: invalid memory access." in 489 let (b, off) = safe_to_pointer msg addr in 490 let shift_off n = Offset.add off (Offset.of_int n) in 491 (*print_string ("Db: store m "^(string_of_memory_q chunk)^" " 492 ^(Value.to_string addr)^" "^(Value.to_string v)^" (" 493 ^(Value.to_string v0)^")\n"); *) 494 match memory_find msg mem b off with 495 | Datum (size', _) when size <= size' -> 496 write_value msg mem b off size v size' 497 | Datum (size', _) 498 when all_are_undef msg mem b (shift_off size') (shift_off size) -> 499 write_value msg mem b off size v size' 500 | Cont when all_are_undef_or_cont msg mem b off (shift_off size) -> 501 let mem = write_value msg mem b off size v size in 502 write_undef_before msg mem b (Offset.pred off) 503 | _ -> error msg 504 505 (** [store mem chunk addr v] writes the value [v] interpreted as a value of 506 type [chunk] at address [addr] in memory [mem]. *) 507 let store mem chunk addr v = 508 store2 mem (size_of_mq chunk) addr (cast_of_mq chunk v) 509 510 511 (* Data manipulation *) 399 else store_chunks msg mem size b off (Value.break v) 400 401 let storeq mem q vs v = store mem (size_of_quantity q) vs v 402 403 404 (* Data manipulation *) 512 405 513 406 let value_of_data = function 514 407 | AST.Data_reserve _ -> Value.undef 515 408 | AST.Data_int8 i | AST.Data_int16 i | AST.Data_int32 i -> Value.of_int i 516 | AST.Data_float32 f | AST.Data_float64 f -> Value.of_float f 517 518 let size_of_data = function 519 | AST.Data_reserve n -> n 520 | data -> size_of_mq (mq_of_data data) 409 | AST.Data_float32 f | AST.Data_float64 f -> error "float not supported." 521 410 522 411 let offsets_size_of_datas datas = … … 526 415 allocating space and storing the datas [datas] in the memory [mem]. *) 527 416 let alloc_datas mem datas = 417 let msg = "cannot allocate datas." (* TODO *) in 528 418 let (offs_of_datas, size) = offsets_size_of_datas datas in 529 let (mem, addr) = alloc mem size in 530 let shift_addr off = Value.add addr (Value.of_int_repr off) in 419 let (mem, vs) = alloc mem size in 420 let addr = safe_to_address msg vs in 421 let (b, off) = Value.decompose_mem_address addr in 422 let shift_addr off' = 423 let off = Offset.add off off' in 424 address_of_block_offset b off in 531 425 let f mem data off = match data with 532 426 | AST.Data_reserve _ -> mem 533 | _ -> store mem ( mq_of_data data) (shift_addr off) (value_of_data data)427 | _ -> store mem (size_of_data data) (shift_addr off) (value_of_data data) 534 428 in 535 (List.fold_left2 f mem datas offs_of_datas, addr)429 (List.fold_left2 f mem datas offs_of_datas, vs) 536 430 537 431 let size_of_datas datas = snd (offsets_size_of_datas datas) … … 550 444 551 445 552 (* Global environmentmanipulation *)446 (* Globals manipulation *) 553 447 554 448 (** [add_var mem x init_datas] stores the datas [init_datas] in a new block of … … 556 450 the block. *) 557 451 let add_var mem v_id datas = 558 let (mem, addr) = alloc_datas mem datas in559 let addr_of_global = GlobalMap.add v_id addrmem.addr_of_global in452 let (mem, vs) = alloc_datas mem datas in 453 let addr_of_global = GlobalMap.add v_id vs mem.addr_of_global in 560 454 { mem with addr_of_global = addr_of_global } 561 455 … … 566 460 let b = mem.next_fun_block in 567 461 let next_fun_block = Block.pred mem.next_fun_block in 568 let addr = Value.of_pointer (b, Offset.zero)in569 let addr_of_global = GlobalMap.add f_id addrmem.addr_of_global in462 let vs = address_of_block_offset b Offset.zero in 463 let addr_of_global = GlobalMap.add f_id vs mem.addr_of_global in 570 464 let blocks = BlockMap.add b (Fun_def f_def) mem.blocks in 571 465 { mem with blocks = blocks ; 572 466 addr_of_global = addr_of_global ; 573 467 next_fun_block = next_fun_block } 468 469 let mem_global mem id = GlobalMap.mem id mem.addr_of_global 574 470 575 471 (** [find_global mem x] returns the address associated with the global symbol … … 584 480 [addr] in memory [mem]. Raises an error if no function definition is 585 481 found. *) 586 let find_fun_def mem v =482 let find_fun_def mem vs = 587 483 let msg = "Invalid access to a function definition." in 588 let (b, _) = safe_to_pointer msg vin484 let (b, _) = Value.decompose_mem_address (safe_to_address msg vs) in 589 485 match safe_find_block msg b mem with 590 486 | Contents _ -> error msg 591 487 | Fun_def def -> def 592 488 593 594 595 596 489 end -
Deliverables/D2.2/8051/src/common/memory.mli
r619 r740 4 4 following the memory model of the CompCert compiler. *) 5 5 6 (** In the module, every size areexpressed in bytes. *)6 (** In the module, every size is expressed in bytes. *) 7 7 8 (** Memory quantities is the size and type of what can be loaded or stored in 9 memory. *) 8 10 9 (* Memory quantities are the size and the type of what can be loaded 10 and stored in memory *) 11 type quantity = 12 | QInt of int (* Sized integer *) 13 | QPtr (* Pointer *) 11 14 12 type memory_q = 13 | MQ_int8signed | MQ_int8unsigned | MQ_int16signed | MQ_int16unsigned 14 | MQ_int32 | MQ_float32 | MQ_float64 | MQ_pointer 15 | MQ_chunk (* no type, just the raw content of a word size *) 15 val string_of_quantity : quantity -> string 16 16 17 val string_of_memory_q : memory_q -> string 18 19 val mq_of_data : AST.data -> memory_q 20 21 val type_of_memory_q : memory_q -> AST.sig_type 17 val size_of_data : AST.data -> int 22 18 23 19 … … 26 22 module type DATA_SIZE = 27 23 sig 28 val int_size : int (* in bytes *)29 val ptr_size : int (* in bytes *)30 val alignment : int option (* in bytes, if any *)24 val int_size : int 25 val ptr_size : int 26 val alignment : int option 31 27 end 32 28 … … 38 34 sig 39 35 40 val mq_of_ptr : memory_q41 36 val int_size : int 42 37 val ptr_size : int 43 38 val alignment : int option 39 40 val size_of_quantity : quantity -> int 44 41 45 42 module Value : Value.S … … 56 53 val empty : 'fun_def memory 57 54 58 (** [alloc mem size] allocates a block of [size] size (in bytes) in the memory59 [mem]. It returns the new memory and a pointer to the beginning of the55 (** [alloc mem size] allocates a block of [size] bytes in the memory [mem]. It 56 returns the new memory and the address of the beginning of the newly 60 57 allocated area. *) 61 val alloc : 'fun_def memory -> int -> 'fun_def memory * Value. t58 val alloc : 'fun_def memory -> int -> 'fun_def memory * Value.address 62 59 63 60 (* Memory free *) 64 61 65 val free : 'fun_def memory -> Value. t-> 'fun_def memory62 val free : 'fun_def memory -> Value.address -> 'fun_def memory 66 63 67 64 (* Memory load and store *) 68 65 69 (** [load mem chunk addr] reads a value of type [chunk] at the address [addr] 70 in memory [mem]. *) 71 val load : 'fun_def memory -> memory_q -> Value.t -> Value.t 72 (** [load2 mem size addr] reads a value of size [size] at the address [addr] 73 in memory [mem]. *) 74 val load2 : 'fun_def memory -> int -> Value.t -> Value.t 66 (** [load mem size addr] reads [size] bytes from address [addr] in memory 67 [mem] and returns the value found. *) 68 val load : 'fun_def memory -> int -> Value.address -> Value.t 69 val loadq : 'fun_def memory -> quantity -> Value.address -> Value.t 75 70 76 (** [store mem chunk addr v] writes the value [v] interpreted as a value of77 type [chunk] at address [addr] in memory [mem]. *)78 val store : 'fun_def memory -> memory_q -> Value.t-> Value.t ->71 (** [store mem size addr v] writes the [size] first bytes (little endian 72 representation) of value [v] at address [addr] in memory [mem]. *) 73 val store : 'fun_def memory -> int -> Value.address -> Value.t -> 79 74 'fun_def memory 80 (** [store2 mem size addr v] writes the value [v] of size [size] at address 81 [addr] in memory [mem]. *) 82 val store2 : 'fun_def memory -> int -> Value.t -> Value.t -> 75 val storeq : 'fun_def memory -> quantity -> Value.address -> Value.t -> 83 76 'fun_def memory 77 78 (* Globals management *) 84 79 85 80 (** [add_var mem x init_datas] stores the datas [init_datas] in a new block of … … 93 88 val add_fun_def : 'fun_def memory -> AST.ident -> 'fun_def -> 'fun_def memory 94 89 90 val mem_global : 'fun_def memory -> AST.ident -> bool 91 95 92 (** [find_global mem x] returns the address associated with the global symbol 96 93 [x] in memory [mem]. [x] may be a global variable or the name of a 97 94 function. *) 98 val find_global : 'fun_def memory -> AST.ident -> Value. t95 val find_global : 'fun_def memory -> AST.ident -> Value.address 99 96 100 97 (** [find_fun_def mem addr] returns the function definition found at address 101 98 [addr] in memory [mem]. Raises an error if no function definition is 102 99 found. *) 103 val find_fun_def : 'fun_def memory -> Value. t-> 'fun_def100 val find_fun_def : 'fun_def memory -> Value.address -> 'fun_def 104 101 105 102 (** [align off sizes] returns the aligned offsets (starting at [off]) of datas … … 115 112 116 113 val alloc_datas : 'fun_def memory -> AST.data list -> 117 ('fun_def memory * Value. t)114 ('fun_def memory * Value.address) 118 115 116 val to_string : 'fun_def memory -> string 119 117 val print : 'fun_def memory -> unit 120 118 -
Deliverables/D2.2/8051/src/common/primitive.ml
r486 r740 2 2 (** These are the functions provided by the runtime system. *) 3 3 4 let print_int = "print_int" 5 let print_intln = "print_intln" 4 5 let error_prefix = "Primitives" 6 let error s = Error.global_error error_prefix s 7 let warning s = Error.warning error_prefix s 8 9 10 let print = "print" 11 let println = "println" 6 12 let scan_int = "scan_int" 7 13 let alloc = "alloc" 8 let modulo = "mod"14 let newline = "newline" 9 15 10 16 let primitives_list = 11 [print _int ; print_intln ; scan_int ; alloc ; modulo]17 [print ; println ; scan_int ; alloc ; newline] 12 18 13 19 let primitives = … … 16 22 17 23 let is_primitive f = StringTools.Set.mem f primitives 24 25 26 module Interpret (M : Memory.S) = struct 27 28 type res = V of M.Value.t | A of M.Value.address 29 30 let t mem f = function 31 | _ when f = scan_int -> 32 Printf.printf ": %!" ; 33 (mem, V (M.Value.of_int (int_of_string (read_line ())))) 34 | v :: _ when f = print -> 35 Printf.printf "%s%!" (M.Value.to_string v) ; 36 (mem, V M.Value.zero) 37 | v :: _ when f = println -> 38 Printf.printf "%s\n%!" (M.Value.to_string v) ; 39 (mem, V M.Value.zero) 40 | v :: _ when f = alloc && M.Value.is_int v -> 41 let size = M.Value.to_int v in 42 let (mem, addr) = M.alloc mem size in 43 (mem, A addr) 44 | _ when f = newline -> 45 Printf.printf "\n%!" ; 46 (mem, V M.Value.zero) 47 | _ -> error ("unknown primitive " ^ f ^ " or wrong size arguments.") 48 end 18 49 19 50 … … 35 66 (print_arg_types sg.AST.args) 36 67 (print_type_return sg.AST.res) 68 69 let print_prototype = 70 "extern void print(int);" 71 72 let println_prototype = 73 "extern void println(int);" 74 75 let scan_int_prototype = 76 "extern int scan_int(void);" 77 78 let alloc_prototype = 79 "extern int* alloc(int);" 80 81 let newline_prototype = 82 "extern void newline(void);" 83 84 let prototypes = 85 let ss = 86 [print_prototype ; println_prototype ; scan_int_prototype ; 87 alloc_prototype ; newline_prototype] in 88 let f res s = res ^ "\n" ^ s in 89 (List.fold_left f "" ss) ^ "\n\n" -
Deliverables/D2.2/8051/src/common/primitive.mli
r486 r740 6 6 val is_primitive : string -> bool 7 7 8 val print_int : string 9 val print_intln : string 8 (* extern void print(int); *) 9 val print : string 10 (* extern void println(int); *) 11 val println : string 12 (* extern int scan_int(void); *) 10 13 val scan_int : string 14 (* extern int* alloc(int); *) 11 15 val alloc : string 12 val modulo : string 16 (* extern void newline(void); *) 17 val newline : string 13 18 14 19 val print_sig : AST.signature -> string 20 21 module Interpret (M : Memory.S) : sig 22 type res = V of M.Value.t | A of M.Value.address 23 val t : 'a M.memory -> string -> M.Value.t list -> 'a M.memory * res 24 end 25 26 val prototypes : string -
Deliverables/D2.2/8051/src/common/value.ml
r619 r740 21 21 end 22 22 23 (** This is the signature of the module that provides functions and types to23 (** This is the signature of the module that provides types and functions to 24 24 manipulate values. *) 25 25 … … 27 27 sig 28 28 29 (** Addresses are represented by a block, i.e. a base address, and an offset 30 from this block. Both blocks and offsets are represented using bounded 31 integers. *) 32 module Block : IntValue.S 33 module Offset : IntValue.S 34 35 (** The type of values. A value may be: a bounded integer, a float (though 36 they are not fully supported), an address, or undefined. *) 29 (** The type of values. A value may be: a bounded integer, a chunk of an 30 address (exactly an address when they have the same size as a machine 31 register), or undefined. *) 37 32 type t 38 33 … … 50 45 val of_int : int -> t 51 46 52 val is_float : t -> bool 53 val to_float : t -> float 54 val of_float : float -> t 55 47 val of_int_repr : IntValue.int_repr -> t 56 48 val to_int_repr : t -> IntValue.int_repr 57 val of_int_repr : IntValue.int_repr -> t58 59 val is_pointer : t -> bool60 val to_pointer : t -> Block.t * Offset.t61 val of_pointer : Block.t * Offset.t -> t62 49 63 50 val of_bool : bool -> t … … 71 58 val undef : t 72 59 73 (** [cast8unsigned v] returns undefined for non-integer values. Forinteger74 values , it supposes that the value is a 8 bit unsigned integer. It will75 re turn the integer value that represents the same quantity, but using76 e very bits. The other cast operations behave the same way. *)77 val cast8unsigned : t -> t 78 val cast8signed : t -> t 79 val cast16unsigned : t -> t 60 (** The cast operations below returns the undefined value for non-integer 61 values. For integer values, it will return the integer value that 62 represents the same quantity, but using every bits (sign or zero 63 extension) of an integer value. *) 64 val cast8unsigned : t -> t 65 val cast8signed : t -> t 66 val cast16unsigned : t -> t 80 67 val cast16signed : t -> t 81 68 val cast32 : t -> t 82 69 70 (** [zero_ext v n m] performs a zero extension on [v] where [n] bits are 71 significant to a value where [m] bits are significant. *) 72 val zero_ext : t -> int -> int -> t 73 (** [sign_ext v n m] performs a sign extension on [v] where [n] bits are 74 significant to a value where [m] bits are significant. *) 75 val sign_ext : t -> int -> int -> t 76 83 77 (** Integer opposite *) 84 val negint 78 val negint : t -> t 85 79 (** Boolean negation *) 86 val notbool 80 val notbool : t -> t 87 81 (** Bitwise not *) 88 val notint : t -> t 89 val negf : t -> t 90 val absf : t -> t 91 val singleoffloat : t -> t 92 val intoffloat : t -> t 93 val intuoffloat : t -> t 94 val floatofint : t -> t 95 val floatofintu : t -> t 96 97 val succ : t -> t 98 val pred : t -> t 99 val cmpl : t -> t 82 val notint : t -> t 83 84 val succ : t -> t 85 val pred : t -> t 86 val cmpl : t -> t 100 87 101 88 (** [add_and_of v1 v2] returns the sum of [v1] and [v2], and whether this sum … … 106 93 overflows, and [0] otherwise. *) 107 94 val add_of : t -> t -> t 108 (** [sub_and_ of v1 v2] returns the substraction of [v1] and [v2], and whether95 (** [sub_and_uf v1 v2] returns the substraction of [v1] and [v2], and whether 109 96 this substraction underflows. *) 110 97 val sub_and_uf : t -> t -> (t * t) 111 98 val sub : t -> t -> t 112 (** [sub_ of v1 v2] returns the [1] value if the substraction of [v1] and [v2]99 (** [sub_uf v1 v2] returns the [1] value if the substraction of [v1] and [v2] 113 100 underflows, and [0] otherwise. *) 114 101 val sub_uf : t -> t -> t … … 124 111 val shr : t -> t -> t 125 112 val shru : t -> t -> t 126 val addf : t -> t -> t 127 val subf : t -> t -> t 128 val mulf : t -> t -> t 129 val divf : t -> t -> t 113 114 (** Signed comparisions *) 115 val cmp_eq : t -> t -> t 116 val cmp_ne : t -> t -> t 117 val cmp_lt : t -> t -> t 118 val cmp_ge : t -> t -> t 119 val cmp_le : t -> t -> t 120 val cmp_gt : t -> t -> t 130 121 131 122 (** Unsigned comparisions *) 132 val cmp_eq_u : t -> t -> t 133 val cmp_ne_u : t -> t -> t 134 val cmp_lt_u : t -> t -> t 135 val cmp_ge_u : t -> t -> t 136 val cmp_le_u : t -> t -> t 137 val cmp_gt_u : t -> t -> t 138 139 val cmp_eq_f : t -> t -> t 140 val cmp_ne_f : t -> t -> t 141 val cmp_lt_f : t -> t -> t 142 val cmp_ge_f : t -> t -> t 143 val cmp_le_f : t -> t -> t 144 val cmp_gt_f : t -> t -> t 145 146 val cmp_eq : t -> t -> t 147 val cmp_ne : t -> t -> t 148 val cmp_lt : t -> t -> t 149 val cmp_ge : t -> t -> t 150 val cmp_le : t -> t -> t 151 val cmp_gt : t -> t -> t 152 153 (** [break v n] cuts [v] in [n] parts. In the resulting list, the first 154 element is the high bits, and the last is the low bits. *) 155 val break : t -> int -> t list 156 (** [merge l] creates the value where the first element of [l] is its 157 high bits, etc, and the last element of [l] is its low bits. *) 158 val merge : t list -> t 123 val cmp_eq_u : t -> t -> t 124 val cmp_ne_u : t -> t -> t 125 val cmp_lt_u : t -> t -> t 126 val cmp_ge_u : t -> t -> t 127 val cmp_le_u : t -> t -> t 128 val cmp_gt_u : t -> t -> t 129 130 (** A chunk is a part of a value that has the size of a memory cell. *) 131 132 type chunk 133 val string_of_chunk : chunk -> string 134 val undef_byte : chunk 135 val is_undef_byte : chunk -> bool 136 137 (** [break v] cuts [v] in chunks that each fits into a memory cell. In the 138 resulting list, the first element is the low bits, and the last is the 139 high bits (little endian representation). *) 140 val break : t -> chunk list 141 (** [merge l] creates the value where the first element of [l] is its low 142 bits, etc, and the last element of [l] is its high bits (little endian 143 representation). *) 144 val merge : chunk list -> t 145 146 (** Addresses from the memory point of view. *) 147 148 (** Some architectures have pointers bigger than integers. In this case, only 149 a chunk of pointer can fit into a machine register. Thus, an address is 150 represented by several values (little endian representation). *) 151 152 type address = t list 153 val string_of_address : address -> string 154 val null : address 155 156 (** Addresses from the memory point of view. Only use the functions below in 157 the Memory module.*) 158 159 (** Addresses are represented by a block, i.e. a base address, and an offset 160 from this block. Both blocks and offsets are represented using bounded 161 integers. *) 162 module Block : IntValue.S 163 module Offset : IntValue.S 164 165 type mem_address 166 167 val is_mem_address : address -> bool 168 169 val of_mem_address : mem_address -> address 170 val to_mem_address : address -> mem_address 171 val make_mem_address : Block.t -> Offset.t -> mem_address 172 val decompose_mem_address : mem_address -> Block.t * Offset.t 173 val block_of_address : address -> Block.t 174 val offset_of_address : address -> Offset.t 175 176 val change_address_offset : address -> Offset.t -> address 177 val add_address : address -> Offset.t -> address 178 val eq_address : address -> address -> bool 159 179 160 180 end … … 164 184 struct 165 185 166 (* This module will be used to represent integer values. *) 167 module Int = 168 IntValue.Make (struct let size = D.int_size end) 186 (* Integer values. *) 187 module ValInt = IntValue.Make (struct let size = D.int_size end) 169 188 170 189 (* Addresses are represented by a block, i.e. a base address, and an offset 171 190 from this block. Both blocks and offsets are represented using bounded 172 integers. *) 173 174 (* In 8051, addresses are not the same size as integers: the size of an 175 address (16 bits) is twice that of an integer (8 bits). Thus, blocks and 176 offsets need 16 bits each to be represented. Indeed, one may allocate 2^16 177 blocks of size one byte, or one block of size 2^16 bytes. *) 178 179 module Block = 180 IntValue.Make (struct let size = D.ptr_size end) 181 module Offset = (* Block *) 182 IntValue.Make (struct let size = D.ptr_size end) 183 184 (* We want to be able to put an address into registers, and we want to be able 185 to restore an address given values from several registers. We provide a 186 function that breaks an address into multiple parts (two parts for the 187 8051), where each part fits into a register. But an address is formed with 188 two 16 bits values (the block and the offset), so we cannot break it into 189 two parts that are each represented by an integer: we need to keep the 190 information of the block and the offset. This is the purpose of the 191 Val_ptrh (the high bits of an address) and Val_ptrl (the low bits of an 192 address) constructors. *) 191 integers. However, values must fit into a machine register. Some 192 architectures, like the 8051, have addresses bigger than registers. Pointer 193 values will only represent a part of a full pointer (or exactly a pointer 194 when addresses fit into a register). *) 195 196 (* Blocks and offsets need [D.ptr_size] bits each to be represented. Indeed, 197 one may allocate 2^[D.ptr_size] blocks of size one byte, or one block of 198 size 2^[D.ptr_size] bytes. *) 199 200 module ValBlock = IntValue.Make (struct let size = D.int_size end) 201 module ValOffset = IntValue.Make (struct let size = D.int_size end) 193 202 194 203 type t = 195 | Val_int of Int.t 196 | Val_float of float 197 | Val_ptr of Block.t * Offset.t 198 | Val_ptrh of Block.t * Offset.t 199 | Val_ptrl of Block.t * Offset.t 204 | Val_int of ValInt.t 205 | Val_ptr of ValBlock.t * ValOffset.t 200 206 | Val_undef 201 207 202 208 let compare a b = match a, b with 203 | Val_int i1, Val_int i2 -> Int.compare i1 i2 204 | Val_float f1, Val_float f2 -> compare f1 f2 205 | Val_ptr (b1, off1), Val_ptr (b2, off2) 206 | Val_ptrh (b1, off1), Val_ptrh (b2, off2) 207 | Val_ptrl (b1, off1), Val_ptrl (b2, off2) -> 208 let i1 = Block.compare b1 b2 in 209 if i1 = 0 then Offset.compare off1 off2 209 | Val_int i1, Val_int i2 -> ValInt.compare i1 i2 210 | Val_ptr (b1, off1), Val_ptr (b2, off2) -> 211 let i1 = ValBlock.compare b1 b2 in 212 if i1 = 0 then ValOffset.compare off1 off2 210 213 else i1 211 214 | Val_undef, Val_undef -> 0 212 215 | Val_int _, _ -> 1 213 216 | _, Val_int _ -> -1 214 | Val_float _, _ -> 1215 | _, Val_float _ -> -1216 217 | Val_ptr _, _ -> 1 217 218 | _, Val_ptr _ -> -1 218 | Val_ptrh _, _ -> 1 219 | _, Val_ptrh _ -> -1 220 | Val_ptrl _, _ -> 1 221 | _, Val_ptrl _ -> -1 222 223 (* 224 let hash = function 225 | Val_int i -> Int.to_int i 219 220 (* 221 let hash = function 222 | Val_int i -> ValInt.to_int i 226 223 | Val_float f -> int_of_float f 227 224 | Val_undef -> 0 228 225 | Val_ptr (b,o) 229 226 | Val_ptrh (b,o) 230 | Val_ptrl (b,o) -> Int.to_int (Int.add b o)231 *)227 | Val_ptrl (b,o) -> ValInt.to_int (ValInt.add b o) 228 *) 232 229 233 230 let hash = Hashtbl.hash … … 237 234 238 235 let to_string = function 239 | Val_int i -> Int.to_string i 240 | Val_float f -> string_of_float f 236 | Val_int i -> ValInt.to_string i 241 237 | Val_ptr (b, off) -> 242 "Ptr(" ^ (Block.to_string b) ^ ", " ^ (Offset.to_string off) ^ ")" 243 | Val_ptrh (b, off) -> 244 "PtrH(" ^ (Block.to_string b) ^ ", " ^ (Offset.to_string off) ^ ")" 245 | Val_ptrl (b, off) -> 246 "PtrL(" ^ (Block.to_string b) ^ ", " ^ (Offset.to_string off) ^ ")" 238 "VPtr(" ^ (ValBlock.to_string b) ^ ", " ^ (ValOffset.to_string off) ^ ")" 247 239 | Val_undef -> "undef" 248 240 … … 252 244 253 245 let to_int = function 254 | Val_int i -> Int.to_int i246 | Val_int i -> ValInt.to_int i 255 247 | _ -> raise (Failure "Value.to_int") 256 248 257 let of_int i = Val_int (Int.of_int i) 249 let of_int i = Val_int (ValInt.of_int i) 250 let one = of_int 1 251 252 let of_int_repr i = Val_int i 258 253 259 254 let to_int_repr = function … … 261 256 | _ -> raise (Failure "Value.to_int_repr") 262 257 263 let of_int_repr i = Val_int i 264 265 let is_pointer = function 266 | Val_ptr _ -> true 258 let zero = Val_int ValInt.zero 259 let val_true = Val_int ValInt.one 260 let val_false = Val_int ValInt.zero 261 262 let is_true = function 263 | Val_int i -> ValInt.neq i ValInt.zero 264 | Val_ptr (b, off) -> 265 (ValBlock.neq b ValBlock.zero) || (ValOffset.neq off ValOffset.zero) 267 266 | _ -> false 268 267 269 let to_pointer = function 270 | Val_ptr (b, off) -> (b, off) 271 | _ -> raise (Failure "Value.to_pointer") 272 273 let of_pointer (b, off) = Val_ptr (b, off) 274 275 let is_float = function 276 | Val_float _ -> true 268 let is_false = function 269 | Val_int i -> ValInt.eq i ValInt.zero 270 | Val_ptr (b, off) -> 271 (ValBlock.eq b ValBlock.zero) && (ValOffset.eq off ValOffset.zero) 277 272 | _ -> false 278 273 279 let to_float = function280 | Val_float f -> f281 | _ -> raise (Failure "Value.to_float")282 283 let of_float f = Val_float f284 285 let zero = Val_int Int.zero286 287 let val_true = Val_int Int.one288 289 let val_false = Val_int Int.zero290 291 let is_true = function292 | Val_int i -> Int.neq i Int.zero293 | Val_ptr _ | Val_ptrh _ | Val_ptrl _ -> true294 | _ -> false295 296 let is_false = function297 | Val_int i -> Int.eq i Int.zero298 | _ -> false299 300 274 let of_bool = function 301 | true -> Val_int Int.one302 | false -> Val_int Int.zero275 | true -> val_true 276 | false -> val_false 303 277 304 278 let to_bool v = … … 315 289 316 290 (** Sign or 0 extensions from various bounded integers. *) 317 let cast8unsigned = cast ( Int.zero_ext 8)318 let cast8signed = cast ( Int.sign_ext 8)319 let cast16unsigned = cast ( Int.zero_ext 16)320 let cast16signed = cast ( Int.sign_ext 16)321 let cast32 = cast ( Int.zero_ext 32)291 let cast8unsigned = cast (ValInt.zero_ext 8) 292 let cast8signed = cast (ValInt.sign_ext 8) 293 let cast16unsigned = cast (ValInt.zero_ext 16) 294 let cast16signed = cast (ValInt.sign_ext 16) 295 let cast32 = cast (ValInt.zero_ext 32) 322 296 323 297 … … 330 304 | _ -> Val_undef 331 305 332 let unary_float_op f = function 333 | Val_float i -> Val_float (f i) 334 | _ -> Val_undef 335 336 let binary_float_op f v1 v2 = match v1, v2 with 337 | Val_float i1, Val_float i2 -> Val_float (f i1 i2) 338 | _ -> Val_undef 339 340 let binary_float_cmp f v1 v2 = match v1, v2 with 341 | Val_float i1, Val_float i2 -> of_bool (f i1 i2) 342 | _ -> Val_undef 343 344 345 let negint = unary_int_op Int.neg 306 let negint = unary_int_op ValInt.neg 346 307 347 308 let notbool v = … … 351 312 else Val_undef 352 313 353 let andbool v1 v2 = 354 if is_true v1 && is_true v2 then val_true 355 else 356 if (is_true v1 && is_false v2) || 357 (is_false v1 && is_true v2) || 358 (is_false v1 && is_false v2) then val_false 359 else Val_undef 360 361 let orbool v1 v2 = 362 if (is_true v1 && is_true v2) || 363 (is_true v1 && is_false v2) || 364 (is_false v1 && is_true v2) then val_true 365 else 366 if is_false v1 && is_false v2 then val_false 367 else Val_undef 368 369 let notint = unary_int_op Int.lognot 370 371 let negf = unary_float_op (fun f -> -.f) 372 373 let absf = unary_float_op abs_float 374 375 let singleoffloat _ = assert false (* TODO *) 376 377 let intoffloat = function 378 | Val_float f -> Val_int (Int.of_int (int_of_float f)) 379 | _ -> Val_undef 380 381 let intuoffloat _ = assert false (* TODO *) 382 383 let floatofint = function 384 | Val_int i -> Val_float (float_of_int (Int.to_int i)) 385 | _ -> Val_undef 386 387 let floatofintu _ = assert false (* TODO *) 314 let notint = unary_int_op ValInt.lognot 315 316 let cmpl = unary_int_op ValInt.lognot 388 317 389 318 (** [add_and_of v1 v2] returns the sum of [v1] and [v2], and whether this sum … … 391 320 let add_and_of v1 v2 = match v1, v2 with 392 321 | Val_int i1, Val_int i2 -> 393 (Val_int ( Int.add i1 i2), of_bool (Int.add_of i1 i2))322 (Val_int (ValInt.add i1 i2), of_bool (ValInt.add_of i1 i2)) 394 323 | Val_int i, Val_ptr (b, off) 395 324 | Val_ptr (b, off), Val_int i -> 396 (Val_ptr (b, Offset.add off i), 397 of_bool (Offset.add_of off (Offset.cast i))) 398 | Val_int i, Val_ptrh (b, off) 399 | Val_ptrh (b, off), Val_int i -> 400 (Val_ptrh (b, Offset.add off i), 401 of_bool (Offset.add_of off (Offset.cast i))) 402 | Val_int i, Val_ptrl (b, off) 403 | Val_ptrl (b, off), Val_int i -> 404 (Val_ptrl (b, Offset.add off i), 405 of_bool (Offset.add_of off (Offset.cast i))) 325 let i = ValOffset.cast i in 326 (Val_ptr (b, ValOffset.add off i), of_bool (ValOffset.add_of off i)) 406 327 | _, _ -> (Val_undef, Val_undef) 407 328 … … 409 330 let add_of v1 v2 = snd (add_and_of v1 v2) 410 331 411 let succ v = add v (Val_int Int.one)332 let succ v = add v (Val_int ValInt.one) 412 333 413 334 (** [sub_and_uf v1 v2] returns the substraction of [v1] and [v2], and whether … … 415 336 let sub_and_uf v1 v2 = match v1, v2 with 416 337 | Val_int i1, Val_int i2 -> 417 (Val_int ( Int.sub i1 i2), of_bool (Int.sub_uf i1 i2))338 (Val_int (ValInt.sub i1 i2), of_bool (ValInt.sub_uf i1 i2)) 418 339 | Val_ptr (b, off), Val_int i -> 419 (Val_ptr (b, Offset.sub off i), 420 of_bool (Offset.sub_uf off (Offset.cast i))) 421 | Val_ptrh (b, off), Val_int i -> 422 (Val_ptrh (b, Offset.sub off i), 423 of_bool (Offset.sub_uf off (Offset.cast i))) 424 | Val_ptrl (b, off), Val_int i -> 425 (Val_ptrl (b, Offset.sub off i), 426 of_bool (Offset.sub_uf off (Offset.cast i))) 427 | Val_ptr (b1, off1), Val_ptr (b2, off2) 428 | Val_ptrh (b1, off1), Val_ptrh (b2, off2) 429 | Val_ptrl (b1, off1), Val_ptrl (b2, off2) when Block.eq b1 b2 -> 430 (Val_int (Int.cast (Offset.sub off1 off2)), 431 of_bool (Offset.sub_uf off1 off2)) 340 let i = ValOffset.cast i in 341 (Val_ptr (b, ValOffset.sub off i), of_bool (ValOffset.sub_uf off i)) 342 | Val_ptr (b1, off1), Val_ptr (b2, off2) when ValBlock.eq b1 b2 -> 343 (Val_int (ValInt.cast (ValOffset.sub off1 off2)), 344 of_bool (ValOffset.sub_uf off1 off2)) 432 345 | _, _ -> (Val_undef, Val_undef) 433 346 … … 435 348 let sub_uf v1 v2 = snd (sub_and_uf v1 v2) 436 349 437 let pred v = sub v (Val_int Int.one) 438 439 let cmpl = unary_int_op Int.lognot 440 441 let mul = binary_int_op Int.mul 350 let pred v = sub v (Val_int ValInt.one) 351 352 let mul = binary_int_op ValInt.mul 442 353 443 354 let is_zero = function 444 | Val_int i when Int.eq iInt.zero -> true355 | Val_int i when ValInt.eq i ValInt.zero -> true 445 356 | _ -> false 446 357 447 let div v1 v2 = 448 if is_zero v2 then Val_undef 449 else binary_int_op Int.div v1 v2 450 451 let divu v1 v2 = 452 if is_zero v2 then Val_undef 453 else binary_int_op Int.divu v1 v2 454 455 let modulo v1 v2 = 456 if is_zero v2 then Val_undef 457 else binary_int_op Int.modulo v1 v2 458 459 let modulou v1 v2 = 460 if is_zero v2 then Val_undef 461 else binary_int_op Int.modulou v1 v2 462 463 let and_op = binary_int_op Int.logand 464 465 let or_op = binary_int_op Int.logor 466 467 let xor = binary_int_op Int.logxor 468 469 let shl = binary_int_op Int.shl 470 471 let shr = binary_int_op Int.shr 472 473 let shru = binary_int_op Int.shrl 474 475 let addf = binary_float_op (+.) 476 477 let subf = binary_float_op (-.) 478 479 let mulf = binary_float_op ( *. ) 480 481 let divf v1 v2 = match v2 with 482 | Val_float f2 when f2 <> 0. -> binary_float_op (/.) v1 v2 358 let error_if_zero op v1 v2 = 359 if is_zero v2 then error "Division by zero." 360 else binary_int_op op v1 v2 361 362 let div = error_if_zero ValInt.div 363 let divu = error_if_zero ValInt.divu 364 let modulo = error_if_zero ValInt.modulo 365 let modulou = error_if_zero ValInt.modulou 366 367 let and_op = binary_int_op ValInt.logand 368 let or_op = binary_int_op ValInt.logor 369 let xor = binary_int_op ValInt.logxor 370 let shl = binary_int_op ValInt.shl 371 let shr = binary_int_op ValInt.shr 372 let shru = binary_int_op ValInt.shrl 373 374 let ext sh v n m = 375 let real_size = D.int_size * 8 in 376 let int_sh sh v n = sh v (of_int n) in 377 if n >= m then 378 if m = real_size then v 379 else modulou v (shl one (of_int m)) 380 else 381 let v = int_sh shl v (real_size - n) in 382 let v = int_sh sh v (m - n) in 383 int_sh shru v (real_size - m) 384 385 let zero_ext = ext shru 386 let sign_ext = ext shr 387 388 let cmp f_int f_off v1 v2 = match v1, v2 with 389 | Val_int i1, Val_int i2 -> of_bool (f_int i1 i2) 390 | Val_ptr (b1, off1), Val_ptr (b2, off2) when ValBlock.eq b1 b2 -> 391 of_bool (f_off off1 off2) 483 392 | _ -> Val_undef 484 393 485 let cmp f_int f_ptr v1 v2 = match v1, v2 with 486 | Val_int i1, Val_int i2 -> of_bool (f_int i1 i2) 487 | Val_ptr (b1, off1), Val_ptr (b2, off2) 488 | Val_ptrh (b1, off1), Val_ptrh (b2, off2) 489 | Val_ptrl (b1, off1), Val_ptrl (b2, off2) when Block.eq b1 b2 -> 490 of_bool (f_ptr off1 off2) 491 | _ -> Val_undef 492 493 let cmp_eq = cmp Int.eq Offset.eq 494 let cmp_ne = cmp Int.neq Offset.neq 495 let cmp_lt = cmp Int.lt Offset.lt 496 let cmp_ge = cmp Int.ge Offset.ge 497 let cmp_le = cmp Int.le Offset.le 498 let cmp_gt = cmp Int.gt Offset.gt 499 500 let cmp_eq_u = cmp Int.eq Offset.eq 501 let cmp_ne_u = cmp Int.neq Offset.neq 502 let cmp_lt_u = cmp Int.ltu Offset.ltu 503 let cmp_ge_u = cmp Int.geu Offset.geu 504 let cmp_le_u = cmp Int.leu Offset.leu 505 let cmp_gt_u = cmp Int.gtu Offset.gtu 506 507 let cmp_eq_f = binary_float_cmp (=) 508 let cmp_ne_f = binary_float_cmp (<>) 509 let cmp_lt_f = binary_float_cmp (<) 510 let cmp_ge_f = binary_float_cmp (>=) 511 let cmp_le_f = binary_float_cmp (<=) 512 let cmp_gt_f = binary_float_cmp (>) 513 514 (** [break v n] cuts [v] in [n] parts. In the resulting list, the first 515 element is the high bits, and the last is the low bits. *) 516 let break v n = match v with 517 (* Parameter [n] is used to generalize the concept of breaking a value into 518 multiple parts. But for now, we only break values in exactly two 519 parts. *) 520 | Val_ptr (b, off) -> 521 begin match Offset.break off 2 with 522 | [off1 ; off2] -> [Val_ptrh (b, off1) ; Val_ptrl (b, off2)] 523 | _ -> assert false (* should be impossible *) end 524 | Val_int i -> List.map (fun i' -> Val_int i') (Int.break i n) 525 | v when n = 1 -> [v] 526 | _ -> MiscPottier.make Val_undef n 527 528 (** [all_are_integers l] returns [true] iff all the values in the list [l] are 394 let cmp_eq = cmp ValInt.eq ValOffset.eq 395 let cmp_ne = cmp ValInt.neq ValOffset.neq 396 let cmp_lt = cmp ValInt.lt ValOffset.lt 397 let cmp_ge = cmp ValInt.ge ValOffset.ge 398 let cmp_le = cmp ValInt.le ValOffset.le 399 let cmp_gt = cmp ValInt.gt ValOffset.gt 400 401 let cmp_eq_u = cmp ValInt.eq ValOffset.eq 402 let cmp_ne_u = cmp ValInt.neq ValOffset.neq 403 let cmp_lt_u = cmp ValInt.ltu ValOffset.ltu 404 let cmp_ge_u = cmp ValInt.geu ValOffset.geu 405 let cmp_le_u = cmp ValInt.leu ValOffset.leu 406 let cmp_gt_u = cmp ValInt.gtu ValOffset.gtu 407 408 409 (* The memory is based on byte values. In order to be able to fit a bigger 410 integer or pointer value in memory, we need to be able to break this value 411 into several values of size a byte. An integer will be broken into multiple 412 8 bits integers. A pointer will be broken into several couples of 8 bits 413 blocks and 8 bits offsets. *) 414 415 (* 8 bits integers *) 416 module IntChunk = IntValue.Int8 417 (* 8 bits blocks *) 418 module BlockChunk = IntValue.Int8 419 (* 8 bits offsets *) 420 module OffsetChunk = IntValue.Int8 421 422 (** A chunk is a part of a value that has the size of a memory cell. *) 423 424 type chunk = 425 | Byte_int of IntChunk.t 426 | Byte_ptr of BlockChunk.t * OffsetChunk.t 427 | Byte_undef 428 429 let string_of_chunk = function 430 | Byte_int i -> IntChunk.to_string i 431 | Byte_ptr (b, off) -> 432 "BPtr(" ^ (BlockChunk.to_string b) ^ ", " ^ 433 (OffsetChunk.to_string off) ^ ")" 434 | Byte_undef -> "Bundef" 435 436 let undef_byte = Byte_undef 437 438 let is_undef_byte = function 439 | Byte_undef -> true 440 | _ -> false 441 442 let break_and_cast break cast x n = 443 let ys = break x n in 444 List.map cast ys 445 446 (** [break v] cuts [v] in chunks that each fits into a memory cell. In the 447 resulting list, the first element is the low bits, and the last is the 448 high bits (little endian representation). *) 449 let break v = 450 let nb_chunks = D.int_size in 451 match v with 452 | Val_ptr (b, off) -> 453 let bbs = break_and_cast ValBlock.break BlockChunk.cast b nb_chunks in 454 let boffs = 455 break_and_cast ValOffset.break OffsetChunk.cast off nb_chunks in 456 List.map2 (fun bb boff -> Byte_ptr (bb, boff)) bbs boffs 457 | Val_int i -> 458 let bis = break_and_cast ValInt.break IntChunk.cast i nb_chunks in 459 List.map (fun i' -> Byte_int i') bis 460 | _ -> MiscPottier.make Byte_undef nb_chunks 461 462 (** [all_are_pointers l] returns [true] iff the values in the list [l] all are 463 pointers. *) 464 let all_are_pointers = 465 let f b v = b && (match v with Byte_ptr _ -> true | _ -> false) in 466 List.fold_left f true 467 468 (** [all_are_integers l] returns [true] iff the values in the list [l] all are 529 469 integers. *) 530 470 let all_are_integers = 531 let f b v = b && (match v with Val_int _ -> true | _ -> false) in471 let f b v = b && (match v with Byte_int _ -> true | _ -> false) in 532 472 List.fold_left f true 533 473 534 (** [integers l] supposes that [l] is a list of integer values. It the returns 535 the (list of) integers. *) 536 let integers = 537 List.map (function 538 | Val_int i -> i 539 | _ -> assert false (* should be impossible *)) 540 541 (** [merge l] creates the value where the first element of [l] is its 542 high bits, etc, and the last element of [l] is its low bits. *) 474 let bblock_of_chunk = function 475 | Byte_ptr (b, _) -> b 476 | _ -> assert false (* do not use on this argument *) 477 478 let boffset_of_chunk = function 479 | Byte_ptr (_, off) -> off 480 | _ -> assert false (* do not use on this argument *) 481 482 let bint_of_chunk = function 483 | Byte_int i -> i 484 | _ -> assert false (* do not use on this argument *) 485 486 let cast_and_merge cast merge transform l = 487 merge (List.map (fun x -> cast (transform x)) l) 488 489 (** [merge l] creates the value where the first element of [l] is its low 490 bits, etc, and the last element of [l] is its high bits (little endian 491 representation). *) 543 492 let merge = function 544 | [v] -> v 545 | [Val_ptrh (b1, off1) ; Val_ptrl (b2, off2)] when Block.eq b1 b2 -> 546 let off = Offset.merge [off1 ; off2] in 547 Val_ptr (b1, off) 548 | l when all_are_integers l -> Val_int (Int.merge (integers l)) 493 | l when all_are_pointers l -> 494 let b = cast_and_merge ValBlock.cast ValBlock.merge bblock_of_chunk l in 495 let off = 496 cast_and_merge ValOffset.cast ValOffset.merge boffset_of_chunk l in 497 Val_ptr (b, off) 498 | l when all_are_integers l -> 499 Val_int (cast_and_merge ValInt.cast ValInt.merge bint_of_chunk l) 549 500 | _ -> Val_undef 550 501 502 503 (** Addresses from the memory point of view. *) 504 505 (** Some architectures have pointers bigger than integers. In this case, only 506 a chunk of pointer can fit into a machine register. Thus, an address is 507 represented by several values (little endian representation). *) 508 509 type address = t list 510 511 let string_of_address vs = 512 "[" ^ (MiscPottier.string_of_list " " to_string vs) ^ "]" 513 514 515 (** Addresses are represented by a block, i.e. a base address, and an offset 516 from this block. Both blocks and offsets are represented using bounded 517 integers. *) 518 519 let ptr_int_size = max (D.ptr_size / D.int_size) 1 520 521 module Block = IntValue.Make (struct let size = D.ptr_size end) 522 module Offset = IntValue.Make (struct let size = D.ptr_size end) 523 524 type mem_address = Block.t * Offset.t 525 526 let is_mem_address = 527 let f b v = b && (match v with | Val_ptr _ -> true | _ -> false) in 528 List.fold_left f true 529 530 let of_mem_address (b, off) = 531 let bs = Block.break b ptr_int_size in 532 let offs = Offset.break off ptr_int_size in 533 let f b off = Val_ptr (ValBlock.cast b, ValOffset.cast off) in 534 List.map2 f bs offs 535 536 let decompose_Val_ptr = function 537 | Val_ptr (b, off) -> (b, off) 538 | _ -> error "Not an address." 539 540 let to_mem_address vs = 541 let (bs, offs) = List.split (List.map decompose_Val_ptr vs) in 542 let b = Block.merge (List.map Block.cast bs) in 543 let off = Offset.merge (List.map Offset.cast offs) in 544 (b, off) 545 546 let make_mem_address b off = (b, off) 547 let decompose_mem_address addr = addr 548 let block_of_address vs = fst (to_mem_address vs) 549 let offset_of_address vs = snd (to_mem_address vs) 550 551 let null = of_mem_address (Block.zero, Offset.zero) 552 553 let change_address_offset vs off = 554 let (b, _) = decompose_mem_address (to_mem_address vs) in 555 of_mem_address (make_mem_address b off) 556 557 let add_address vs off' = 558 let (b, off) = decompose_mem_address (to_mem_address vs) in 559 let off = Offset.add off off' in 560 of_mem_address (make_mem_address b off) 561 562 let eq_address addr1 addr2 = 563 let f b v1 v2 = b && (eq v1 v2) in 564 List.fold_left2 f true addr1 addr2 565 551 566 end -
Deliverables/D2.2/8051/src/common/value.mli
r619 r740 1 1 2 (** This module describes the values manipulated by high level 3 languages. *) 2 (** This module describes the values manipulated by high level languages. *) 4 3 5 4 (** The representation of values depends on the size of integers and the size of … … 14 13 end 15 14 16 (** This is the signature of the module that provides functions and types to15 (** This is the signature of the module that provides types and functions to 17 16 manipulate values. *) 18 17 … … 20 19 sig 21 20 22 (** Addresses are represented by a block, i.e. a base address, and an offset 23 from this block. Both blocks and offsets are represented using bounded 24 integers. *) 25 module Block : IntValue.S 26 module Offset : IntValue.S 27 28 (** The type of values. A value may be: a bounded integer, a float (though 29 they are not fully supported), an address, or undefined. *) 21 (** The type of values. A value may be: a bounded integer, a chunk of an 22 address (exactly an address when they have the same size as a machine 23 register), or undefined. *) 30 24 type t 31 25 … … 43 37 val of_int : int -> t 44 38 45 val is_float : t -> bool 46 val to_float : t -> float 47 val of_float : float -> t 48 39 val of_int_repr : IntValue.int_repr -> t 49 40 val to_int_repr : t -> IntValue.int_repr 50 val of_int_repr : IntValue.int_repr -> t51 52 val is_pointer : t -> bool53 val to_pointer : t -> Block.t * Offset.t54 val of_pointer : Block.t * Offset.t -> t55 41 56 42 val of_bool : bool -> t … … 64 50 val undef : t 65 51 66 67 (** Sign or 0 extensions from various bounded integers. *) 68 val cast8unsigned : t -> t 69 val cast8signed : t -> t 70 val cast16unsigned : t -> t 52 (** The cast operations below returns the undefined value for non-integer 53 values. For integer values, it will return the integer value that 54 represents the same quantity, but using every bits (sign or zero 55 extension) of an integer value. *) 56 val cast8unsigned : t -> t 57 val cast8signed : t -> t 58 val cast16unsigned : t -> t 71 59 val cast16signed : t -> t 72 60 val cast32 : t -> t 73 61 62 (** [zero_ext v n m] performs a zero extension on [v] where [n] bits are 63 significant to a value where [m] bits are significant. *) 64 val zero_ext : t -> int -> int -> t 65 (** [sign_ext v n m] performs a sign extension on [v] where [n] bits are 66 significant to a value where [m] bits are significant. *) 67 val sign_ext : t -> int -> int -> t 68 74 69 (** Integer opposite *) 75 val negint 70 val negint : t -> t 76 71 (** Boolean negation *) 77 val notbool 72 val notbool : t -> t 78 73 (** Bitwise not *) 79 val notint : t -> t 80 val negf : t -> t 81 val absf : t -> t 82 val singleoffloat : t -> t 83 val intoffloat : t -> t 84 val intuoffloat : t -> t 85 val floatofint : t -> t 86 val floatofintu : t -> t 74 val notint : t -> t 87 75 88 val succ 89 val pred 90 val cmpl 76 val succ : t -> t 77 val pred : t -> t 78 val cmpl : t -> t 91 79 92 80 (** [add_and_of v1 v2] returns the sum of [v1] and [v2], and whether this sum … … 97 85 overflows, and [0] otherwise. *) 98 86 val add_of : t -> t -> t 99 (** [sub_and_ of v1 v2] returns the substraction of [v1] and [v2], and whether87 (** [sub_and_uf v1 v2] returns the substraction of [v1] and [v2], and whether 100 88 this substraction underflows. *) 101 89 val sub_and_uf : t -> t -> (t * t) 102 90 val sub : t -> t -> t 103 (** [sub_ of v1 v2] returns the [1] value if the substraction of [v1] and [v2]91 (** [sub_uf v1 v2] returns the [1] value if the substraction of [v1] and [v2] 104 92 underflows, and [0] otherwise. *) 105 93 val sub_uf : t -> t -> t … … 115 103 val shr : t -> t -> t 116 104 val shru : t -> t -> t 117 val addf : t -> t -> t 118 val subf : t -> t -> t 119 val mulf : t -> t -> t 120 val divf : t -> t -> t 105 106 (** Signed comparisions *) 107 val cmp_eq : t -> t -> t 108 val cmp_ne : t -> t -> t 109 val cmp_lt : t -> t -> t 110 val cmp_ge : t -> t -> t 111 val cmp_le : t -> t -> t 112 val cmp_gt : t -> t -> t 121 113 122 114 (** Unsigned comparisions *) 123 val cmp_eq_u : t -> t -> t 124 val cmp_ne_u : t -> t -> t 125 val cmp_lt_u : t -> t -> t 126 val cmp_ge_u : t -> t -> t 127 val cmp_le_u : t -> t -> t 128 val cmp_gt_u : t -> t -> t 115 val cmp_eq_u : t -> t -> t 116 val cmp_ne_u : t -> t -> t 117 val cmp_lt_u : t -> t -> t 118 val cmp_ge_u : t -> t -> t 119 val cmp_le_u : t -> t -> t 120 val cmp_gt_u : t -> t -> t 129 121 130 val cmp_eq_f : t -> t -> t 131 val cmp_ne_f : t -> t -> t 132 val cmp_lt_f : t -> t -> t 133 val cmp_ge_f : t -> t -> t 134 val cmp_le_f : t -> t -> t 135 val cmp_gt_f : t -> t -> t 122 (** A chunk is a part of a value that has the size of a memory cell. *) 136 123 137 val cmp_eq : t -> t -> t 138 val cmp_ne : t -> t -> t 139 val cmp_lt : t -> t -> t 140 val cmp_ge : t -> t -> t 141 val cmp_le : t -> t -> t 142 val cmp_gt : t -> t -> t 124 type chunk 125 val string_of_chunk : chunk -> string 126 val undef_byte : chunk 127 val is_undef_byte : chunk -> bool 143 128 144 (** [break v n] cuts [v] in [n] parts. In the resulting list, the first 145 element is the high bits, and the last is the low bits. *) 146 val break : t -> int -> t list 147 (** [merge l] creates the value where the first element of [l] is its 148 high bits, etc, and the last element of [l] is its low bits. *) 149 val merge : t list -> t 129 (** [break v] cuts [v] in chunks that each fits into a memory cell. In the 130 resulting list, the first element is the low bits, and the last is the 131 high bits (little endian representation). *) 132 val break : t -> chunk list 133 (** [merge l] creates the value where the first element of [l] is its low 134 bits, etc, and the last element of [l] is its high bits (little endian 135 representation). *) 136 val merge : chunk list -> t 137 138 (** Addresses from interpreters point of view. *) 139 140 (** Some architectures have pointers bigger than integers. In this case, only 141 a chunk of pointer can fit into a machine register. Thus, an address is 142 represented by several values (little endian representation). *) 143 144 type address = t list 145 val string_of_address : address -> string 146 val null : address 147 148 (** Addresses from the memory point of view. *) 149 150 (** Addresses are represented by a block, i.e. a base address, and an offset 151 from this block. Both blocks and offsets are represented using bounded 152 integers. *) 153 module Block : IntValue.S 154 module Offset : IntValue.S 155 156 type mem_address 157 158 val is_mem_address : address -> bool 159 160 val of_mem_address : mem_address -> address 161 val to_mem_address : address -> mem_address 162 val make_mem_address : Block.t -> Offset.t -> mem_address 163 val decompose_mem_address : mem_address -> Block.t * Offset.t 164 val block_of_address : address -> Block.t 165 val offset_of_address : address -> Offset.t 166 167 val change_address_offset : address -> Offset.t -> address 168 val add_address : address -> Offset.t -> address 169 val eq_address : address -> address -> bool 150 170 151 171 end
Note: See TracChangeset
for help on using the changeset viewer.