Version 2.17.0-190.0.dev

Merge commit '86ab89ee50b45d92c898d33e68fc25180a09d25a' into 'dev'
diff --git a/DEPS b/DEPS
index 3da1ec8..bf5df69 100644
--- a/DEPS
+++ b/DEPS
@@ -110,7 +110,7 @@
   "dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea",
 
   "dartdoc_rev" : "a39f378f8100b907e6285ac825967d764fd664ad",
-  "devtools_rev" : "b9f2039239cc72ac8b26f8a5fe46123f34d53ce1",
+  "devtools_rev" : "65c40d3f6b3dd03411cb8f4b0c0b1ecaa9148f26",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
   "fixnum_rev": "848341f061359ef7ddc0cad472c2ecbb036b28ac",
   "file_rev": "1ebc38852ffed24b564910317982298b56c2cedd",
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/dart_snippet_producers.dart b/pkg/analysis_server/lib/src/services/snippets/dart/dart_snippet_producers.dart
new file mode 100644
index 0000000..d066ac5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/dart_snippet_producers.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/lint/linter.dart' show LinterContextImpl;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+
+/// Produces a [Snippet] that creates a top-level `main` function.
+///
+/// A `List<String> args` parameter will be included when generating inside a
+/// file in `bin` or `tool` folders.
+class DartMainFunctionSnippetProducer extends DartSnippetProducer {
+  static const prefix = 'main';
+  static const label = 'main()';
+
+  DartMainFunctionSnippetProducer(DartSnippetRequest request) : super(request);
+
+  /// Whether to insert a `List<String> args` parameter in the generated
+  /// function.
+  ///
+  /// The parameter is suppressed for any known test directories.
+  bool get _insertArgsParameter {
+    final path = request.unit.path;
+    return !LinterContextImpl.testDirectories
+        .any((testDir) => path.contains(testDir));
+  }
+
+  @override
+  Future<Snippet> compute() async {
+    final builder = ChangeBuilder(session: request.analysisSession);
+
+    final typeProvider = request.unit.typeProvider;
+    final listString = typeProvider.listType(typeProvider.stringType);
+
+    await builder.addDartFileEdit(request.filePath, (builder) {
+      builder.addReplacement(request.replacementRange, (builder) {
+        builder.writeFunctionDeclaration(
+          'main',
+          returnType: VoidTypeImpl.instance,
+          parameterWriter: _insertArgsParameter
+              ? () => builder.writeParameter('args', type: listString)
+              : null,
+          bodyWriter: () {
+            builder.writeln('{');
+            builder.write('  ');
+            builder.selectHere();
+            builder.writeln();
+            builder.write('}');
+          },
+        );
+      });
+    });
+
+    return Snippet(
+      prefix,
+      label,
+      'Insert a main function, used as an entry point.',
+      builder.sourceChange,
+    );
+  }
+
+  static DartMainFunctionSnippetProducer newInstance(
+          DartSnippetRequest request) =>
+      DartMainFunctionSnippetProducer(request);
+}
+
+abstract class DartSnippetProducer extends SnippetProducer {
+  final AnalysisSessionHelper sessionHelper;
+
+  DartSnippetProducer(DartSnippetRequest request)
+      : sessionHelper = AnalysisSessionHelper(request.analysisSession),
+        super(request);
+}
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
index 1a6a9ec..9792d8e 100644
--- a/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/flutter_snippet_producers.dart
@@ -2,25 +2,22 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
 import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
 import 'package:analysis_server/src/utilities/flutter.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:meta/meta.dart';
 
-abstract class FlutterSnippetProducer extends SnippetProducer {
+abstract class FlutterSnippetProducer extends DartSnippetProducer {
   final flutter = Flutter.instance;
-  final AnalysisSessionHelper sessionHelper;
 
   late ClassElement? classWidget;
 
-  FlutterSnippetProducer(DartSnippetRequest request)
-      : sessionHelper = AnalysisSessionHelper(request.analysisSession),
-        super(request);
+  FlutterSnippetProducer(DartSnippetRequest request) : super(request);
 
   @override
   @mustCallSuper
@@ -152,7 +149,7 @@
     return Snippet(
       prefix,
       label,
-      'Insert a StatefulWidget',
+      'Insert a Flutter StatefulWidget.',
       builder.sourceChange,
     );
   }
@@ -333,7 +330,7 @@
     return Snippet(
       prefix,
       label,
-      'Insert a StatefulWidget with an AnimationController',
+      'Insert a Flutter StatefulWidget with an AnimationController.',
       builder.sourceChange,
     );
   }
@@ -446,7 +443,7 @@
     return Snippet(
       prefix,
       label,
-      'Insert a StatelessWidget',
+      'Insert a Flutter StatelessWidget.',
       builder.sourceChange,
     );
   }
diff --git a/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart b/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
index 34dc40b..5c6d87d 100644
--- a/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
+++ b/pkg/analysis_server/lib/src/services/snippets/dart/snippet_manager.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
 import 'package:analysis_server/src/services/snippets/dart/flutter_snippet_producers.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
@@ -23,6 +24,7 @@
   final producerGenerators =
       const <SnippetContext, List<SnippetProducerGenerator>>{
     SnippetContext.atTopLevel: [
+      DartMainFunctionSnippetProducer.newInstance,
       FlutterStatefulWidgetSnippetProducer.newInstance,
       FlutterStatefulWidgetWithAnimationControllerSnippetProducer.newInstance,
       FlutterStatelessWidgetSnippetProducer.newInstance,
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 7da4b3c..51d5c28 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -34,9 +34,10 @@
     return _analysisContextCollection!.contexts.map((e) => e.driver).toList();
   }
 
-  /// The file system specific `/home/test/analysis_options.yaml` path.
+  /// The file system specific path for `analysis_options.yaml` in
+  /// [testPackageRootPath].
   String get analysisOptionsPath =>
-      convertPath('/home/test/analysis_options.yaml');
+      convertPath('$testPackageRootPath/analysis_options.yaml');
 
   List<String> get collectionIncludedPaths => [workspaceRootPath];
 
@@ -62,7 +63,7 @@
 
   Folder get sdkRoot => newFolder('/sdk');
 
-  AnalysisSession get session => contextFor('/home/test').currentSession;
+  AnalysisSession get session => contextFor(testPackageRootPath).currentSession;
 
   String? get testPackageLanguageVersion => latestLanguageVersion;
 
@@ -72,8 +73,9 @@
 
   String get testPackageTestPath => '$testPackageRootPath/test';
 
-  /// The file system specific `/home/test/pubspec.yaml` path.
-  String get testPubspecPath => convertPath('/home/test/pubspec.yaml');
+  /// The file system specific path for `pubspec.yaml` in [testPackageRootPath].
+  String get testPubspecPath =>
+      convertPath('$testPackageRootPath/pubspec.yaml');
 
   String get workspaceRootPath => '/home';
 
@@ -197,7 +199,7 @@
     AnalysisEngine.instance.clearCaches();
   }
 
-  /// Update `/home/test/pubspec.yaml` and create the driver.
+  /// Update `pubspec.yaml` and create the driver.
   void updateTestPubspecFile(String content) {
     newFile(testPubspecPath, content: content);
   }
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 1b9520b..3e0b30e 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
 import 'package:analysis_server/src/services/snippets/dart/flutter_snippet_producers.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -2408,6 +2409,33 @@
     );
   }
 
+  Future<void> test_snippets_mainFunction() async {
+    final content = '''
+class A {}
+
+main^
+
+class B {}
+''';
+
+    await initializeWithSnippetSupportAndPreviewFlag();
+    final updated = await expectAndApplySnippet(
+      content,
+      prefix: DartMainFunctionSnippetProducer.prefix,
+      label: DartMainFunctionSnippetProducer.label,
+    );
+
+    expect(updated, r'''
+class A {}
+
+void main(List<String> args) {
+  $0
+}
+
+class B {}
+''');
+  }
+
   Future<void> test_snippets_notSupported() async {
     final content = '^';
 
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index f2d2833..f9f3c7d 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -203,7 +203,7 @@
         processRunner: processRunner);
     server.pluginManager = pluginManager;
 
-    projectFolderPath = convertPath('/home/test');
+    projectFolderPath = convertPath('/home/my_project');
     projectFolderUri = Uri.file(projectFolderPath);
     newFolder(projectFolderPath);
     newFolder(join(projectFolderPath, 'lib'));
