github.com/llir/llvm@v0.3.6/asm/inst.go (about) 1 package asm 2 3 import ( 4 "fmt" 5 6 "github.com/llir/ll/ast" 7 "github.com/llir/llvm/ir" 8 "github.com/pkg/errors" 9 ) 10 11 // === [ Create IR ] =========================================================== 12 13 // newInst returns a new IR instruction (without body but with type) based on 14 // the given AST instruction. 15 func (fgen *funcGen) newInst(old ast.Instruction) (ir.Instruction, error) { 16 switch old := old.(type) { 17 // Value instructions. 18 case *ast.LocalDefInst: 19 ident := localIdent(old.Name()) 20 return fgen.newValueInst(ident, old.Inst()) 21 case ast.ValueInstruction: 22 unnamed := ir.LocalIdent{} 23 return fgen.newValueInst(unnamed, old) 24 // Non-value instructions. 25 case *ast.StoreInst: 26 return &ir.InstStore{}, nil 27 case *ast.FenceInst: 28 return &ir.InstFence{}, nil 29 default: 30 panic(fmt.Errorf("support for AST instruction type %T not yet implemented", old)) 31 } 32 } 33 34 // newValueInst returns a new IR value instruction (without body but with type) 35 // based on the given AST value instruction. 36 func (fgen *funcGen) newValueInst(ident ir.LocalIdent, old ast.ValueInstruction) (ir.Instruction, error) { 37 switch old := old.(type) { 38 // Unary instructions 39 case *ast.FNegInst: 40 return fgen.newFNegInst(ident, old) 41 // Binary instructions 42 case *ast.AddInst: 43 return fgen.newAddInst(ident, old) 44 case *ast.FAddInst: 45 return fgen.newFAddInst(ident, old) 46 case *ast.SubInst: 47 return fgen.newSubInst(ident, old) 48 case *ast.FSubInst: 49 return fgen.newFSubInst(ident, old) 50 case *ast.MulInst: 51 return fgen.newMulInst(ident, old) 52 case *ast.FMulInst: 53 return fgen.newFMulInst(ident, old) 54 case *ast.UDivInst: 55 return fgen.newUDivInst(ident, old) 56 case *ast.SDivInst: 57 return fgen.newSDivInst(ident, old) 58 case *ast.FDivInst: 59 return fgen.newFDivInst(ident, old) 60 case *ast.URemInst: 61 return fgen.newURemInst(ident, old) 62 case *ast.SRemInst: 63 return fgen.newSRemInst(ident, old) 64 case *ast.FRemInst: 65 return fgen.newFRemInst(ident, old) 66 // Bitwise instructions 67 case *ast.ShlInst: 68 return fgen.newShlInst(ident, old) 69 case *ast.LShrInst: 70 return fgen.newLShrInst(ident, old) 71 case *ast.AShrInst: 72 return fgen.newAShrInst(ident, old) 73 case *ast.AndInst: 74 return fgen.newAndInst(ident, old) 75 case *ast.OrInst: 76 return fgen.newOrInst(ident, old) 77 case *ast.XorInst: 78 return fgen.newXorInst(ident, old) 79 // Vector instructions 80 case *ast.ExtractElementInst: 81 return fgen.newExtractElementInst(ident, old) 82 case *ast.InsertElementInst: 83 return fgen.newInsertElementInst(ident, old) 84 case *ast.ShuffleVectorInst: 85 return fgen.newShuffleVectorInst(ident, old) 86 // Aggregate instructions 87 case *ast.ExtractValueInst: 88 return fgen.newExtractValueInst(ident, old) 89 case *ast.InsertValueInst: 90 return fgen.newInsertValueInst(ident, old) 91 // Memory instructions 92 case *ast.AllocaInst: 93 return fgen.newAllocaInst(ident, old) 94 case *ast.LoadInst: 95 return fgen.newLoadInst(ident, old) 96 case *ast.CmpXchgInst: 97 return fgen.newCmpXchgInst(ident, old) 98 case *ast.AtomicRMWInst: 99 return fgen.newAtomicRMWInst(ident, old) 100 case *ast.GetElementPtrInst: 101 return fgen.newGetElementPtrInst(ident, old) 102 // Conversion instructions 103 case *ast.TruncInst: 104 return fgen.newTruncInst(ident, old) 105 case *ast.ZExtInst: 106 return fgen.newZExtInst(ident, old) 107 case *ast.SExtInst: 108 return fgen.newSExtInst(ident, old) 109 case *ast.FPTruncInst: 110 return fgen.newFPTruncInst(ident, old) 111 case *ast.FPExtInst: 112 return fgen.newFPExtInst(ident, old) 113 case *ast.FPToUIInst: 114 return fgen.newFPToUIInst(ident, old) 115 case *ast.FPToSIInst: 116 return fgen.newFPToSIInst(ident, old) 117 case *ast.UIToFPInst: 118 return fgen.newUIToFPInst(ident, old) 119 case *ast.SIToFPInst: 120 return fgen.newSIToFPInst(ident, old) 121 case *ast.PtrToIntInst: 122 return fgen.newPtrToIntInst(ident, old) 123 case *ast.IntToPtrInst: 124 return fgen.newIntToPtrInst(ident, old) 125 case *ast.BitCastInst: 126 return fgen.newBitCastInst(ident, old) 127 case *ast.AddrSpaceCastInst: 128 return fgen.newAddrSpaceCastInst(ident, old) 129 // Other instructions 130 case *ast.ICmpInst: 131 return fgen.newICmpInst(ident, old) 132 case *ast.FCmpInst: 133 return fgen.newFCmpInst(ident, old) 134 case *ast.PhiInst: 135 return fgen.newPhiInst(ident, old) 136 case *ast.SelectInst: 137 return fgen.newSelectInst(ident, old) 138 case *ast.FreezeInst: 139 return fgen.newFreezeInst(ident, old) 140 case *ast.CallInst: 141 return fgen.newCallInst(ident, old) 142 case *ast.VAArgInst: 143 return fgen.newVAArgInst(ident, old) 144 case *ast.LandingPadInst: 145 return fgen.newLandingPadInst(ident, old) 146 case *ast.CatchPadInst: 147 // Result type is always token. 148 return &ir.InstCatchPad{LocalIdent: ident}, nil 149 case *ast.CleanupPadInst: 150 // Result type is always token. 151 return &ir.InstCleanupPad{LocalIdent: ident}, nil 152 default: 153 panic(fmt.Errorf("support for AST value instruction type %T not yet implemented", old)) 154 } 155 } 156 157 // === [ Translate AST to IR ] ================================================= 158 159 // translateInsts translates the AST instructions of the given function to IR. 160 func (fgen *funcGen) translateInsts(oldBlocks []ast.BasicBlock) error { 161 for i, oldBlock := range oldBlocks { 162 block := fgen.f.Blocks[i] 163 for j, old := range oldBlock.Insts() { 164 new := block.Insts[j] 165 if err := fgen.irInst(new, old); err != nil { 166 return errors.WithStack(err) 167 } 168 } 169 } 170 return nil 171 } 172 173 // irInst translates the AST instruction into an equivalent IR instruction. 174 func (fgen *funcGen) irInst(new ir.Instruction, old ast.Instruction) error { 175 switch old := old.(type) { 176 // Value instructions. 177 case *ast.LocalDefInst: 178 return fgen.irValueInst(new, old.Inst()) 179 case ast.ValueInstruction: 180 return fgen.irValueInst(new, old) 181 // Non-value instructions. 182 case *ast.StoreInst: 183 return fgen.irStoreInst(new, old) 184 case *ast.FenceInst: 185 return fgen.irFenceInst(new, old) 186 default: 187 panic(fmt.Errorf("support for AST instruction type %T not yet implemented", old)) 188 } 189 } 190 191 // irValueInst translates the AST value instruction into an equivalent IR value 192 // instruction. 193 func (fgen *funcGen) irValueInst(new ir.Instruction, old ast.ValueInstruction) error { 194 switch old := old.(type) { 195 // Unary instructions 196 case *ast.FNegInst: 197 return fgen.irFNegInst(new, old) 198 // Binary instructions 199 case *ast.AddInst: 200 return fgen.irAddInst(new, old) 201 case *ast.FAddInst: 202 return fgen.irFAddInst(new, old) 203 case *ast.SubInst: 204 return fgen.irSubInst(new, old) 205 case *ast.FSubInst: 206 return fgen.irFSubInst(new, old) 207 case *ast.MulInst: 208 return fgen.irMulInst(new, old) 209 case *ast.FMulInst: 210 return fgen.irFMulInst(new, old) 211 case *ast.UDivInst: 212 return fgen.irUDivInst(new, old) 213 case *ast.SDivInst: 214 return fgen.irSDivInst(new, old) 215 case *ast.FDivInst: 216 return fgen.irFDivInst(new, old) 217 case *ast.URemInst: 218 return fgen.irURemInst(new, old) 219 case *ast.SRemInst: 220 return fgen.irSRemInst(new, old) 221 case *ast.FRemInst: 222 return fgen.irFRemInst(new, old) 223 // Bitwise instructions 224 case *ast.ShlInst: 225 return fgen.irShlInst(new, old) 226 case *ast.LShrInst: 227 return fgen.irLShrInst(new, old) 228 case *ast.AShrInst: 229 return fgen.irAShrInst(new, old) 230 case *ast.AndInst: 231 return fgen.irAndInst(new, old) 232 case *ast.OrInst: 233 return fgen.irOrInst(new, old) 234 case *ast.XorInst: 235 return fgen.irXorInst(new, old) 236 // Vector instructions 237 case *ast.ExtractElementInst: 238 return fgen.irExtractElementInst(new, old) 239 case *ast.InsertElementInst: 240 return fgen.irInsertElementInst(new, old) 241 case *ast.ShuffleVectorInst: 242 return fgen.irShuffleVectorInst(new, old) 243 // Aggregate instructions 244 case *ast.ExtractValueInst: 245 return fgen.irExtractValueInst(new, old) 246 case *ast.InsertValueInst: 247 return fgen.irInsertValueInst(new, old) 248 // Memory instructions 249 case *ast.AllocaInst: 250 return fgen.irAllocaInst(new, old) 251 case *ast.LoadInst: 252 return fgen.irLoadInst(new, old) 253 case *ast.CmpXchgInst: 254 return fgen.irCmpXchgInst(new, old) 255 case *ast.AtomicRMWInst: 256 return fgen.irAtomicRMWInst(new, old) 257 case *ast.GetElementPtrInst: 258 return fgen.irGetElementPtrInst(new, old) 259 // Conversion instructions 260 case *ast.TruncInst: 261 return fgen.irTruncInst(new, old) 262 case *ast.ZExtInst: 263 return fgen.irZExtInst(new, old) 264 case *ast.SExtInst: 265 return fgen.irSExtInst(new, old) 266 case *ast.FPTruncInst: 267 return fgen.irFPTruncInst(new, old) 268 case *ast.FPExtInst: 269 return fgen.irFPExtInst(new, old) 270 case *ast.FPToUIInst: 271 return fgen.irFPToUIInst(new, old) 272 case *ast.FPToSIInst: 273 return fgen.irFPToSIInst(new, old) 274 case *ast.UIToFPInst: 275 return fgen.irUIToFPInst(new, old) 276 case *ast.SIToFPInst: 277 return fgen.irSIToFPInst(new, old) 278 case *ast.PtrToIntInst: 279 return fgen.irPtrToIntInst(new, old) 280 case *ast.IntToPtrInst: 281 return fgen.irIntToPtrInst(new, old) 282 case *ast.BitCastInst: 283 return fgen.irBitCastInst(new, old) 284 case *ast.AddrSpaceCastInst: 285 return fgen.irAddrSpaceCastInst(new, old) 286 // Other instructions 287 case *ast.ICmpInst: 288 return fgen.irICmpInst(new, old) 289 case *ast.FCmpInst: 290 return fgen.irFCmpInst(new, old) 291 case *ast.PhiInst: 292 return fgen.irPhiInst(new, old) 293 case *ast.SelectInst: 294 return fgen.irSelectInst(new, old) 295 case *ast.FreezeInst: 296 return fgen.irFreezeInst(new, old) 297 case *ast.CallInst: 298 return fgen.irCallInst(new, old) 299 case *ast.VAArgInst: 300 return fgen.irVAArgInst(new, old) 301 case *ast.LandingPadInst: 302 return fgen.irLandingPadInst(new, old) 303 case *ast.CatchPadInst: 304 return fgen.irCatchPadInst(new, old) 305 case *ast.CleanupPadInst: 306 return fgen.irCleanupPadInst(new, old) 307 default: 308 panic(fmt.Errorf("support for AST value instruction type %T not yet implemented", old)) 309 } 310 }