File: amd64-opcodes.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (105 lines) | stat: -rw-r--r-- 3,838 bytes parent folder | download
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
(* amd64-opcodes.sml
 *
 * COPYRIGHT (c) 2018 The Fellowship of SML/NJ (http://www.smlnj.org)
 * All rights reserved.
 *
 * This functor converts from types of instructions, e.g. addition, and  their
 * bit widths to AMD64 instructions.
 *)

functor AMD64Opcodes (structure I : AMD64INSTR) =
  struct

    type opcodes = {INC : I.unaryOp, DEC : I.unaryOp, NOT : I.unaryOp,
                    NEG : I.unaryOp,
                    ADD : I.binaryOp, SUB : I.binaryOp, IMUL : I.binaryOp,
                    SHL : I.binaryOp, SHR : I.binaryOp, SAR : I.binaryOp,
                    OR : I.binaryOp, AND : I.binaryOp, XOR : I.binaryOp,
                    CMP : {lsrc:I.operand, rsrc:I.operand} -> I.instr,
                    MOV : I.move}
    val opcodes8 = {INC=I.INCB,DEC=I.DECB,
                    NOT=I.NOTB,NEG=I.NEGB,
                    ADD=I.ADDB,SUB=I.SUBB,IMUL=I.IMULB,
                    SHR=I.SHRB,SAR=I.SARB,SHL=I.SHLB,
                    OR=I.ORB,AND=I.ANDB,XOR=I.XORB,
	 	    CMP=I.CMPB,MOV=I.MOVB}
    val opcodes16 = {INC=I.INCW,DEC=I.DECW,ADD=I.ADDW,SUB=I.SUBW,
                     NOT=I.NOTW,NEG=I.NEGW,
                     SHL=I.SHLW,SHR=I.SHRW,SAR=I.SARW,
                     OR=I.ORW,AND=I.ANDW,XOR=I.XORW,
	  	     IMUL=I.IMULW,
		     CMP=I.CMPW,MOV=I.MOVW}
    val opcodes32 = {INC=I.INCL,DEC=I.DECL,ADD=I.ADDL,SUB=I.SUBL,
                     NOT=I.NOTL,NEG=I.NEGL,
                     SHL=I.SHLL,SHR=I.SHRL,SAR=I.SARL,
                     OR=I.ORL,AND=I.ANDL,XOR=I.XORL,
		     IMUL=I.IMULL,
		     CMP=I.CMPL, MOV=I.MOVL}
    val opcodes64 = {INC=I.INCQ,DEC=I.DECQ,ADD=I.ADDQ,SUB=I.SUBQ,
                     NOT=I.NOTQ,NEG=I.NEGQ,
                     SHL=I.SHLQ,SHR=I.SHRQ,SAR=I.SARQ,
                     OR=I.ORQ,AND=I.ANDQ,XOR=I.XORQ,
		     IMUL=I.IMULQ,
		     CMP=I.CMPQ, MOV=I.MOVQ}

    fun opcodes ty = (case ty
	of 8 => opcodes8
         | 16 => opcodes16
         | 32 => opcodes32
	 | 64 => opcodes64
	 | _  => opcodes64
	(* end case *))

    fun opC opc ty = opc (opcodes ty)

    val notOp = opC #NOT val incOp = opC #INC val decOp = opC #DEC
    val addOp = opC #ADD val subOp = opC #SUB val notOp = opC #NOT
    val negOp = opC #NEG val shlOp = opC #SHL val shrOp = opC #SHR
    val sarOp = opC #SAR val orOp  = opC #OR  val andOp = opC #AND
    val xorOp = opC #XOR val movOp = opC #MOV val cmpOp = opC #CMP
    val imulOp = opC #IMUL
    fun div1Op 32 = I.DIVL1
      | div1Op 64 = I.DIVQ1
    fun idiv1Op 32 = I.IDIVL1
      | idiv1Op 64 = I.IDIVQ1
    fun mul1Op 32 = I.MULL1
      | mul1Op 64 = I.MULQ1
    fun imul1Op 32 = I.IMULL1
      | imul1Op 64 = I.IMULQ1
    val divOp = div1Op
    val idivOp = idiv1Op

   (* fromTy, toTy *)
    fun loadZXOp (8, 32) = I.MOVZBL
      | loadZXOp (16, 32) = I.MOVZWL
      | loadZXOp (8, 64) = I.MOVZBQ
      | loadZXOp (16, 64) = I.MOVZWQ
      | loadZXOp (fTy, tTy) = raise Fail ("incompatible "^Int.toString fTy^" "^Int.toString tTy)

   (* fromTy, toTy *)
    fun loadSXOp (8, 64) = I.MOVSBQ
      | loadSXOp (16, 64) = I.MOVSWQ
      | loadSXOp (8, 32) = I.MOVSBL
      | loadSXOp (16, 32) = I.MOVSWL
      | loadSXOp (32, 64) = I.MOVSLQ
      | loadSXOp (fTy, tTy) = raise Fail ("incompatible "^Int.toString fTy^" "^Int.toString tTy)

    val fopcodes32 = {MOV=I.MOVSS, ADD=I.ADDSS, SUB=I.SUBSS,
		      MUL=I.MULSS, DIV=I.DIVSS, UCOM=I.UCOMISS}
    val fopcodes64 = {MOV=I.MOVSD, ADD=I.ADDSD, SUB=I.SUBSD,
                      MUL=I.MULSD, DIV=I.DIVSD, UCOM=I.UCOMISD}

    fun fopC opc ty = let
	val opcodes = (case ty
	    of 32 => fopcodes32
	     | 64 => fopcodes64
	     | _  => fopcodes64
	    (* end case *))
      in
	opc opcodes
      end (* fopC *)

    val fmovOp = fopC #MOV val faddOp = fopC #ADD val fsubOp = fopC #SUB
    val fmulOp = fopC #MUL val fdivOp = fopC #DIV val ucomOp = fopC #UCOM

  end (* AMD64Opcodes *)