diff --git a/pkg/analysis_server/test/services/snippets/dart/dart_snippet_producers_test.dart b/pkg/analysis_server/test/services/snippets/dart/dart_snippet_producers_test.dart
new file mode 100644
index 0000000..ac446c3
--- /dev/null
+++ b/pkg/analysis_server/test/services/snippets/dart/dart_snippet_producers_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
+import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../abstract_single_unit.dart';
+import 'test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DartMainFunctionSnippetProducerTest);
+  });
+}
+
+@reflectiveTest
+class DartMainFunctionSnippetProducerTest extends DartSnippetProducerTest {
+  @override
+  final generator = DartMainFunctionSnippetProducer.newInstance;
+
+  @override
+  String get label => DartMainFunctionSnippetProducer.label;
+
+  @override
+  String get prefix => DartMainFunctionSnippetProducer.prefix;
+
+  Future<void> test_noParams_testFolder() => testInFile(
+        convertPath('$testPackageLibPath/test/foo_test.dart'),
+        expectArgsParameter: false,
+      );
+
+  Future<void> test_params_binFolder() => testInFile(
+        convertPath('$testPackageLibPath/bin/main.dart'),
+        expectArgsParameter: true,
+      );
+
+  Future<void> test_params_projectRoot() => testInFile(
+        convertPath('$testPackageRootPath/foo.dart'),
+        expectArgsParameter: true,
+      );
+
+  Future<void> test_params_toolFolder() => testInFile(
+        convertPath('$testPackageLibPath/tool/tool.dart'),
+        expectArgsParameter: true,
+      );
+
+  Future<void> test_typedPrefix() => testInFile(
+        testFile,
+        code: '$prefix^',
+        expectArgsParameter: true,
+      );
+
+  Future<void> testInFile(
+    String file, {
+    String code = '^',
+    required bool expectArgsParameter,
+  }) async {
+    testFile = file;
+    final snippet = await expectValidSnippet(code);
+    expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
+    expect(snippet.change.edits, hasLength(1));
+    code = withoutMarkers(code);
+    snippet.change.edits
+        .forEach((edit) => code = SourceEdit.applySequence(code, edit.edits));
+    final expectedParams = expectArgsParameter ? 'List<String> args' : '';
+    expect(code, '''
+void main($expectedParams) {
+  
+}''');
+    expect(snippet.change.selection!.file, file);
+    expect(snippet.change.selection!.offset, 16 + expectedParams.length);
+    expect(snippet.change.linkedEditGroups, isEmpty);
+  }
+}
+
+abstract class DartSnippetProducerTest extends AbstractSingleUnitTest {
+  SnippetProducerGenerator get generator;
+  String get label;
+  String get prefix;
+
+  /// Override the package root because it usually contains /test/ and some
+  /// snippets behave differently for test files.
+  @override
+  String get testPackageRootPath => '$workspaceRootPath/my_package';
+
+  @override
+  bool get verifyNoTestUnitErrors => false;
+
+  Future<void> expectNotValidSnippet(
+    String code,
+  ) async {
+    await resolveTestCode(withoutMarkers(code));
+    final request = DartSnippetRequest(
+      unit: testAnalysisResult,
+      offset: offsetFromMarker(code),
+    );
+
+    final producer = generator(request);
+    expect(await producer.isValid(), isFalse);
+  }
+
+  Future<Snippet> expectValidSnippet(String code) async {
+    await resolveTestCode(withoutMarkers(code));
+    final request = DartSnippetRequest(
+      unit: testAnalysisResult,
+      offset: offsetFromMarker(code),
+    );
+
+    final producer = generator(request);
+    expect(await producer.isValid(), isTrue);
+    return producer.compute();
+  }
+}
diff --git a/pkg/analysis_server/test/services/snippets/dart/flutter_snippet_producers_test.dart b/pkg/analysis_server/test/services/snippets/dart/flutter_snippet_producers_test.dart
index 6edf13b..d082f0b 100644
--- a/pkg/analysis_server/test/services/snippets/dart/flutter_snippet_producers_test.dart
+++ b/pkg/analysis_server/test/services/snippets/dart/flutter_snippet_producers_test.dart
@@ -4,12 +4,10 @@
 
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/snippets/dart/flutter_snippet_producers.dart';
-import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../abstract_single_unit.dart';
-import 'test_support.dart';
+import 'dart_snippet_producers_test.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -20,39 +18,7 @@
   });
 }
 
