1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.nabla.forward.arithmetic;
18
19 import org.apache.commons.nabla.DifferentiationException;
20 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
21 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
22 import org.objectweb.asm.Opcodes;
23 import org.objectweb.asm.Type;
24 import org.objectweb.asm.tree.AbstractInsnNode;
25 import org.objectweb.asm.tree.InsnList;
26 import org.objectweb.asm.tree.InsnNode;
27 import org.objectweb.asm.tree.MethodInsnNode;
28
29
30
31
32 public class DDivTransformer implements InstructionsTransformer {
33
34
35 private static final String DIVIDE_METHOD = "divide";
36
37
38 private static final String RECIPROCAL_METHOD = "reciprocal";
39
40
41 private static final String MULTIPLY_METHOD = "multiply";
42
43
44 private final boolean stack0Converted;
45
46
47 private final boolean stack1Converted;
48
49
50
51
52
53 public DDivTransformer(final boolean stack0Converted, final boolean stack1Converted) {
54 this.stack0Converted = stack0Converted;
55 this.stack1Converted = stack1Converted;
56 }
57
58
59 public InsnList getReplacement(final AbstractInsnNode insn,
60 final MethodDifferentiator methodDifferentiator)
61 throws DifferentiationException {
62
63 final InsnList list = new InsnList();
64
65 if (stack1Converted) {
66 if (stack0Converted) {
67 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
68 DIVIDE_METHOD,
69 Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
70 } else {
71 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
72 DIVIDE_METHOD,
73 Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
74 }
75 } else {
76 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
77 RECIPROCAL_METHOD,
78 Type.getMethodDescriptor(DS_TYPE)));
79 list.add(new InsnNode(Opcodes.DUP_X2));
80 list.add(new InsnNode(Opcodes.POP));
81 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
82 MULTIPLY_METHOD,
83 Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
84 }
85
86 return list;
87
88 }
89
90 }