JNAsm implementation in progress.
[jnode:svn-mirror.git] / builder / src / builder / org / jnode / jnasm / assembler / x86 / X86Support.java
1 /**
2  * $Id$  
3  */
4 package org.jnode.jnasm.assembler.x86;
5
6 import org.jnode.jnasm.assembler.HardwareSupport;
7 import org.jnode.jnasm.assembler.AssemblerModule;
8 import org.jnode.jnasm.assembler.Instruction;
9 import org.jnode.jnasm.assembler.Assembler;
10 import org.jnode.assembler.x86.X86Assembler;
11 import org.jnode.assembler.x86.X86BinaryAssembler;
12 import org.jnode.assembler.x86.X86Constants;
13 import org.jnode.assembler.Label;
14 import org.jnode.assembler.NativeStream;
15 import org.jnode.vm.x86.X86CpuID;
16
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.ArrayList;
20 import java.util.Map;
21 import java.io.OutputStream;
22 import java.io.IOException;
23
24 /**
25  * @author Levente S\u00e1ntha
26  */
27 public class X86Support extends HardwareSupport {
28     private final List modules;
29     private final List instructions;
30     private final Map labels;
31     private int pass;
32     private final Assembler assembler;
33     private X86Assembler nativeStream;
34
35     public X86Support(Assembler assembler, List instructions, Map labels) {
36         this.modules = new ArrayList();
37         this.assembler = assembler;
38         this.instructions = instructions;
39         this.labels = labels;
40         modules.add(new X86Core(labels));
41         modules.add(assembler.getPseudo());
42     }
43
44     public void assemble() {
45         X86CpuID cpuId = X86CpuID.createID("pentium");
46         nativeStream = new X86BinaryAssembler(cpuId, X86Constants.Mode.CODE32, 0);
47
48         for (int i = 0; i < modules.size(); i++) {
49             ((AssemblerModule) modules.get(i)).setNativeStream(nativeStream);
50         }
51
52         for (Iterator it = instructions.iterator(); it.hasNext();) {
53             Instruction ins = (Instruction) it.next();
54             String label = ins.getLabel();
55             if (label != null) {
56                 if (labels.get(label) != null && pass == 1)
57                     throw new IllegalArgumentException("Label already defined: " + label);
58                 defineLabel(label, nativeStream);
59             }
60             String mnemo = ins.getMnemonic();
61             if (mnemo != null) {
62                 emmit(ins.getMnemonic(), ins.getOperands());
63             }
64         }
65     }
66
67     public void writeTo(OutputStream out) throws IOException{
68         nativeStream.writeTo(out);
69     }
70
71     public void setPass(int pass) {
72         this.pass = pass;
73     }
74
75     private void defineLabel(String label, X86Assembler asm) {
76         try {
77             Label lab = new Label(label);
78             labels.put(label, lab);
79             NativeStream.ObjectRef ref = asm.setObjectRef(lab);
80             assembler.putConstant(label, ref.getOffset());
81         } catch (Exception e) {
82             e.printStackTrace();
83         }
84     }
85
86     private void emmit(String mnemonic, List operands) {
87         for (int i = 0; i < modules.size(); i++) {
88             if (((AssemblerModule) modules.get(i)).emmit(mnemonic, operands)) {
89                 return;
90             }
91         }
92
93         if (Assembler.THROW) {
94             throw new RuntimeException("Unknown instruction: " + mnemonic);
95         } else {
96             System.err.println("Unknown instruction: " + mnemonic);
97         }
98     }
99 }