Internal change

PiperOrigin-RevId: 549214897
diff --git a/sim/kelvin_instructions.cc b/sim/kelvin_instructions.cc
index 357eb9b..dbc25d6 100644
--- a/sim/kelvin_instructions.cc
+++ b/sim/kelvin_instructions.cc
@@ -60,6 +60,8 @@
       break;
     }
     case 1: {  // Scalar log op to load an integer argument.
+      // The value is stored as an unsigned integer. The actual format will be
+      // determined with the format specifier "d" or "u".
       auto data =
           mpact::sim::generic::GetInstructionSource<uint32_t>(inst, 0, 0);
       state->SetLogArgs(data);
diff --git a/sim/kelvin_state.cc b/sim/kelvin_state.cc
index 5fd15ca..3903548 100644
--- a/sim/kelvin_state.cc
+++ b/sim/kelvin_state.cc
@@ -3,6 +3,7 @@
 
 #include <cstdint>
 #include <iostream>
+#include <ostream>
 #include <string>
 
 #include "absl/log/check.h"
@@ -47,10 +48,25 @@
       CHECK_GT(log_args_.size(), 0)
           << "Invalid program with insufficient log argurments";
       if (log_args_[0].type() == typeid(uint32_t)) {
-        std::cout << std::any_cast<uint32_t>(log_args_[0]);
+        switch (print_ptr[1]) {
+          case 'u':
+            std::cout << std::any_cast<uint32_t>(log_args_[0]);
+            break;
+          case 'd':
+            std::cout << static_cast<int32_t>(
+                std::any_cast<uint32_t>(log_args_[0]));
+            break;
+          default:
+            std::cerr << "incorrect format" << std::endl;
+            break;
+        }
       }
       if (log_args_[0].type() == typeid(std::string)) {
-        std::cout << std::any_cast<std::string>(log_args_[0]);
+        if (print_ptr[1] == 's') {
+          std::cout << std::any_cast<std::string>(log_args_[0]);
+        } else {
+          std::cerr << "incorrect format" << std::endl;
+        }
       }
       log_args_.erase(log_args_.begin());
       print_ptr += 2;  // skip the format specifier too.
diff --git a/sim/test/kelvin_log_instructions_test.cc b/sim/test/kelvin_log_instructions_test.cc
index 093b610..e868a62 100644
--- a/sim/test/kelvin_log_instructions_test.cc
+++ b/sim/test/kelvin_log_instructions_test.cc
@@ -46,9 +46,9 @@
   EXPECT_EQ(kHelloString, stdout_str);
 }
 
-TEST_F(KelvinLogInstructionsTest, PrintNumer) {
-  constexpr char kFormatString[] = "Hello %d\n";
-  constexpr uint32_t kPrintNum = 1337;
+TEST_F(KelvinLogInstructionsTest, PrintUnsignedNumber) {
+  constexpr char kFormatString[] = "Hello %u\n";
+  constexpr uint32_t kPrintNum = 2200000000;  // a number > INT32_MAX
 
   // Initialize memory.
   auto *db = state_->db_factory()->Allocate<char>(sizeof(kFormatString));
@@ -80,7 +80,44 @@
     instructions[i]->Execute(nullptr);
   }
   const std::string stdout_str = testing::internal::GetCapturedStdout();
-  EXPECT_EQ("Hello 1337\n", stdout_str);
+  EXPECT_EQ("Hello 2200000000\n", stdout_str);
+}
+
+TEST_F(KelvinLogInstructionsTest, PrintSignedNumber) {
+  constexpr char kFormatString[] = "Hello %d\n";
+  constexpr int32_t kPrintNum = -1337;
+
+  // Initialize memory.
+  auto *db = state_->db_factory()->Allocate<char>(sizeof(kFormatString));
+  for (int i = 0; i < sizeof(kFormatString); ++i) {
+    db->Set<char>(i, kFormatString[i]);
+  }
+  db->DecRef();
+
+  std::array<InstructionPtr, 2> instructions = {CreateInstruction(),
+                                                CreateInstruction()};
+
+  AppendRegisterOperands(instructions[0].get(), {kelvin::sim::test::kRs1Name},
+                         {});
+  instructions[0]->set_semantic_function(
+      absl::bind_front(&KelvinLogInstruction, /*mode=*/1));  // scalar log
+
+  // Set the second instruction for the actual print out.
+  state_->StoreMemory(instructions[1].get(), kMemAddress, db);
+  AppendRegisterOperands(instructions[1].get(), {kelvin::sim::test::kRs2Name},
+                         {});
+  instructions[1]->set_semantic_function(
+      absl::bind_front(&KelvinLogInstruction, /*mode=*/0));
+
+  SetRegisterValues<int32_t>({{kelvin::sim::test::kRs1Name, kPrintNum}});
+  SetRegisterValues<uint32_t>({{kelvin::sim::test::kRs2Name, kMemAddress}});
+
+  testing::internal::CaptureStdout();
+  for (int i = 0; i < instructions.size(); ++i) {
+    instructions[i]->Execute(nullptr);
+  }
+  const std::string stdout_str = testing::internal::GetCapturedStdout();
+  EXPECT_EQ("Hello -1337\n", stdout_str);
 }
 
 TEST_F(KelvinLogInstructionsTest, PrintCharacterStream) {