1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.nabla.automatic.arithmetic;
18
19 import org.apache.commons.nabla.automatic.analysis.InstructionsTransformer;
20 import org.apache.commons.nabla.automatic.analysis.MethodDifferentiator;
21 import org.apache.commons.nabla.core.DifferentiationException;
22 import org.objectweb.asm.Opcodes;
23 import org.objectweb.asm.tree.AbstractInsnNode;
24 import org.objectweb.asm.tree.InsnList;
25 import org.objectweb.asm.tree.InsnNode;
26 import org.objectweb.asm.tree.VarInsnNode;
27
28 /** Differentiation transformer for DSUB instructions.
29 * <p>This transformer is used when both arguments of DSUB are
30 * expanded differential pairs. It implements the classical
31 * differentiation rules for subtraction.</p>
32 * @see DSubTransformer1
33 * @see DSubTransformer2
34 */
35 public class DSubTransformer12 implements InstructionsTransformer {
36
37 /** Holder for the singleton instance.*/
38 private static class LazyHolder {
39 /** The singleton instance. */
40 private static final InstructionsTransformer INSTANCE = new DSubTransformer12();
41 }
42
43 /** Hidden constructor.
44 */
45 private DSubTransformer12() {
46 }
47
48 /** Get the singleton instance.
49 * <p>We use here the Initialization on Demand Holder idiom.</p>
50 * @return the singleton instance
51 */
52 public static InstructionsTransformer getInstance() {
53 return LazyHolder.INSTANCE;
54 }
55
56 /** {@inheritDoc} */
57 public InsnList getReplacement(final AbstractInsnNode insn,
58 final MethodDifferentiator methodDifferentiator)
59 throws DifferentiationException {
60
61 final int tmp = methodDifferentiator.getTmp(1);
62 final InsnList list = new InsnList();
63
64 // operand stack initial state: a0, a1, b0, b1
65 list.add(new VarInsnNode(Opcodes.DSTORE, tmp)); // => a0, a1, b0
66 list.add(new InsnNode(Opcodes.DUP2_X2)); // => a0, b0, a1, b0
67 list.add(new InsnNode(Opcodes.POP2)); // => a0, b0, a1
68 list.add(new VarInsnNode(Opcodes.DLOAD, tmp)); // => a0, b0, a1, b1
69 list.add(new InsnNode(Opcodes.DSUB)); // => a0, b0, a1-b1
70 list.add(new VarInsnNode(Opcodes.DSTORE, tmp)); // => a0, b0
71 list.add(new InsnNode(Opcodes.DSUB)); // => a0-b0
72 list.add(new VarInsnNode(Opcodes.DLOAD, tmp)); // => a0-b0, a1-b1
73
74 return list;
75
76 }
77
78 }