Skip to content

Conversation

@samek-h
Copy link

@samek-h samek-h commented Jan 23, 2026

A pull request created in response to #1304 that fixes the incorrect order of the rdtsc instruction output registers.

Reproduced using following program:

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
with System.Machine_Code; use System.Machine_code;

procedure Rdtsc is
   function Get_Processor_Cycles return Unsigned_64 is
      Low, High : Unsigned_32;
      Counter   : Unsigned_64;
   begin
      Asm ("rdtsc",
           Outputs =>
             (Unsigned_32'Asm_Output ("=a", High),  -- Incorrect
              Unsigned_32'Asm_Output ("=d", Low)),  -- Incorrect
           Volatile => True);

      Counter :=
         Unsigned_64 (High) * 2 ** 32 +
         Unsigned_64 (Low);

      return Counter;
   end Get_Processor_Cycles;
begin
   Put_Line ("tsc =" & Get_Processor_Cycles'Image);
end Rdtsc;

The resulting rdtsc value is seemingly random, not increasing:

$ taskset -c 0 ./rdtsc
tsc = 14729149879850896313
$ taskset -c 0 ./rdtsc
tsc = 7769122674801904570
$ taskset -c 0 ./rdtsc
tsc = 17445020729480317882
$ taskset -c 0 ./rdtsc
tsc = 8327487355497745339
$ taskset -c 0 ./rdtsc
tsc = 1353739439335017404

The same program, but using the correct order:

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
with System.Machine_Code; use System.Machine_code;

procedure Rdtsc is
   function Get_Processor_Cycles return Unsigned_64 is
      Low, High : Unsigned_32;
      Counter   : Unsigned_64;
   begin
      Asm ("rdtsc",
           Outputs =>
             (Unsigned_32'Asm_Output ("=a", Low),
              Unsigned_32'Asm_Output ("=d", High)),
           Volatile => True);

      Counter :=
         Unsigned_64 (High) * 2 ** 32 +
         Unsigned_64 (Low);

      return Counter;
   end Get_Processor_Cycles;
begin
   Put_Line ("tsc =" & Get_Processor_Cycles'Image);
end Rdtsc;

The resulting values are now increasing:

$ taskset -c 0 ./rdtsc
tsc = 13377973989561
$ taskset -c 0 ./rdtsc
tsc = 13381489237427
$ taskset -c 0 ./rdtsc
tsc = 13384125133819
$ taskset -c 0 ./rdtsc
tsc = 13386827400627
$ taskset -c 0 ./rdtsc
tsc = 13389239550049

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Jan Samek seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants