diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/DivOperationBenchmarkV2.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/DivOperationBenchmarkV2.java new file mode 100644 index 00000000000..3befa9c2105 --- /dev/null +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/DivOperationBenchmarkV2.java @@ -0,0 +1,27 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.vm.operations.v2; + +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.operation.v2.DivOperationV2; + +public class DivOperationBenchmarkV2 extends BinaryOperationBenchmarkV2 { + + @Override + protected Operation.OperationResult invoke(final MessageFrame frame) { + return DivOperationV2.staticOperation(frame, frame.stackDataV2()); + } +} diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/MulOperationBenchmarkV2.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/MulOperationBenchmarkV2.java new file mode 100644 index 00000000000..2969c0397c6 --- /dev/null +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/v2/MulOperationBenchmarkV2.java @@ -0,0 +1,27 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.vm.operations.v2; + +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.operation.v2.MulOperationV2; + +public class MulOperationBenchmarkV2 extends BinaryOperationBenchmarkV2 { + + @Override + protected Operation.OperationResult invoke(final MessageFrame frame) { + return MulOperationV2.staticOperation(frame, frame.stackDataV2()); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/DivOperationV2.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/DivOperationV2.java new file mode 100644 index 00000000000..4a5be57e96b --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/DivOperationV2.java @@ -0,0 +1,82 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.operation.v2; + +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.UInt256; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.operation.Operation; + +/** + * EVM v2 DIV operation using long[] stack representation. + * + *

Delegates to {@link UInt256#div(UInt256)} for the 256-bit unsigned division, reading operands + * directly from and writing the result back to the long[] stack. Division by zero returns zero per + * EVM specification. + */ +public class DivOperationV2 extends AbstractFixedCostOperationV2 { + + private static final Operation.OperationResult DIV_SUCCESS = + new Operation.OperationResult(5, null); + + /** + * Instantiates a new Div operation. + * + * @param gasCalculator the gas calculator + */ + public DivOperationV2(final GasCalculator gasCalculator) { + super(0x04, "DIV", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + } + + @Override + public Operation.OperationResult executeFixedCostOperation( + final MessageFrame frame, final EVM evm) { + return staticOperation(frame, frame.stackDataV2()); + } + + /** + * Performs DIV on the v2 long[] stack. + * + * @param frame the message frame + * @param s the stack data as a long[] array + * @return the operation result + */ + public static Operation.OperationResult staticOperation( + final MessageFrame frame, final long[] s) { + final int top = frame.stackTopV2(); + final int a = (top - 1) * 4; + final int b = (top - 2) * 4; + + if (s[b] == 0L && s[b + 1] == 0L && s[b + 2] == 0L && s[b + 3] == 0L) { + s[b] = 0L; + s[b + 1] = 0L; + s[b + 2] = 0L; + s[b + 3] = 0L; + } else { + final UInt256 val0 = new UInt256(s[a], s[a + 1], s[a + 2], s[a + 3]); + final UInt256 val1 = new UInt256(s[b], s[b + 1], s[b + 2], s[b + 3]); + final UInt256 result = val0.div(val1); + + s[b] = result.u3(); + s[b + 1] = result.u2(); + s[b + 2] = result.u1(); + s[b + 3] = result.u0(); + } + + frame.setTopV2(top - 1); + return DIV_SUCCESS; + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/MulOperationV2.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/MulOperationV2.java new file mode 100644 index 00000000000..67a61c940f3 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/v2/MulOperationV2.java @@ -0,0 +1,74 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.operation.v2; + +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.UInt256; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.operation.Operation; + +/** + * EVM v2 MUL operation using long[] stack representation. + * + *

Delegates to {@link UInt256#mul(UInt256)} for the 256-bit multiplication, reading operands + * directly from and writing the result back to the long[] stack. + */ +public class MulOperationV2 extends AbstractFixedCostOperationV2 { + + private static final Operation.OperationResult MUL_SUCCESS = + new Operation.OperationResult(5, null); + + /** + * Instantiates a new Mul operation. + * + * @param gasCalculator the gas calculator + */ + public MulOperationV2(final GasCalculator gasCalculator) { + super(0x02, "MUL", 2, 1, gasCalculator, gasCalculator.getLowTierGasCost()); + } + + @Override + public Operation.OperationResult executeFixedCostOperation( + final MessageFrame frame, final EVM evm) { + return staticOperation(frame, frame.stackDataV2()); + } + + /** + * Performs MUL on the v2 long[] stack. + * + * @param frame the message frame + * @param s the stack data as a long[] array + * @return the operation result + */ + public static Operation.OperationResult staticOperation( + final MessageFrame frame, final long[] s) { + final int top = frame.stackTopV2(); + final int a = (top - 1) * 4; + final int b = (top - 2) * 4; + + final UInt256 val0 = new UInt256(s[a], s[a + 1], s[a + 2], s[a + 3]); + final UInt256 val1 = new UInt256(s[b], s[b + 1], s[b + 2], s[b + 3]); + final UInt256 result = val0.mul(val1); + + s[b] = result.u3(); + s[b + 1] = result.u2(); + s[b + 2] = result.u1(); + s[b + 3] = result.u0(); + + frame.setTopV2(top - 1); + return MUL_SUCCESS; + } +}