-abstract class FlutterSnippetProducerTest extends AbstractSingleUnitTest {
-  SnippetProducerGenerator get generator;
-  String get label;
-  String get prefix;
-
-  @override
-  bool get verifyNoTestUnitErrors => false;
-
-  Future<void> expectNotValidSnippet(
-    String code,
-  ) async {
-    await resolveTestCode(withoutMarkers(code));
-    final request = DartSnippetRequest(
-      unit: testAnalysisResult,
-      offset: offsetFromMarker(code),
-    );
-
-    final producer = generator(request);
-    expect(await producer.isValid(), isFalse);
-  }
-
-  Future<Snippet> expectValidSnippet(String code) async {
-    await resolveTestCode(withoutMarkers(code));
-    final request = DartSnippetRequest(
-      unit: testAnalysisResult,
-      offset: offsetFromMarker(code),
-    );
-
-    final producer = generator(request);
-    expect(await producer.isValid(), isTrue);
-    return producer.compute();
-  }
-
+abstract class FlutterSnippetProducerTest extends DartSnippetProducerTest {
   /// Checks snippets can produce edits where the imports and snippet will be
   /// inserted at the same location.
   ///
@@ -64,6 +30,7 @@
 
     final snippet = await expectValidSnippet('$prefix^');
     expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
 
     // Main edits replace $prefix.length characters starting at $prefix
     final mainEdit = snippet.change.edits[0].edits[0];
@@ -85,6 +52,7 @@
 $prefix^
 ''');
     expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
 
     // Main edits replace $prefix.length characters starting at $prefix
     final mainEdit = snippet.change.edits[0].edits[0];
@@ -120,8 +88,8 @@
     writeTestPackageConfig(flutter: true);
 
     final snippet = await expectValidSnippet('^');
-    expect(snippet.prefix, 'stful');
-    expect(snippet.label, 'Flutter Stateful Widget');
+    expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
     var code = '';
     expect(snippet.change.edits, hasLength(1));
     snippet.change.edits
@@ -187,8 +155,8 @@
     writeTestPackageConfig(flutter: true);
 
     final snippet = await expectValidSnippet('^');
-    expect(snippet.prefix, 'stanim');
-    expect(snippet.label, 'Flutter Widget with AnimationController');
+    expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
     var code = '';
     expect(snippet.change.edits, hasLength(1));
     snippet.change.edits
@@ -268,8 +236,8 @@
     writeTestPackageConfig(flutter: true);
 
     final snippet = await expectValidSnippet('^');
-    expect(snippet.prefix, 'stless');
-    expect(snippet.label, 'Flutter Stateless Widget');
+    expect(snippet.prefix, prefix);
+    expect(snippet.label, label);
     var code = '';
     expect(snippet.change.edits, hasLength(1));
     snippet.change.edits
diff --git a/pkg/analysis_server/test/services/snippets/dart/test_all.dart b/pkg/analysis_server/test/services/snippets/dart/test_all.dart
index 907e05a..5686247 100644
--- a/pkg/analysis_server/test/services/snippets/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/snippets/dart/test_all.dart
@@ -4,12 +4,14 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'dart_snippet_producers_test.dart' as dart_snippet_producers;
 import 'flutter_snippet_producers_test.dart' as flutter_snippet_producers;
 import 'snippet_manager_test.dart' as snippet_manager;
 import 'snippet_request_test.dart' as snippet_request;
 
 void main() {
   defineReflectiveSuite(() {
+    dart_snippet_producers.main();
     flutter_snippet_producers.main();
     snippet_manager.main();
     snippet_request.main();
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 542e9ec..2e07c8a 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -280,7 +280,7 @@
 
 /// Implementation of [LinterContext]
 class LinterContextImpl implements LinterContext {
-  static final _testDirectories = [
+  static final testDirectories = [
     '${p.separator}test${p.separator}',
     '${p.separator}integration_test${p.separator}',
     '${p.separator}test_driver${p.separator}',
@@ -393,7 +393,7 @@
   @override
   bool inTestDir(CompilationUnit unit) {
     var path = unit.declaredElement?.source.fullName;
-    return path != null && _testDirectories.any(path.contains);
+    return path != null && testDirectories.any(path.contains);
   }
 
   @override
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index eb5cacc..eb0477e 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -223,7 +223,7 @@
 }
 
 void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  // static void _rsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
   // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
diff --git a/runtime/vm/compiler/asm_intrinsifier_riscv.cc b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
index c96447f..5623b79 100644
--- a/runtime/vm/compiler/asm_intrinsifier_riscv.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
@@ -156,49 +156,749 @@
 }
 
 void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // static void _lsh(Uint32List src_digits, int src_used,
+  //                  int shift_amount,
+  //                  Uint32List result_digits)
+
+  Label loop, done;
+  __ lx(T0, Address(SP, 3 * target::kWordSize));  // src_digits
+  __ lx(T1, Address(SP, 2 * target::kWordSize));  // src_used
+  __ lx(T2, Address(SP, 1 * target::kWordSize));  // shift_amount
+  __ lx(T3, Address(SP, 0 * target::kWordSize));  // result_digits
+
+#if XLEN == 32
+  // 1 word = 1 digit
+  __ SmiUntag(T1);
+#else
+  // 1 word = 2 digits
+  __ addi(T1, T1, target::ToRawSmi(1));  // Round up to even
+  __ srai(T1, T1, kSmiTagSize + 1);
+#endif
+  __ SmiUntag(T2);
+
+  __ srai(T4, T2, target::kBitsPerWordLog2);  // T4 = word shift
+  __ andi(T5, T2, target::kBitsPerWord - 1);  // T5 = bit shift
+  __ li(T6, target::kBitsPerWord);
+  __ sub(T6, T6, T5);  // T6 = carry bit shift
+
+  __ slli(TMP, T1, target::kWordSizeLog2);
+  __ add(T0, T0, TMP);
+  __ subi(T0, T0, target::kWordSize);  // T0 = &src_digits[src_used - 1]
+
+  __ add(TMP, T1, T4);
+  __ slli(TMP, TMP, target::kWordSizeLog2);
+  __ add(T3, T3, TMP);  // T3 = &dst_digits[src_used + word_shift]
+
+  __ li(T2, 0);  // carry
+
+  __ Bind(&loop);
+  __ beqz(T1, &done, Assembler::kNearJump);
+  __ lx(TMP, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ srl(TMP2, TMP, T6);
+  __ or_(TMP2, TMP2, T2);
+  __ sx(TMP2, FieldAddress(T3, target::TypedData::payload_offset()));
+  __ sll(T2, TMP, T5);
+  __ subi(T0, T0, target::kWordSize);
+  __ subi(T3, T3, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ j(&loop);
+
+  __ Bind(&done);
+  __ sx(T2, FieldAddress(T3, target::TypedData::payload_offset()));
+  __ LoadObject(A0, NullObject());
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // static void _rsh(Uint32List src_digits, int src_used,
+  //                  int shift_amount,
+  //                  Uint32List result_digits)
+
+  Label loop, done;
+  __ lx(T0, Address(SP, 3 * target::kWordSize));  // src_digits
+  __ lx(T1, Address(SP, 2 * target::kWordSize));  // src_used
+  __ lx(T2, Address(SP, 1 * target::kWordSize));  // shift_amount
+  __ lx(T3, Address(SP, 0 * target::kWordSize));  // result_digits
+
+#if XLEN == 32
+  // 1 word = 1 digit
+  __ SmiUntag(T1);
+#else
+  // 1 word = 2 digits
+  __ addi(T1, T1, target::ToRawSmi(1));  // Round up to even
+  __ srai(T1, T1, kSmiTagSize + 1);
+#endif
+  __ SmiUntag(T2);
+
+  __ srai(T4, T2, target::kBitsPerWordLog2);  // T4 = word shift
+  __ andi(T5, T2, target::kBitsPerWord - 1);  // T5 = bit shift
+  __ li(T6, target::kBitsPerWord);
+  __ sub(T6, T6, T5);  // T6 = carry bit shift
+
+  __ slli(TMP, T4, target::kWordSizeLog2);
+  __ add(T0, T0, TMP);  // T0 = &src_digits[word_shift]
+
+  __ li(T2, 0);  // carry
+  __ lx(T2, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ srl(T2, T2, T5);
+  __ addi(T0, T0, target::kWordSize);
+  __ subi(T1, T1, 1);
+
+  __ Bind(&loop);
+  __ beqz(T1, &done, Assembler::kNearJump);
+  __ lx(TMP, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ sll(TMP2, TMP, T6);
+  __ or_(TMP2, TMP2, T2);
+  __ sx(TMP2, FieldAddress(T3, target::TypedData::payload_offset()));
+  __ srl(T2, TMP, T5);
+  __ addi(T0, T0, target::kWordSize);
+  __ addi(T3, T3, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ j(&loop);
+
+  __ Bind(&done);
+  __ sx(T2, FieldAddress(T3, target::TypedData::payload_offset()));
+  __ LoadObject(A0, NullObject());
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
                                     Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // static void _absAdd(Uint32List longer_digits, int longer_used,
+  //                     Uint32List shorter_digits, int shorter_used,
+  //                     Uint32List result_digits)
+
+  Label first_loop, second_loop, last_carry, done;
+  __ lx(T0, Address(SP, 4 * target::kWordSize));  // longer_digits
+  __ lx(T1, Address(SP, 3 * target::kWordSize));  // longer_used
+  __ lx(T2, Address(SP, 2 * target::kWordSize));  // shorter_digits
+  __ lx(T3, Address(SP, 1 * target::kWordSize));  // shorter_used
+  __ lx(T4, Address(SP, 0 * target::kWordSize));  // result_digits
+
+#if XLEN == 32
+  // 1 word = 1 digit
+  __ SmiUntag(T1);
+  __ SmiUntag(T3);
+#else
+  // 1 word = 2 digits
+  __ addi(T1, T1, target::ToRawSmi(1));  // Round up to even
+  __ srai(T1, T1, kSmiTagSize + 1);
+  __ addi(T3, T3, target::ToRawSmi(1));  // Round up to even
+  __ srai(T3, T3, kSmiTagSize + 1);
+#endif
+  __ li(T5, 0);  // Carry
+
+  __ Bind(&first_loop);
+  __ beqz(T3, &second_loop);
+  __ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ lx(A1, FieldAddress(T2, target::TypedData::payload_offset()));
+  __ add(A0, A0, A1);
+  __ sltu(TMP, A0, A1);  // Carry
+  __ add(A0, A0, T5);
+  __ sltu(TMP2, A0, T5);  // Carry
+  __ add(T5, TMP, TMP2);
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T0, T0, target::kWordSize);
+  __ addi(T2, T2, target::kWordSize);
+  __ addi(T4, T4, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ subi(T3, T3, 1);
+  __ j(&first_loop);
+
+  __ Bind(&second_loop);
+  __ beqz(T1, &last_carry);
+  __ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ add(TMP, A0, T5);
+  __ sltu(T5, TMP, A0);  // Carry
+  __ sx(TMP, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T0, T0, target::kWordSize);
+  __ addi(T4, T4, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ j(&second_loop);
+
+  __ Bind(&last_carry);
+  __ beqz(T5, &done);
+  __ sx(T5, FieldAddress(T4, target::TypedData::payload_offset()));
+
+  __ Bind(&done);
+  __ LoadObject(A0, NullObject());
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
                                     Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // static void _absSub(Uint32List longer_digits, int longer_used,
+  //                     Uint32List shorter_digits, int shorter_used,
+  //                     Uint32List result_digits)
+  Label first_loop, second_loop, last_borrow, done;
+  __ lx(T0, Address(SP, 4 * target::kWordSize));  // longer_digits
+  __ lx(T1, Address(SP, 3 * target::kWordSize));  // longer_used
+  __ lx(T2, Address(SP, 2 * target::kWordSize));  // shorter_digits
+  __ lx(T3, Address(SP, 1 * target::kWordSize));  // shorter_used
+  __ lx(T4, Address(SP, 0 * target::kWordSize));  // result_digits
+
+#if XLEN == 32
+  // 1 word = 1 digit
+  __ SmiUntag(T1);
+  __ SmiUntag(T3);
+#else
+  // 1 word = 2 digits
+  __ addi(T1, T1, target::ToRawSmi(1));  // Round up to even
+  __ srai(T1, T1, kSmiTagSize + 1);
+  __ addi(T3, T3, target::ToRawSmi(1));  // Round up to even
+  __ srai(T3, T3, kSmiTagSize + 1);
+#endif
+  __ li(T5, 0);  // Borrow
+
+  __ Bind(&first_loop);
+  __ beqz(T3, &second_loop);
+  __ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ lx(A1, FieldAddress(T2, target::TypedData::payload_offset()));
+  __ sltu(TMP, A0, A1);  // Borrow
+  __ sub(A0, A0, A1);
+  __ sltu(TMP2, A0, T5);  // Borrow
+  __ sub(A0, A0, T5);
+  __ add(T5, TMP, TMP2);
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T0, T0, target::kWordSize);
+  __ addi(T2, T2, target::kWordSize);
+  __ addi(T4, T4, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ subi(T3, T3, 1);
+  __ j(&first_loop);
+
+  __ Bind(&second_loop);
+  __ beqz(T1, &last_borrow);
+  __ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ sltu(TMP, A0, T5);  // Borrow
+  __ sub(A0, A0, T5);
+  __ mv(T5, TMP);
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T0, T0, target::kWordSize);
+  __ addi(T4, T4, target::kWordSize);
+  __ subi(T1, T1, 1);
+  __ j(&second_loop);
+
+  __ Bind(&last_borrow);
+  __ beqz(T5, &done);
+  __ neg(T5, T5);
+  __ sx(T5, FieldAddress(T4, target::TypedData::payload_offset()));
+
+  __ Bind(&done);
+  __ LoadObject(A0, NullObject());
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
                                     Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // Pseudo code:
+  // static int _mulAdd(Uint32List x_digits, int xi,
+  //                    Uint32List m_digits, int i,
+  //                    Uint32List a_digits, int j, int n) {
+  //   uint64_t x = x_digits[xi >> 1 .. (xi >> 1) + 1];  // xi is Smi and even.
+  //   if (x == 0 || n == 0) {
+  //     return 2;
+  //   }
+  //   uint64_t* mip = &m_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t* ajp = &a_digits[j >> 1];  // j is Smi and even.
+  //   uint64_t c = 0;
+  //   SmiUntag(n);  // n is Smi and even.
+  //   n = (n + 1)/2;  // Number of pairs to process.
+  //   do {
+  //     uint64_t mi = *mip++;
+  //     uint64_t aj = *ajp;
+  //     uint128_t t = x*mi + aj + c;  // 64-bit * 64-bit -> 128-bit.
+  //     *ajp++ = low64(t);
+  //     c = high64(t);
+  //   } while (--n > 0);
+  //   while (c != 0) {
+  //     uint128_t t = *ajp + c;
+  //     *ajp++ = low64(t);
+  //     c = high64(t);  // c == 0 or 1.
+  //   }
+  //   return 2;
+  // }
+
+  Label done;
+  __ lx(T0, Address(SP, 6 * target::kWordSize));  // x_digits
+  __ lx(T1, Address(SP, 5 * target::kWordSize));  // xi
+  __ lx(T2, Address(SP, 4 * target::kWordSize));  // m_digits
+  __ lx(T3, Address(SP, 3 * target::kWordSize));  // i
+  __ lx(T4, Address(SP, 2 * target::kWordSize));  // a_digits
+  __ lx(T5, Address(SP, 1 * target::kWordSize));  // j
+  __ lx(T6, Address(SP, 0 * target::kWordSize));  // n
+
+  // R3 = x, no_op if x == 0
+  // T0 = xi as Smi, R1 = x_digits.
+  __ slli(T1, T1, 1);
+  __ add(T0, T0, T1);
+  __ lx(T0, FieldAddress(T0, target::TypedData::payload_offset()));
+  __ beqz(T0, &done);
+
+  // R6 = (SmiUntag(n) + 1)/2, no_op if n == 0
+#if XLEN == 32
+  // 1 word = 1 digit
+  __ SmiUntag(T6);
+#else
+  // 1 word = 2 digits
+  __ addi(T6, T6, target::ToRawSmi(1));
+  __ srai(T6, T6, 2);
+#endif
+  __ beqz(T6, &done);
+
+  // R4 = mip = &m_digits[i >> 1]
+  // R0 = i as Smi, R1 = m_digits.
+  __ slli(T3, T3, 1);
+  __ add(T2, T2, T3);
+
+  // R5 = ajp = &a_digits[j >> 1]
+  // R0 = j as Smi, R1 = a_digits.
+  __ slli(T5, T5, 1);
+  __ add(T4, T4, T5);
+
+  // T1 = c = 0
+  __ li(T1, 0);
+
+  Label muladd_loop;
+  __ Bind(&muladd_loop);
+  // x:   T0
+  // mip: T2
+  // ajp: T4
+  // c:   T1
+  // n:   T6
+  // t:   A7:A6 (not live at loop entry)
+
+  // uint64_t mi = *mip++
+  __ lx(A0, FieldAddress(T2, target::TypedData::payload_offset()));
+  __ addi(T2, T2, target::kWordSize);
+
+  // uint64_t aj = *ajp
+  __ lx(A1, FieldAddress(T4, target::TypedData::payload_offset()));
+
+  // uint128_t t = x*mi + aj + c
+  // Macro-op fusion: when both products are required, the recommended sequence
+  // is high first.
+  __ mulhu(A7, A0, T0);  // A7 = high64(A0*T0), t = A7:A6 = x*mi.
+  __ mul(A6, A0, T0);    // A6 = low64(A0*T0).
+
+  __ add(A6, A6, A1);
+  __ sltu(TMP, A6, A1);  // Carry
+  __ add(A7, A7, TMP);   // t += aj
+
+  __ add(A6, A6, T1);
+  __ sltu(TMP, A6, T1);  // Carry
+  __ add(A7, A7, TMP);   // t += c
+
+  __ mv(T1, A7);  // c = high64(t)
+
+  // *ajp++ = low64(t) = R0
+  __ sx(A6, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T4, T4, target::kWordSize);
+
+  // while (--n > 0)
+  __ subi(T6, T6, 1);  // --n
+  __ bnez(T6, &muladd_loop);
+
+  __ beqz(T1, &done);
+
+  // *ajp++ += c
+  __ lx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ add(A0, A0, T1);
+  __ sltu(T1, A0, T1);  // Carry
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T4, T4, target::kWordSize);
+  __ beqz(T1, &done);
+
+  Label propagate_carry_loop;
+  __ Bind(&propagate_carry_loop);
+  __ lx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ add(A0, A0, T1);
+  __ sltu(T1, A0, T1);  // Carry
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
+  __ addi(T4, T4, target::kWordSize);
+  __ bnez(T1, &propagate_carry_loop);
+
+  __ Bind(&done);
+  // Result = One or two digits processed.
+  __ li(A0, target::ToRawSmi(target::kWordSize / kBytesPerBigIntDigit));
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
                                     Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // Pseudo code:
+  // static int _sqrAdd(Uint32List x_digits, int i,
+  //                    Uint32List a_digits, int used) {
+  //   uint64_t* xip = &x_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t x = *xip++;
+  //   if (x == 0) return 2;
+  //   uint64_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = x*x + aj;
+  //   *ajp++ = low64(t);
+  //   uint128_t c = high64(t);
+  //   int n = ((used - i + 2) >> 2) - 1;  // used and i are Smi. n: num pairs.
+  //   while (--n >= 0) {
+  //     uint64_t xi = *xip++;
+  //     uint64_t aj = *ajp;
+  //     uint192_t t = 2*x*xi + aj + c;  // 2-bit * 64-bit * 64-bit -> 129-bit.
+  //     *ajp++ = low64(t);
+  //     c = high128(t);  // 65-bit.
+  //   }
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = aj + c;  // 64-bit + 65-bit -> 66-bit.
+  //   *ajp++ = low64(t);
+  //   *ajp = high64(t);
+  //   return 2;
+  // }
+
+  // T2 = xip = &x_digits[i >> 1]
+  // T0 = i as Smi, T1 = x_digits
+  __ lx(T0, Address(SP, 2 * target::kWordSize));
+  __ lx(T1, Address(SP, 3 * target::kWordSize));
+  __ slli(TMP, T0, 1);
+  __ add(T1, T1, TMP);
+  __ addi(T2, T1, target::TypedData::payload_offset() - kHeapObjectTag);
+
+  // T1 = x = *xip++, return if x == 0
+  Label x_zero;
+  __ lx(T1, Address(T2, 0));
+  __ addi(T2, T2, target::kWordSize);
+  __ beqz(T1, &x_zero);
+
+  // T3 = ajp = &a_digits[i]
+  __ lx(A1, Address(SP, 1 * target::kWordSize));  // a_digits
+  __ slli(TMP, T0, 2);
+  __ add(A1, A1, TMP);  // j == 2*i, i is Smi.
+  __ addi(T3, A1, target::TypedData::payload_offset() - kHeapObjectTag);
+
+  // T4:A1 = t = x*x + *ajp
+  __ lx(A0, Address(T3, 0));
+  __ mul(A1, T1, T1);    // A1 = low64(T1*T1).
+  __ mulhu(T4, T1, T1);  // T4 = high64(T1*T1).
+  __ add(A1, A1, A0);    // T4:A1 += *ajp.
+  __ sltu(TMP, A1, A0);
+  __ add(T4, T4, TMP);  // T4 = low64(c) = high64(t).
+  __ li(T5, 0);         // T5 = high64(c) = 0.
+
+  // *ajp++ = low64(t) = A1
+  __ sx(A1, Address(T3, 0));
+  __ addi(T3, T3, target::kWordSize);
+
+  __ lx(A0, Address(SP, 0 * target::kWordSize));  // used is Smi
+#if XLEN == 32
+  // int n = used - i - 2;
+  __ sub(T6, A0, T0);
+  __ SmiUntag(T6);
+  __ subi(T6, T6, 2);
+#else
+  // int n = (used - i + 1)/2 - 1
+  __ sub(T6, A0, T0);
+  __ addi(T6, T6, 2);
+  __ srai(T6, T6, 2);
+  __ subi(T6, T6, 2);
+#endif
+
+  Label loop, done;
+  __ bltz(T6, &done);  // while (--n >= 0)
+
+  __ Bind(&loop);
+  // x:   T1
+  // xip: T2
+  // ajp: T3
+  // c:   T5:T4
+  // t:   T0:A1:A0 (not live at loop entry)
+  // n:   T6
+
+  // uint64_t xi = *xip++
+  __ lx(T0, Address(T2, 0));
+  __ addi(T2, T2, target::kWordSize);
+
+  // uint192_t t = T0:A1:A0 = 2*x*xi + aj + c
+  __ mul(A0, T0, T1);    // A0 = low64(T0*T1) = low64(x*xi).
+  __ mulhu(A1, T0, T1);  // A1 = high64(T0*T1) = high64(x*xi).
+
+  __ mv(TMP, A0);
+  __ add(A0, A0, A0);
+  __ sltu(TMP, A0, TMP);
+  __ mv(TMP2, A1);
+  __ add(A1, A1, A1);
+  __ sltu(TMP2, A1, TMP2);
+  __ add(A1, A1, TMP);
+  __ sltu(TMP, A1, TMP);
+  __ add(T0, TMP, TMP2);  // T0:A1:A0 = A1:A0 + A1:A0 = 2*x*xi.
+
+  __ add(A0, A0, T4);
+  __ sltu(TMP, A0, T4);
+  __ add(A1, A1, T5);
+  __ sltu(TMP2, A1, T5);
+  __ add(A1, A1, TMP);
+  __ sltu(TMP, A1, TMP);
+  __ add(T0, T0, TMP);
+  __ add(T0, T0, TMP2);  // T0:A1:A0 += c.
+
+  __ lx(T5, Address(T3, 0));  // T5 = aj = *ajp.
+  __ add(A0, A0, T5);
+  __ sltu(TMP, A0, T5);
+  __ add(T4, A1, TMP);
+  __ sltu(TMP, T4, A1);
+  __ add(T5, T0, TMP);  // T5:T4:A0 = 2*x*xi + aj + c.
+
+  // *ajp++ = low64(t) = A0
+  __ sx(A0, Address(T3, 0));
+  __ addi(T3, T3, target::kWordSize);
+
+  // while (--n >= 0)
+  __ subi(T6, T6, 1);  // --n
+  __ bgez(T6, &loop);
+
+  __ Bind(&done);
+  // uint64_t aj = *ajp
+  __ lx(A0, Address(T3, 0));
+
+  // uint128_t t = aj + c
+  __ add(T4, T4, A0);
+  __ sltu(TMP, T4, A0);
+  __ add(T5, T5, TMP);
+
+  // *ajp = low64(t) = T4
+  // *(ajp + 1) = high64(t) = T5
+  __ sx(T4, Address(T3, 0));
+  __ sx(T5, Address(T3, target::kWordSize));
+
+  __ Bind(&x_zero);
+  // Result = One or two digits processed.
+  __ li(A0, target::ToRawSmi(target::kWordSize / kBytesPerBigIntDigit));
+  __ ret();
 }
 
 void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
                                                    Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // There is no 128-bit by 64-bit division instruction on arm64, so we use two
+  // 64-bit by 32-bit divisions and two 64-bit by 64-bit multiplications to
+  // adjust the two 32-bit digits of the estimated quotient.
+  //
+  // Pseudo code:
+  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
+  //   uint64_t* dp = &digits[(i >> 1) - 1];  // i is Smi.
+  //   uint64_t dh = dp[0];  // dh == digits[(i >> 1) - 1 .. i >> 1].
+  //   uint64_t qd;
+  //   if (dh == yt) {
+  //     qd = (DIGIT_MASK << 32) | DIGIT_MASK;
+  //   } else {
+  //     dl = dp[-1];  // dl == digits[(i >> 1) - 3 .. (i >> 1) - 2].
+  //     // We cannot calculate qd = dh:dl / yt, so ...
+  //     uint64_t yth = yt >> 32;
+  //     uint64_t qh = dh / yth;
+  //     uint128_t ph:pl = yt*qh;
+  //     uint64_t tl = (dh << 32)|(dl >> 32);
+  //     uint64_t th = dh >> 32;
+  //     while ((ph > th) || ((ph == th) && (pl > tl))) {
+  //       if (pl < yt) --ph;
+  //       pl -= yt;
+  //       --qh;
+  //     }
+  //     qd = qh << 32;
+  //     tl = (pl << 32);
+  //     th = (ph << 32)|(pl >> 32);
+  //     if (tl > dl) ++th;
+  //     dl -= tl;
+  //     dh -= th;
+  //     uint64_t ql = ((dh << 32)|(dl >> 32)) / yth;
+  //     ph:pl = yt*ql;
+  //     while ((ph > dh) || ((ph == dh) && (pl > dl))) {
+  //       if (pl < yt) --ph;
+  //       pl -= yt;
+  //       --ql;
+  //     }
+  //     qd |= ql;
+  //   }
+  //   args[_QD .. _QD_HI] = qd;  // _QD == 2, _QD_HI == 3.
+  //   return 2;
+  // }
+
+  __ lx(T4, Address(SP, 2 * target::kWordSize));  // args
+
+#if XLEN == 32
+  // ECX = yt = args[1]
+  __ lx(T3, FieldAddress(T4, target::TypedData::payload_offset() +
+                                 kBytesPerBigIntDigit));
+#else
+  // T3 = yt = args[0..1]
+  __ lx(T3, FieldAddress(T4, target::TypedData::payload_offset()));
+#endif
+
+  __ lx(A0, Address(SP, 0 * target::kWordSize));  // A0 = i as Smi
+  __ lx(T1, Address(SP, 1 * target::kWordSize));  // T1 = digits
+  __ slli(TMP, A0, 1);
+  __ add(T1, T1, TMP);
+#if XLEN == 32
+  // EBX = dp = &digits[i >> 1]
+  __ lx(T2, FieldAddress(T1, target::TypedData::payload_offset()));
+#else
+  // T2 = dh = digits[(i >> 1) - 1 .. i >> 1]
+  __ lx(T2, FieldAddress(T1, target::TypedData::payload_offset() -
+                                 kBytesPerBigIntDigit));
+#endif
+
+  // A0 = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
+  __ li(A0, -1);
+
+  // Return qd if dh == yt
+  Label return_qd;
+  __ beq(T2, T3, &return_qd);
+
+#if XLEN == 32
+  // EAX = dl = dp[-1]
+  __ lx(T1, FieldAddress(T1, target::TypedData::payload_offset() -
+                                 kBytesPerBigIntDigit));
+#else
+  // T1 = dl = digits[(i >> 1) - 3 .. (i >> 1) - 2]
+  __ lx(T1, FieldAddress(T1, target::TypedData::payload_offset() -
+                                 3 * kBytesPerBigIntDigit));
+#endif
+
+  // T5 = yth = yt >> 32
+  __ srli(T5, T3, target::kWordSize * 4);
+
+  // T6 = qh = dh / yth
+  __ divu(T6, T2, T5);
+
+  // A6:A1 = ph:pl = yt*qh
+  __ mulhu(A6, T3, T6);
+  __ mul(A1, T3, T6);
+
+  // A7 = tl = (dh << 32)|(dl >> 32)
+  __ slli(A7, T2, target::kWordSize * 4);
+  __ srli(TMP, T1, target::kWordSize * 4);
+  __ or_(A7, A7, TMP);
+
+  // S3 = th = dh >> 32
+  __ srli(S3, T2, target::kWordSize * 4);
+
+  // while ((ph > th) || ((ph == th) && (pl > tl)))
+  Label qh_adj_loop, qh_adj, qh_ok;
+  __ Bind(&qh_adj_loop);
+  __ bgtu(A6, S3, &qh_adj);
+  __ bne(A6, S3, &qh_ok);
+  __ bleu(A1, A7, &qh_ok);
+
+  __ Bind(&qh_adj);
+  // if (pl < yt) --ph
+  __ sltu(TMP, A1, T3);
+  __ sub(A6, A6, TMP);
+
+  // pl -= yt
+  __ sub(A1, A1, T3);
+
+  // --qh
+  __ subi(T6, T6, 1);
+
+  // Continue while loop.
+  __ j(&qh_adj_loop);
+
+  __ Bind(&qh_ok);
+  // A0 = qd = qh << 32
+  __ slli(A0, T6, target::kWordSize * 4);
+
+  // tl = (pl << 32)
+  __ slli(A7, A1, target::kWordSize * 4);
+
+  // th = (ph << 32)|(pl >> 32);
+  __ slli(S3, A6, target::kWordSize * 4);
+  __ srli(TMP, A1, target::kWordSize * 4);
+  __ or_(S3, S3, TMP);
+
+  // if (tl > dl) ++th
+  __ sltu(TMP, T1, A7);
+  __ add(S3, S3, TMP);
+
+  // dl -= tl
+  __ sub(T1, T1, A7);
+
+  // dh -= th
+  __ sub(T2, T2, S3);
+
+  // T6 = ql = ((dh << 32)|(dl >> 32)) / yth
+  __ slli(T6, T2, target::kWordSize * 4);
+  __ srli(TMP, T1, target::kWordSize * 4);
+  __ or_(T6, T6, TMP);
+  __ divu(T6, T6, T5);
+
+  // A6:A1 = ph:pl = yt*ql
+  __ mulhu(A6, T3, T6);
+  __ mul(A1, T3, T6);
+
+  // while ((ph > dh) || ((ph == dh) && (pl > dl))) {
+  Label ql_adj_loop, ql_adj, ql_ok;
+  __ Bind(&ql_adj_loop);
+  __ bgtu(A6, T2, &ql_adj);
+  __ bne(A6, T2, &ql_ok);
+  __ bleu(A1, T1, &ql_ok);
+
+  __ Bind(&ql_adj);
+  // if (pl < yt) --ph
+  __ sltu(TMP, A1, T3);
+  __ sub(A6, A6, TMP);
+
+  // pl -= yt
+  __ sub(A1, A1, T3);
+
+  // --ql
+  __ subi(T6, T6, 1);
+
+  // Continue while loop.
+  __ j(&ql_adj_loop);
+
+  __ Bind(&ql_ok);
+  // qd |= ql;
+  __ or_(A0, A0, T6);
+
+  __ Bind(&return_qd);
+  // args[2..3] = qd
+  __ sx(A0, FieldAddress(T4, target::TypedData::payload_offset() +
+                                 2 * kBytesPerBigIntDigit));
+
+  // Result = One or two digits processed.
+  __ li(A0, target::ToRawSmi(target::kWordSize / kBytesPerBigIntDigit));
+  __ ret();
 }
 
 void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
                                         Label* normal_ir_body) {
-  // TODO(riscv)
-  __ Bind(normal_ir_body);
+  // Pseudo code:
+  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
+  //   uint64_t d = digits[i >> 1 .. (i >> 1) + 1];  // i is Smi and even.
+  //   uint128_t t = rho*d;
+  //   args[_MU .. _MU_HI] = t mod DIGIT_BASE^2;  // _MU == 4, _MU_HI == 5.
+  //   return 2;
+  // }
+
+  __ lx(T0, Address(SP, 2 * target::kWordSize));  // args
+  __ lx(T1, Address(SP, 1 * target::kWordSize));  // digits
+  __ lx(T2, Address(SP, 0 * target::kWordSize));  // i as Smi
+
+  // T3 = rho = args[2..3]
+  __ lx(T3, FieldAddress(T0, target::TypedData::payload_offset() +
+                                 2 * kBytesPerBigIntDigit));
+
+  // T4 = digits[i >> 1 .. (i >> 1) + 1]
+  __ slli(T2, T2, 1);
+  __ add(T1, T1, T2);
+  __ lx(T4, FieldAddress(T1, target::TypedData::payload_offset()));
+
+  // T5 = rho*d mod DIGIT_BASE
+  __ mul(T5, T4, T3);  // T5 = low64(T4*T3).
+
+  // args[4 .. 5] = T5
+  __ sx(T5, FieldAddress(T0, target::TypedData::payload_offset() +
+                                 4 * kBytesPerBigIntDigit));
+
+  // Result = One or two digits processed.
+  __ li(A0, target::ToRawSmi(target::kWordSize / kBytesPerBigIntDigit));
+  __ ret();
 }
 
 // FA0: left
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 0916e2a..2a6d1b8 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -35,19 +35,10 @@
 class LocalScope;
 class LocalVariable;
 struct RegExpCompileData;
-class SourceLabel;
 template <typename T>
 class GrowableArray;
 class Parser;
 
-struct CatchParamDesc;
-class ClassDesc;
-struct MemberDesc;
-struct ParamList;
-struct QualIdent;
-class TopLevel;
-class RecursionChecker;
-
 // The class ParsedFunction holds the result of parsing a function.
 class ParsedFunction : public ZoneAllocated {
  public:
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 7a966ac..b155a46 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -21,11 +21,6 @@
             "enclosing scope (up to innermost loop) and spare the allocation "
             "of a local context.");
 
-int SourceLabel::FunctionLevel() const {
-  ASSERT(owner() != NULL);
-  return owner()->function_level();
-}
-
 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level)
     : parent_(parent),
       child_(NULL),
@@ -36,11 +31,9 @@
       begin_token_pos_(TokenPosition::kNoSource),
       end_token_pos_(TokenPosition::kNoSource),
       variables_(),
-      labels_(),
       context_variables_(),
       context_slots_(new (Thread::Current()->zone())
-                         ZoneGrowableArray<const Slot*>()),
-      referenced_() {
+                         ZoneGrowableArray<const Slot*>()) {
   // Hook this node into the children of the parent, unless the parent has a
   // different function_level, since the local scope of a nested function can
   // be discarded after it has been parsed.
@@ -87,66 +80,6 @@
   return true;
 }
 
-bool LocalScope::AddLabel(SourceLabel* label) {
-  if (LocalLookupLabel(label->name()) != NULL) {
-    return false;
-  }
-  labels_.Add(label);
-  if (label->owner() == NULL) {
-    // Labels must be added to their owner scope first. Subsequent calls
-    // to 'add' treat the label as an alias.
-    label->set_owner(this);
-  }
-  return true;
-}
-
-void LocalScope::MoveLabel(SourceLabel* label) {
-  ASSERT(LocalLookupLabel(label->name()) == NULL);
-  ASSERT(label->kind() == SourceLabel::kForward);
-  labels_.Add(label);
-  label->set_owner(this);
-}
-
-NameReference* LocalScope::FindReference(const String& name) const {
-  ASSERT(name.IsSymbol());
-  intptr_t num_references = referenced_.length();
-  for (intptr_t i = 0; i < num_references; i++) {
-    if (name.ptr() == referenced_[i]->name().ptr()) {
-      return referenced_[i];
-    }
-  }
-  return NULL;
-}
-
-void LocalScope::AddReferencedName(TokenPosition token_pos,
-                                   const String& name) {
-  if (LocalLookupVariable(name) != NULL) {
-    return;
-  }
-  NameReference* ref = FindReference(name);
-  if (ref != NULL) {
-    ref->set_token_pos(token_pos);
-    return;
-  }
-  ref = new NameReference(token_pos, name);
-  referenced_.Add(ref);
-  // Add name reference in innermost enclosing scopes that do not
-  // define a local variable with this name.
-  LocalScope* scope = this->parent();
-  while (scope != NULL && (scope->LocalLookupVariable(name) == NULL)) {
-    scope->referenced_.Add(ref);
-    scope = scope->parent();
-  }
-}
-
-TokenPosition LocalScope::PreviousReferencePos(const String& name) const {
-  NameReference* ref = FindReference(name);
-  if (ref != NULL) {
-    return ref->token_pos();
-  }
-  return TokenPosition::kNoSource;
-}
-
 void LocalScope::AllocateContextVariable(LocalVariable* variable,
                                          LocalScope** context_owner) {
   ASSERT(variable->is_captured());
@@ -464,17 +397,6 @@
   }
 }
 
-SourceLabel* LocalScope::LocalLookupLabel(const String& name) const {
-  ASSERT(name.IsSymbol());
-  for (intptr_t i = 0; i < labels_.length(); i++) {
-    SourceLabel* label = labels_[i];
-    if (label->name().ptr() == name.ptr()) {
-      return label;
-    }
-  }
-  return NULL;
-}
-
 LocalVariable* LocalScope::LocalLookupVariable(const String& name) const {
   ASSERT(name.IsSymbol());
   for (intptr_t i = 0; i < variables_.length(); i++) {
@@ -529,71 +451,6 @@
   }
 }
 
-SourceLabel* LocalScope::LookupLabel(const String& name) {
-  LocalScope* current_scope = this;
-  while (current_scope != NULL) {
-    SourceLabel* label = current_scope->LocalLookupLabel(name);
-    if (label != NULL) {
-      return label;
-    }
-    current_scope = current_scope->parent();
-  }
-  return NULL;
-}
-
-SourceLabel* LocalScope::LookupInnermostLabel(Token::Kind jump_kind) {
-  ASSERT((jump_kind == Token::kCONTINUE) || (jump_kind == Token::kBREAK));
-  LocalScope* current_scope = this;
-  while (current_scope != NULL) {
-    for (intptr_t i = 0; i < current_scope->labels_.length(); i++) {
-      SourceLabel* label = current_scope->labels_[i];
-      if ((label->kind() == SourceLabel::kWhile) ||
-          (label->kind() == SourceLabel::kFor) ||
-          (label->kind() == SourceLabel::kDoWhile) ||
-          ((jump_kind == Token::kBREAK) &&
-           (label->kind() == SourceLabel::kSwitch))) {
-        return label;
-      }
-    }
-    current_scope = current_scope->parent();
-  }
-  return NULL;
-}
-
-LocalScope* LocalScope::LookupSwitchScope() {
-  LocalScope* current_scope = this->parent();
-  int this_level = this->function_level();
-  while (current_scope != NULL &&
-         current_scope->function_level() == this_level) {
-    for (int i = 0; i < current_scope->labels_.length(); i++) {
-      SourceLabel* label = current_scope->labels_[i];
-      if (label->kind() == SourceLabel::kSwitch) {
-        // This scope contains a label that is bound to a switch statement,
-        // so it is the scope of the a statement body.
-        return current_scope;
-      }
-    }
-    current_scope = current_scope->parent();
-  }
-  // We did not find a switch statement scope at the same function level.
-  return NULL;
-}
-
-SourceLabel* LocalScope::CheckUnresolvedLabels() {
-  for (int i = 0; i < this->labels_.length(); i++) {
-    SourceLabel* label = this->labels_[i];
-    if (label->kind() == SourceLabel::kForward) {
-      LocalScope* outer_switch = LookupSwitchScope();
-      if (outer_switch == NULL) {
-        return label;
-      } else {
-        outer_switch->MoveLabel(label);
-      }
-    }
-  }
-  return NULL;
-}
-
 int LocalScope::NumCapturedVariables() const {
   // It is not necessary to traverse parent scopes, since we are only interested
   // in the captured variables referenced in this scope. If this scope is the
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index ff80167..3751aab 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -276,71 +276,6 @@
   GrowableArray<VarDesc> vars_;
 };
 
-class NameReference : public ZoneAllocated {
- public:
-  NameReference(TokenPosition token_pos, const String& name)
-      : token_pos_(token_pos), name_(name) {
-    ASSERT(name.IsSymbol());
-  }
-  const String& name() const { return name_; }
-  TokenPosition token_pos() const { return token_pos_; }
-  void set_token_pos(TokenPosition value) { token_pos_ = value; }
-
- private:
-  TokenPosition token_pos_;
-  const String& name_;
-};
-
-class SourceLabel : public ZoneAllocated {
- public:
-  enum Kind {
-    kFor,
-    kWhile,
-    kDoWhile,
-    kSwitch,
-    kCase,
-    kTry,
-    kCatch,
-    kForward,
-    kStatement  // Any statement other than the above
-  };
-
-  SourceLabel(TokenPosition token_pos, const String& name, Kind kind)
-      : token_pos_(token_pos), name_(name), owner_(NULL), kind_(kind) {
-    ASSERT(name.IsSymbol());
-  }
-
-  static SourceLabel* New(TokenPosition token_pos, String* name, Kind kind) {
-    if (name != NULL) {
-      return new SourceLabel(token_pos, *name, kind);
-    } else {
-      return new SourceLabel(token_pos, Symbols::DefaultLabel(), kind);
-    }
-  }
-
-  TokenPosition token_pos() const { return token_pos_; }
-  const String& name() const { return name_; }
-  LocalScope* owner() const { return owner_; }
-  void set_owner(LocalScope* owner) { owner_ = owner; }
-
-  Kind kind() const { return kind_; }
-
-  // Returns the function level of the scope in which the label is defined.
-  int FunctionLevel() const;
-
-  bool IsUnresolved() { return kind_ == kForward; }
-  void ResolveForwardReference() { kind_ = kCase; }
-
- private:
-  const TokenPosition token_pos_;
-  const String& name_;
-  LocalScope* owner_;  // Local scope declaring this label.
-
-  Kind kind_;
-
-  DISALLOW_COPY_AND_ASSIGN(SourceLabel);
-};
-
 class LocalScope : public ZoneAllocated {
  public:
   LocalScope(LocalScope* parent, int function_level, int loop_level);
@@ -403,19 +338,9 @@
   // Returns false if a variable with the same name is already present.
   bool InsertParameterAt(intptr_t pos, LocalVariable* parameter);
 
-  // Add a label to the scope. Returns false if a label with the same name
-  // is already present.
-  bool AddLabel(SourceLabel* label);
-
-  // Move an unresolved label of a switch case label to an outer switch.
-  void MoveLabel(SourceLabel* label);
-
   // Lookup a variable in this scope only.
   LocalVariable* LocalLookupVariable(const String& name) const;
 
-  // Lookup a label in this scope only.
-  SourceLabel* LocalLookupLabel(const String& name) const;
-
   // Lookup a variable in this scope and its parents. If the variable
   // is found in a parent scope and 'test_only' is not true, we insert
   // aliases of the variable in the current and intermediate scopes up to
@@ -423,26 +348,9 @@
   // We mark a variable as 'captured' when applicable.
   LocalVariable* LookupVariable(const String& name, bool test_only);
 
-  // Lookup a label in this scope and its parents.
-  SourceLabel* LookupLabel(const String& name);
-
-  // Lookup the "innermost" label that labels a for, while, do, or switch
-  // statement.
-  SourceLabel* LookupInnermostLabel(Token::Kind jump_kind);
-
-  // Lookup scope of outer switch statement at same function level.
-  // Returns NULL if this scope is not embedded in a switch.
-  LocalScope* LookupSwitchScope();
-
   // Mark this variable as captured by this scope.
   void CaptureVariable(LocalVariable* variable);
 
-  // Look for unresolved forward references to labels in this scope.
-  // If there are any, propagate the forward reference to the next
-  // outer scope of a switch statement. If there is no outer switch
-  // statement, return the first unresolved label found.
-  SourceLabel* CheckUnresolvedLabels();
-
   // Accessing the variables in the scope.
   intptr_t num_variables() const { return variables_.length(); }
   LocalVariable* VariableAt(intptr_t index) const {
@@ -454,12 +362,6 @@
   // this local scope.
   int NumCapturedVariables() const;
 
-  // Add a reference to the given name into this scope and the enclosing
-  // scopes that do not have a local variable declaration for this name
-  // already.
-  void AddReferencedName(TokenPosition token_pos, const String& name);
-  TokenPosition PreviousReferencePos(const String& name) const;
-
   // Allocate both captured and non-captured variables declared in this scope
   // and in its children scopes of the same function level. Allocating means
   // assigning a frame slot index or a context slot index.
@@ -512,8 +414,6 @@
   void CollectLocalVariables(LocalVarDescriptorsBuilder* vars,
                              int16_t* scope_id);
 
-  NameReference* FindReference(const String& name) const;
-
   static const int kUninitializedContextLevel = INT_MIN;
   LocalScope* parent_;
   LocalScope* child_;
@@ -524,17 +424,12 @@
   TokenPosition begin_token_pos_;  // Token index of beginning of scope.
   TokenPosition end_token_pos_;    // Token index of end of scope.
   GrowableArray<LocalVariable*> variables_;
-  GrowableArray<SourceLabel*> labels_;
 
   // List of variables allocated into the context which is owned by this scope,
   // and their corresponding Slots.
   GrowableArray<LocalVariable*> context_variables_;
   ZoneGrowableArray<const Slot*>* context_slots_;
 
-  // List of names referenced in this scope and its children that
-  // are not resolved to local variables.
-  GrowableArray<NameReference*> referenced_;
-
   DISALLOW_COPY_AND_ASSIGN(LocalScope);
 };
 
diff --git a/runtime/vm/scopes_test.cc b/runtime/vm/scopes_test.cc
index 1005d4c..e54d49e 100644
--- a/runtime/vm/scopes_test.cc
+++ b/runtime/vm/scopes_test.cc
@@ -22,9 +22,6 @@
   const String& c = String::ZoneHandle(Symbols::New(thread, "c"));
   LocalVariable* var_c = new LocalVariable(
       TokenPosition::kNoSource, TokenPosition::kNoSource, c, dynamic_type);
-  const String& L = String::ZoneHandle(Symbols::New(thread, "L"));
-  SourceLabel* label_L =
-      new SourceLabel(TokenPosition::kNoSource, L, SourceLabel::kFor);
 
   LocalScope* outer_scope = new LocalScope(NULL, 0, 0);
   LocalScope* inner_scope1 = new LocalScope(outer_scope, 0, 0);
@@ -51,13 +48,11 @@
   EXPECT(outer_scope->AddVariable(var_a));
   EXPECT(inner_scope1->AddVariable(var_b));
   EXPECT(inner_scope2->AddVariable(var_c));
-  EXPECT(inner_scope2->AddLabel(label_L));
   EXPECT(!outer_scope->AddVariable(var_a));
 
   // Check the simple layout above.
   EXPECT_EQ(var_a, outer_scope->LocalLookupVariable(a));
   EXPECT_EQ(var_a, inner_scope1->LookupVariable(a, true));
-  EXPECT_EQ(label_L, inner_scope2->LookupLabel(L));
   EXPECT(outer_scope->LocalLookupVariable(b) == NULL);
   EXPECT(inner_scope1->LocalLookupVariable(c) == NULL);
 
diff --git a/tests/corelib/bigint_add_test.dart b/tests/corelib/bigint_add_test.dart
new file mode 100644
index 0000000..d947d50
--- /dev/null
+++ b/tests/corelib/bigint_add_test.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectSum(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a + b;
+  String actualString = actual.toRadixString(16);
+  print("$aString + $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tests/corelib/bigint_div_test.dart b/tests/corelib/bigint_div_test.dart
new file mode 100644
index 0000000..ee56068
--- /dev/null
+++ b/tests/corelib/bigint_div_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectQuotient(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a ~/ b;
+  String actualString = actual.toRadixString(16);
+  print("$aString ~/ $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "1");
+  expectQuotient("d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e", "157b1");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e", "36662bd");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "141bfd63e");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "3714fb67de7");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "-1");
+  expectQuotient("-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e", "-157b1");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e", "-36662bd");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "-141bfd63e");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "-3714fb67de7");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "-1");
+  expectQuotient("d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e", "-157b1");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e", "-36662bd");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "-141bfd63e");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "-3714fb67de7");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "1");
+  expectQuotient("-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e", "157b1");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e", "36662bd");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "141bfd63e");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "3714fb67de7");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tests/corelib/bigint_mod_test.dart b/tests/corelib/bigint_mod_test.dart
new file mode 100644
index 0000000..d72e5d9
--- /dev/null
+++ b/tests/corelib/bigint_mod_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectRemainder(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a % b;
+  String actualString = actual.toRadixString(16);
+  print("$aString % $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1fdbde7efec117ff81df42cc8367092a65e4");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "359d4ac0e4440150310acc0e96fdb973c");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "84c9b202365aef6ea4b442ff6897d72e");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "2c66626e41743605244c026579e4f0");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1", "0");
+
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d11b55d5217bfadc012a3502892428b8c9906d8a");
+  expectRemainder(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "8163cdbfe36a817074a6295b3e8fcf60892a");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3c526a361d552fe1825b7b010d68af57d2");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "2775302963150716c7737ef76ff317e0");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "127bc92b2e824f670375f473110a1e");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1", "0");
+
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1fdbde7efec117ff81df42cc8367092a65e4");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "359d4ac0e4440150310acc0e96fdb973c");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "84c9b202365aef6ea4b442ff6897d72e");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "2c66626e41743605244c026579e4f0");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1", "0");
+
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d11b55d5217bfadc012a3502892428b8c9906d8a");
+  expectRemainder(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "8163cdbfe36a817074a6295b3e8fcf60892a");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3c526a361d552fe1825b7b010d68af57d2");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "2775302963150716c7737ef76ff317e0");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "127bc92b2e824f670375f473110a1e");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1", "0");
+}
diff --git a/tests/corelib/bigint_mul_test.dart b/tests/corelib/bigint_mul_test.dart
new file mode 100644
index 0000000..9351dbe
--- /dev/null
+++ b/tests/corelib/bigint_mul_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectProduct(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a * b;
+  String actualString = actual.toRadixString(16);
+  print("$aString * $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0", "0");
+
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0", "0");
+
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0", "0");
+
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0", "0");
+}
diff --git a/tests/corelib/bigint_sll_test.dart b/tests/corelib/bigint_sll_test.dart
new file mode 100644
index 0000000..082c810
--- /dev/null
+++ b/tests/corelib/bigint_sll_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectShifted(aString, n, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a << n;
+  String actualString = actual.toRadixString(16);
+  print("$aString << $n");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae124");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "361efb2a8dc0725ecc6d6e0213cad6cd39e15c248");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b84900000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "d87becaa3701c97b31b5b8084f2b5b34e785709200000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae12400000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b8490000000000000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "d87becaa3701c97b31b5b8084f2b5b34e78570920000000000000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae1240000000000000000");
+
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae124");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "-361efb2a8dc0725ecc6d6e0213cad6cd39e15c248");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b84900000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "-d87becaa3701c97b31b5b8084f2b5b34e785709200000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae12400000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b8490000000000000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "-d87becaa3701c97b31b5b8084f2b5b34e78570920000000000000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae1240000000000000000");
+}
diff --git a/tests/corelib/bigint_sra_test.dart b/tests/corelib/bigint_sra_test.dart
new file mode 100644
index 0000000..a7d073a
--- /dev/null
+++ b/tests/corelib/bigint_sra_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectShifted(aString, n, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a >> n;
+  String actualString = actual.toRadixString(16);
+  print("$aString >> $n");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b849");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "361efb2a8dc0725ecc6d6e0213cad6cd39e15c24");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "1b0f7d9546e0392f6636b70109e56b669");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "d87becaa3701c97b31b5b8084f2b5b34");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "6c3df6551b80e4bd98dadc042795ad9a");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "1b0f7d9546e0392f6636b7010");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "d87becaa3701c97b31b5b808");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "6c3df6551b80e4bd98dadc04");
+
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b849");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "-361efb2a8dc0725ecc6d6e0213cad6cd39e15c25");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "-1b0f7d9546e0392f6636b70109e56b66a");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "-d87becaa3701c97b31b5b8084f2b5b35");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "-6c3df6551b80e4bd98dadc042795ad9b");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "-1b0f7d9546e0392f6636b7011");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "-d87becaa3701c97b31b5b809");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "-6c3df6551b80e4bd98dadc05");
+}
diff --git a/tests/corelib/bigint_sub_test.dart b/tests/corelib/bigint_sub_test.dart
new file mode 100644
index 0000000..1c9d048
--- /dev/null
+++ b/tests/corelib/bigint_sub_test.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectDifference(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a - b;
+  String actualString = actual.toRadixString(16);
+  print("$aString - $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tests/corelib_2/bigint_add_test.dart b/tests/corelib_2/bigint_add_test.dart
new file mode 100644
index 0000000..20e8e66
--- /dev/null
+++ b/tests/corelib_2/bigint_add_test.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectSum(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a + b;
+  String actualString = actual.toRadixString(16);
+  print("$aString + $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectSum(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectSum("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectSum("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tests/corelib_2/bigint_div_test.dart b/tests/corelib_2/bigint_div_test.dart
new file mode 100644
index 0000000..589dedb
--- /dev/null
+++ b/tests/corelib_2/bigint_div_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectQuotient(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a ~/ b;
+  String actualString = actual.toRadixString(16);
+  print("$aString ~/ $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "1");
+  expectQuotient("d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e", "157b1");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e", "36662bd");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "141bfd63e");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "3714fb67de7");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "-1");
+  expectQuotient("-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e", "-157b1");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e", "-36662bd");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "-141bfd63e");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "-3714fb67de7");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "-1");
+  expectQuotient("d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e", "-157b1");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e", "-36662bd");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "-141bfd63e");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "-3714fb67de7");
+  expectQuotient("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e", "1");
+  expectQuotient("-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e", "157b1");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e", "36662bd");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "141bfd63e");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "3714fb67de7");
+  expectQuotient("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tests/corelib_2/bigint_mod_test.dart b/tests/corelib_2/bigint_mod_test.dart
new file mode 100644
index 0000000..56e0aa3
--- /dev/null
+++ b/tests/corelib_2/bigint_mod_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectRemainder(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a % b;
+  String actualString = actual.toRadixString(16);
+  print("$aString % $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1fdbde7efec117ff81df42cc8367092a65e4");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "359d4ac0e4440150310acc0e96fdb973c");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "84c9b202365aef6ea4b442ff6897d72e");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "2c66626e41743605244c026579e4f0");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1", "0");
+
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d11b55d5217bfadc012a3502892428b8c9906d8a");
+  expectRemainder(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "8163cdbfe36a817074a6295b3e8fcf60892a");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3c526a361d552fe1825b7b010d68af57d2");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e", "2775302963150716c7737ef76ff317e0");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e", "127bc92b2e824f670375f473110a1e");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1", "0");
+
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1fdbde7efec117ff81df42cc8367092a65e4");
+  expectRemainder(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "359d4ac0e4440150310acc0e96fdb973c");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "84c9b202365aef6ea4b442ff6897d72e");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "2c66626e41743605244c026579e4f0");
+  expectRemainder("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1", "0");
+
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d11b55d5217bfadc012a3502892428b8c9906d8a");
+  expectRemainder(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "8163cdbfe36a817074a6295b3e8fcf60892a");
+  expectRemainder(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3c526a361d552fe1825b7b010d68af57d2");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e", "2775302963150716c7737ef76ff317e0");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e", "127bc92b2e824f670375f473110a1e");
+  expectRemainder("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1", "0");
+}
diff --git a/tests/corelib_2/bigint_mul_test.dart b/tests/corelib_2/bigint_mul_test.dart
new file mode 100644
index 0000000..7fb5f07
--- /dev/null
+++ b/tests/corelib_2/bigint_mul_test.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectProduct(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a * b;
+  String actualString = actual.toRadixString(16);
+  print("$aString * $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0", "0");
+
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0", "0");
+
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0", "0");
+
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "b3f2d29d6885d40866b040adf8f545352154823b15fed8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "885bc7febac39cd5592e28ce964bfea66a31ea38d8aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "35d827ae2b7d1edeeae0115c81ba4a2496fe6d06aa8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "91a87047f3ae4999a45912763e9eb292049652bc8c35c5c223fcf4bf6eb904401c1875fc");
+  expectProduct(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "352d4596b9163adef2fad0a96d914a7908ab1a7435c5c223fcf4bf6eb904401c1875fc");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectProduct("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0", "0");
+}
diff --git a/tests/corelib_2/bigint_sll_test.dart b/tests/corelib_2/bigint_sll_test.dart
new file mode 100644
index 0000000..551f85f
--- /dev/null
+++ b/tests/corelib_2/bigint_sll_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectShifted(aString, n, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a << n;
+  String actualString = actual.toRadixString(16);
+  print("$aString << $n");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae124");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "361efb2a8dc0725ecc6d6e0213cad6cd39e15c248");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b84900000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "d87becaa3701c97b31b5b8084f2b5b34e785709200000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae12400000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b8490000000000000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "d87becaa3701c97b31b5b8084f2b5b34e78570920000000000000000");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "1b0f7d9546e0392f6636b70109e56b669cf0ae1240000000000000000");
+
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae124");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "-361efb2a8dc0725ecc6d6e0213cad6cd39e15c248");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b84900000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "-d87becaa3701c97b31b5b8084f2b5b34e785709200000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae12400000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b8490000000000000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "-d87becaa3701c97b31b5b8084f2b5b34e78570920000000000000000");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "-1b0f7d9546e0392f6636b70109e56b669cf0ae1240000000000000000");
+}
diff --git a/tests/corelib_2/bigint_sra_test.dart b/tests/corelib_2/bigint_sra_test.dart
new file mode 100644
index 0000000..84f35f3
--- /dev/null
+++ b/tests/corelib_2/bigint_sra_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectShifted(aString, n, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a >> n;
+  String actualString = actual.toRadixString(16);
+  print("$aString >> $n");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "6c3df6551b80e4bd98dadc042795ad9a73c2b849");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "361efb2a8dc0725ecc6d6e0213cad6cd39e15c24");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "1b0f7d9546e0392f6636b70109e56b669");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "d87becaa3701c97b31b5b8084f2b5b34");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "6c3df6551b80e4bd98dadc042795ad9a");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "1b0f7d9546e0392f6636b7010");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "d87becaa3701c97b31b5b808");
+  expectShifted("d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "6c3df6551b80e4bd98dadc04");
+
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 0,
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 1,
+      "-6c3df6551b80e4bd98dadc042795ad9a73c2b849");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 2,
+      "-361efb2a8dc0725ecc6d6e0213cad6cd39e15c25");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 31,
+      "-1b0f7d9546e0392f6636b70109e56b66a");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 32,
+      "-d87becaa3701c97b31b5b8084f2b5b35");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 33,
+      "-6c3df6551b80e4bd98dadc042795ad9b");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 63,
+      "-1b0f7d9546e0392f6636b7011");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 64,
+      "-d87becaa3701c97b31b5b809");
+  expectShifted("-d87becaa3701c97b31b5b8084f2b5b34e7857092", 65,
+      "-6c3df6551b80e4bd98dadc05");
+}
diff --git a/tests/corelib_2/bigint_sub_test.dart b/tests/corelib_2/bigint_sub_test.dart
new file mode 100644
index 0000000..ff7555d
--- /dev/null
+++ b/tests/corelib_2/bigint_sub_test.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// Testing Bigints with and without intrinsics.
+// VMOptions=--intrinsify --no-enable-asserts
+// VMOptions=--intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --enable-asserts
+// VMOptions=--no-intrinsify --no-enable-asserts
+
+import "package:expect/expect.dart";
+
+expectDifference(aString, bString, expectedString) {
+  BigInt a = BigInt.parse(aString, radix: 16);
+  BigInt b = BigInt.parse(bString, radix: 16);
+  BigInt expected = BigInt.parse(expectedString, radix: 16);
+  BigInt actual = a - b;
+  String actualString = actual.toRadixString(16);
+  print("$aString - $bString");
+  print(" = $actualString (expected $expectedString)");
+  Expect.equals(expected, actual);
+}
+
+main() {
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "1ad478de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87c8de9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87bece9e340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaae340aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference(
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "d87becaa3740aba6cb25ae8dbb531d2bc0105fa0");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857093");
+  expectDifference("d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "d87becaa3701c97b31b5b8084f2b5b34e7857092");
+
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d4cba13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "3b04b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-a13fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87b4b6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3fac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87bec6a8ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-ac3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87beca98ac2e74f9845c182e303993e0efa8184");
+  expectDifference(
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092",
+      "-3ee22b996ff6856c27c1f6d88aef0e",
+      "-d87becaa36c2e74f9845c182e303993e0efa8184");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-1",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857091");
+  expectDifference("-d87becaa3701c97b31b5b8084f2b5b34e7857092", "-0",
+      "-d87becaa3701c97b31b5b8084f2b5b34e7857092");
+}
diff --git a/tools/VERSION b/tools/VERSION
index 91a5739..a26c379 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 189
+PRERELEASE 190
 PRERELEASE_PATCH 0
\ No newline at end of file